def __init__(self, x, y, z, direction, id): NodePath.__init__(self,loader.loadModel("../Models/missile")) self.reparentTo(render) self.setPos(x, y, z) self.direction = Vec3() self.direction.set(direction.getX(), direction.getY(), direction.getZ()) self.setH(Vec2.signedAngleDeg(Vec2(0,1), Vec2(direction.getX(),direction.getY()))) if self.direction.length() == 0: self.removeNode() return self.direction /= direction.length() min, max = self.getTightBounds() size = max - min maximum = -1 for i in size: if i > maximum: maximum = i self.cnode = CollisionNode('bullet') self.cnode.setTag( "id", str(id) ) self.cnode.addSolid(CollisionSphere(0, 0, 0, maximum + 0.3)) self.cnodePath = self.attachNewNode(self.cnode) self.cnodePath.show() base.cTrav.addCollider(self.cnodePath, base.event) taskMgr.add(self.updateBullet, "update Bullet") print radiansToDegrees(atan2(direction.getY(),direction.getX()))
def hunt( self, task ): if self.body.node.isEmpty(): return Task.done if self.target == None or self.target.isEmpty() or self.target.getTag("type") == "destroyed": list = render.findAllMatches("**/=type=robot") print "list size = " + str(list.size()) if list.size() < 2: return Task.cont target = randint(0, list.size() - 1 ) self.target = list.getPath( target ) if self.target == self.body.node: return Task.cont if task.time - self.time <= 0.1: return Task.cont self.time = task.time if calcDistance2D( self.target.getPos().getXy(), self.body.node.getPos().getXy() ) < 1: if task.time - self.bulletTime >= 5: Bullet(self.body.node.getX(), self.body.node.getY(), self.body.node.getZ(), calcDirection( self.body.node.getPos(), self.target.getPos() ),self.id) self.bulletTime = task.time else: direction = calcDirection2D(self.body.node.getPos().getXy(), self.target.getPos().getXy() ) # print "in hunt direction=" # print direction self.body.node.setH(Vec2.signedAngleDeg(Vec2(0,1), Vec2(direction.getX(),direction.getY()))) self.body.node.setX( self.body.node.getX() + direction.getX() ) self.body.node.setY( self.body.node.getY() + direction.getY() ) return Task.cont
def randomWalk( self, task ): if self.body.node == None or self.body.node.isEmpty(): return Task.done if task.time - self.time <= 0.1: return Task.cont self.time = task.time if calcDistance2D(self.destination, self.body.node.getPos().getXy() ) <= 1: self.setRandomPoint( self.destination ) direction = calcDirection2D(self.body.node.getPos().getXy(), self.destination) #print "randomWalk destination =" #print direction self.body.node.setH(Vec2.signedAngleDeg(Vec2(0,1), Vec2(direction.getX(),direction.getY()))) self.body.node.setX( self.body.node.getX() + direction.getX() ) self.body.node.setY( self.body.node.getY() + direction.getY() ) return Task.cont
def top_right(self): return Vec2(self.aspect_ratio/2, .5)
def top_left(self): return Vec2(-self.aspect_ratio/2, .5)
def right(self): return Vec2(self.aspect_ratio/2, 0)
def left(self): return Vec2(-self.aspect_ratio/2, 0)
def size(self): return Vec2(self.get_size()[0], self.get_size()[1])
def ai_movement_handler(self, event): """This is but nasty hack to make enemies follow character. TODO: remake and move to its own module""" # TODO: maybe make it possible to chase not for just player? # TODO: not all enemies need to behave this way. e.g, for example, we can # only affect enemies that have their ['ai'] set to ['chaser']... # or something among these lines, will see in future # disable this handler if the enemy or player are dead. Without it, game # will crash the very next second after one of these events occur if self.dead or shared.level.player.dead: return if "stun" in self.status_effects: return event.cont player_position = shared.level.player.node.get_pos() mov_speed = self.stats["mov_spd"] enemy_position = self.node.get_pos() vector_to_player = player_position - enemy_position distance_to_player = vector_to_player.length() # normalizing vector is the key to avoid "flickering" effect, as its # basically ignores whatever minor difference in placement there are # I dont know how it works, lol vector_to_player = vector_to_player.normalized() # workaround to ensure enemy will stay on its layer, even if its different # from player due to size difference or whatever else reasons vxy = vector_to_player.get_xy() # new_pos = enemy_position + (vector_to_player*mov_speed) new_pos = enemy_position + (vxy * mov_speed, 0) pos_diff = enemy_position - new_pos self.node.set_python_tag("mov_spd", mov_speed) action = "idle" # trying to find angle that wont suck. Basically its the same thing, as # with player. Really thinking about moving it to skill itself #TODO hit_vector_x, hit_vector_y = vxy hit_vector_2D = -hit_vector_x, hit_vector_y y_vec = Vec2(0, 1) angle = y_vec.signed_angle_deg(hit_vector_2D) # it may be good idea to also track camera angle, if I will decide # to implement camera controls, at some point or another. #TODO if pos_diff[0] > 0: self.change_direction("right") else: self.change_direction("left") # this thing basically makes enemy move till it hit player, than play # attack animation. May backfire if player's sprite size is not equal # to player's hitbox if distance_to_player > shared.game_data.sprite_size[0] * 2: action = "move" else: # cast the very first skill available. #TODO: add something to affect # order of skills in self.skills skill = self.get_available_skill() if skill: # skill.cast(direction = (vector_to_player*(shared.DEFAULT_SPRITE_SIZE[0]/2)), skill.cast(direction=vector_to_player, angle=angle) # workaround for issue when enemy keeps running into player despite already # colliding with it, which cause enemy's animation to go wild. # idk about the numbers yet. I think, ideally it should be calculated from # player's hitbox and enemy's hitbox... but for now this will do if distance_to_player > 6: self.node.set_pos(new_pos) # self.object.set_pos(new_pos) if not self.node.get_python_tag("using_skill"): self.change_animation(action) return event.cont
def center_on_screen(self): self.position = Vec2( int((self.screen_resolution[0] - self.size[0]) / 2), int((self.screen_resolution[1] - self.size[1]) / 2) )
def test_vec2_len(): assert len(Vec2(2, -3)) == 2
def test_vec2_power(): assert Vec2(2, -3)**2 == Vec2(4, 9)
def test_round(): original_vector = Vec2(2.3, -2.6) rounded_vector = round(original_vector) assert rounded_vector.x == 2 assert rounded_vector.y == -3
def test_vec2_sum(): original_vector = Vec2(2, 3) assert original_vector + original_vector == Vec2(4, 6) assert original_vector + 3 == Vec2(5, 6)
def test_vec2_creation(): assert Vec2(x=1, y=2) == Vec2(1, 2) == Vec2((1, 2))
def test_ceil(): original_vector = Vec2(2.3, -2.6) rounded_vector = ceil(original_vector) assert rounded_vector.x == 3 assert rounded_vector.y == -2
def bottom_left(self): return Vec2(-self.aspect_ratio/2, -.5)
def bottom_right(self): return Vec2(self.aspect_ratio/2, -.5)
def assignAtlasPos(self, x, y): """ Assigns this source a position in the shadow atlas. This is called by the shadow atlas. Coordinates are float from 0 .. 1 """ self.atlasPos = Vec2(x, y) self.doesHaveAtlasPos = True
def test_vec2_swizzle_mask(): original_vector = Vec2(3, 5) assert original_vector.yx == Vec2(5, 3) assert original_vector.xy == original_vector
def __init__(self, showbase): DirectObject.__init__(self) self.showbase = showbase self.showbase.disableMouse() # This disables the default mouse based camera control used by panda. This default control is awkward, and won't be used. self.showbase.camera.setPos(0, -150, 200) self.showbase.camera.lookAt(0, 0, 0) # Gives the camera an initial position and rotation. self.mx, self.my = 0, 0 # Sets up variables for storing the mouse coordinates self.orbiting = False # A boolean variable for specifying whether the camera is in orbiting mode. Orbiting mode refers to when the camera is being moved # because the user is holding down the right mouse button. self.target = Vec3() # sets up a vector variable for the camera's target. The target will be the coordinates that the camera is currently focusing on. self.camDist = 150 # A variable that will determine how far the camera is from it's target focus self.panRateDivisor = 10 # This variable is used as a divisor when calculating how far to move the camera when panning. Higher numbers will yield slower panning # and lower numbers will yield faster panning. This must not be set to 0. self.panZoneSize = .1 # This variable controls how close the mouse cursor needs to be to the edge of the screen to start panning the camera. It must be less than 1, # and I recommend keeping it less than .2 self.panLimitsX = Vec2(-1000, 1000) self.panLimitsY = Vec2(-1000, 1000) # These two vairables will serve as limits for how far the camera can pan, so you don't scroll away from the map. self.maxZoomOut = 500 self.maxZoomIn = 25 # These two variables set the max distance a person can zoom in or out self.orbitRate = 75 # This is the rate of speed that the camera will rotate when middle mouse is pressed and mouse moved # recommended rate 50-100 self.setTarget(0, 0, 0) # calls the setTarget function to set the current target position to the origin. self.turnCameraAroundPoint(0, 0) # calls the turnCameraAroundPoint function with a turn amount of 0 to set the camera position based on the target and camera distance self.accept("mouse2", self.startOrbit) # sets up the camrea handler to accept a right mouse click and start the "drag" mode. self.accept("mouse2-up", self.stopOrbit) # sets up the camrea handler to understand when the right mouse button has been released, and ends the "drag" mode when # the release is detected. self.storeX = 0 self.storeY = 0 # for storing of the x and y for the orbit # The next pair of lines use lambda, which creates an on-the-spot one-shot function. self.accept("wheel_up", self.zoomIn) # sets up the camera handler to detet when the mouse wheel is rolled upwards and uses a lambda function to call the # adjustCamDist function with the argument 0.9 self.accept("wheel_down", self.zoomOut) # sets up the camera handler to detet when the mouse wheel is rolled upwards and uses a lambda function to call the # adjustCamDist function with the argument 1.1 # Keys array (down if 1, up if 0) self.keys = {"cam-left": 0, "cam-right": 0, "cam-up": 0, "cam-down": 0} # Using Arrow Keys self.accept("arrow_left", self.setValue, [self.keys, "cam-left", 1]) self.accept("arrow_right", self.setValue, [self.keys, "cam-right", 1]) self.accept("arrow_up", self.setValue, [self.keys, "cam-up", 1]) self.accept("arrow_down", self.setValue, [self.keys, "cam-down", 1]) self.accept("arrow_left-up", self.setValue, [self.keys, "cam-left", 0]) self.accept("arrow_right-up", self.setValue, [self.keys, "cam-right", 0]) self.accept("arrow_up-up", self.setValue, [self.keys, "cam-up", 0]) self.accept("arrow_down-up", self.setValue, [self.keys, "cam-down", 0]) self.keyPanRate = 1.5 # pan rate for when user presses the arrow keys # set up plane for checking collision with for mouse-3d world self.plane = Plane(Vec3(0, 0, 1), Point3(0, 0, 0))
globals_list.append([e, sys.getsizeof(e)]) globals_list.sort(key=operator.itemgetter(1), reverse=True) print('scene size:', globals_list) def average_position(l): average = list() for i in range(len(l[0])): average.append(sum(e[i] for e in l) / len(l)) return average if __name__ == '__main__': from ursina import * app = Ursina() e1 = Entity(position = (0,0,0)) e2 = Entity(position = (0,1,1)) distance(e1, e2) between_color = lerp(color.lime, color.magenta, .5) print(between_color) print(lerp((0,0), (0,1), .5)) print(lerp(Vec2(0,0), Vec2(0,1), .5)) print(lerp([0,0], [0,1], .5)) print(round(Vec3(.38, .1351, 353.26), 2)) app.run()
def removeFromAtlas(self): """ Deletes the atlas coordinates, called by the atlas after the Source got removed from the atlas """ self.doesHaveAtlasPos = False self.atlasPos = Vec2(0)