def myTimeToCollision(self): self.cp = self.myNextCollisionPoint() if Inf == vec.length(self.cp): return Inf # No collisions detected. # vec.copy(self.myPosition(), gui.debugPt0) # vec.copy(self.cp, gui.debugPt1) self.rp = self.cp - self.myPosition() # With the current set of assumptions, me could not be on a # collision course in the first place if the following assert # fails. assert 0 <= vec.dot(self.rp, self.myVelocity()) # TODO: To more accurately compute the time to collision we should # take into account the velocity of the collider. But if we do # that here, we should have done that in the computation of the # nearest collider. For example, if a collider is moving out of # the way faster than we are approaching it, then there is no # danger of collision after all. But remember this whole method # is a percept and percepts don't have to be perfect as they are # meant to model how the NPC thinks about the world. And in that # vein, using a stationary snapshot of the world is OK for now. # Especially so as the snapshot is regularly updated when the # percept is recalculated every time an action is selected. # colliderVel = vec.dot(self.rp, self.nextCollider) # relVel = myVel - colliderVel; return vec.length(self.rp) # / self.myVelocity()
def angle(u): l = vec.length(u) if util.isAlmostZero(l): return 0.0 assert util.isAlmostEq(vec.length(u), 1.0), "input must be normalized, not " + str(u) return math.atan2(u[1], u[0])
def update_snowballs(lobby): changed_healths = [] destroyed_snowballs = [] player_hit = False ground_hit = False for id, snowball in lobby.snowballs.items(): new_vel = vec.add(snowball.velocity, (0, GRAVITY_ACCELERATION)) new_pos = vec.add(snowball.position, new_vel) new_x, new_y = new_pos hit_object, can_move = level.can_move_to(SNOWBALL_SIZE, SNOWBALL_SIZE, round(new_x), round(new_y), all_players(lobby.clients)) if can_move: snowball.velocity = new_vel snowball.position = new_pos else: destroyed_snowballs.append(id) if isinstance(hit_object, player.Player): player_hit = True speed = vec.length(snowball.velocity) hit_object.health = max( 0, hit_object.health - speed * SNOWBALL_DAMAGE) changed_healths.append(hit_object) else: ground_hit = True lobby.snowballs = { id: v for id, v in lobby.snowballs.items() if id not in destroyed_snowballs } return changed_healths, destroyed_snowballs, player_hit, ground_hit
def setVelocity(self, velocity): s = vec.length(velocity) if util.isAlmostZero(s): self.setSpeed(0) # Don't change the orientation if the speed is zero. else: self.setSpeed(s) self.shape.setOrientation(vec.normalize(velocity, self.velocity))
def calcAction(self): self.action.direction[0] = self.inputDevice.getX() self.action.direction[1] = self.inputDevice.getY() if vec.isAlmostZero(self.action.direction): vec.zeroize(self.action.direction) # TODO: necessary? self.action.speed = 0.0 else: self.action.speed = min(1.0, vec.length(self.action.direction)) vec.normalize(self.action.direction, self.action.direction)
def myNextCollider(self): # If the previous calculation of the next collider is still valid, # return the cached value. if self.nextCollider: return self.nextCollider which = None dMin = Inf for o in self.gs.obstacles: if self.me == o: continue # Don't include me! self.ip = o.nearestIntersection(self.me, self.ip) # Infinity is used to indicate no intersection. if vec.length(self.ip) < Inf: p = self.ip - self.myPosition() d = vec.length(p) - self.myMaxExtent() if d < dMin: dMin = d which = o vec.copy(self.ip, self.cp) # We must at least be on a collision course with one of the sides. # TODO: turn side collisions back on # if false and not which: # print self.myPosition(), "; ", self.myOrientation() # pause # assert which # Computing the nearest collider is expensive so cache the result # in case it's needed again. # TODO: Could also be worth caching dMin as the distance to the # nearest collider. self.nextCollider = which return which
def drawArrow(begin, lvec, lineSize): assert util.isAlmostEq(1.0, vec.length(lvec)), "unnormalized input" headSize = 0.5 * lineSize lAngle = 2.5 rAngle = -2.5 # TODO: get rid of all these constructor calls hvec1 = zeros((util.numDim, ), float) hvec2 = zeros((util.numDim, ), float) tmp = zeros((util.numDim, ), float) hvec1 = vec.scale( array([ lvec[0] * math.cos(lAngle) - lvec[1] * math.sin(lAngle), lvec[0] * math.sin(lAngle) + lvec[1] * math.cos(lAngle) ]), headSize, hvec1) hvec2 = vec.scale( array([ lvec[0] * math.cos(rAngle) - lvec[1] * math.sin(rAngle), lvec[0] * math.sin(rAngle) + lvec[1] * math.cos(rAngle) ]), headSize, hvec2) tmp = vec.scale(lvec, lineSize, tmp) rightWay = True glPushMatrix() if rightWay: glTranslate(begin[0], begin[1], 0.0) else: glTranslate(begin[0] - tmp[0], begin[1] - tmp[1], 0.0) glBegin(GL_LINE_STRIP) glVertex(0.0, 0.0) glVertex(tmp[0], tmp[1]) glVertex(tmp[0] + hvec1[0], tmp[1] + hvec1[1]) glEnd() glPopMatrix() glPushMatrix() if rightWay: glTranslate(begin[0] + tmp[0], begin[1] + tmp[1], 0.0) else: glTranslate(begin[0], begin[1], 0.0) glBegin(GL_LINES) glVertex(0.0, 0.0) glVertex(hvec2[0], hvec2[1]) glEnd() glPopMatrix()
def setOrientation(self, orientation): assert util.isAlmostEq(1.0, vec.length(orientation)), 'invalid orientation ' + str(orientation) vec.copy(orientation, self.orientation)
def getOrientation(self): assert util.isAlmostEq(1.0, vec.length(self.shape.orientation)), 'invalid orientation ' + str(self.shape.orientation) return self.shape.orientation
def distanceTo(c0, c1): return vec.length(c0.position - c1.position) - c0.radius - c1.radius
def setActualVelocity(self, velocity): self.actualVelocity = velocity self.actualSpeed = vec.length(velocity)