def move(self): #move the missile global world if self.target != None: self.v += mymath.unit(self.target.craft.pos - self.pos) * 5 #thrust else: self.v += mymath.unit(self.v) * 5 self.v *= 0.9 #drag self.pos += self.v self.model.pos = self.pos side = cross(mymath.unit(self.v).T, array([[0, 1, 0] ])).T #a column vector for the side of the missile self.model.theta = hstack([ mymath.unit(self.v), -side, cross(mymath.unit(self.v).T, side.T).T ]) #rotate model if self.get_altitude() < 0: #hit ground v1 = ground_height(self.pos) v2 = ground_height(self.pos + array([[1], [0], [0]])) v3 = ground_height(self.pos + array([[0], [0], [1]])) normal = -expand_dims( mymath.unit( cross(array([1, v2 - v1, 0]), array([0, v3 - v1, 1]))), 1) self.hit(normal) if self.target == None and mymath.norm( player.craft.pos - self.pos ) > world.terrain.scale * world.terrain.distance: #despawn if too far global missiles try: missiles.remove(self) world.models.remove(self.model) except ValueError: pass
def crash(self): #crash and explode global world, fragments world.models.remove(self.model) sounds['explosion'].play() for i in range(10): fragments.append( Fragment('plane frag', copy(self.craft.pos), (numpy.random.rand(3, 1) - 0.5) * mymath.norm(self.craft.v) * 10))
def crash(self): #crash and explode global world, fragments, enemies, kills kills += 1 try: enemies.remove(self) world.models.remove(self.model) except ValueError: pass sounds['explosion'].play() for i in range(10): fragments.append( Fragment('plane frag', copy(self.craft.pos), (numpy.random.rand(3, 1) - 0.5) * mymath.norm(self.craft.v) * 10))
def hit_ground( self, normal ): #hit the ground, do not generate fragments, instead make dirt clumps. global world, bullets, fragments try: bullets.remove(self) world.models.remove(self.model) except ValueError: pass for i in range(4): fragments.append( Fragment('dirt clump', copy(self.pos), (self.v - 2 * normal * normal.T.dot(self.v)) * 0.3 + (numpy.random.rand(3, 1) - 0.5) * mymath.norm(self.v) * 0.1))
def hit(self, normal): #hit something other than the ground, generate fragments global world, bullets, fragments try: bullets.remove(self) world.models.remove(self.model) except ValueError: pass #create fragments upon collision for i in range(4): fragments.append( Fragment( 'bullet', copy(self.pos), self.v - 2 * normal * normal.T.dot(self.v) + (numpy.random.rand(3, 1) - 0.5) * mymath.norm(self.v) * 0.5))
def hit(self, normal): #collide and explode global world, missiles, fragments try: missiles.remove(self) world.models.remove(self.model) except ValueError: pass sounds['explosion'].play() #create flames upon collision for i in range(10): fragments.append( Fragment( 'flames', copy(self.pos), self.v - 2 * normal * normal.T.dot(self.v) + (numpy.random.rand(3, 1) - 0.5) * mymath.norm(self.v) * 0.5))
def move(self): #move bullet global world self.pos += self.v self.model.pos = self.pos if mymath.norm( player.craft.pos - self.pos ) > world.terrain.scale * world.terrain.distance: #despawn if too far try: bullets.remove(self) world.models.remove(self.model) except ValueError: pass elif self.get_altitude() < 0: #hit ground v1 = ground_height(self.pos) v2 = ground_height(self.pos + array([[1], [0], [0]])) v3 = ground_height(self.pos + array([[0], [0], [1]])) normal = -expand_dims( mymath.unit( cross(array([1, v2 - v1, 0]), array([0, v3 - v1, 1]))), 1) self.hit_ground(normal)
def update(self): #update the enemy self.craft.move() self.model.pos = self.craft.pos #move model self.model.theta = self.craft.theta #rotate model for obj in bullets + missiles: #test for bullet/missile collision closest_point = mymath.closestpoint(self.craft.pos, obj.pos, obj.pos - obj.v) if mymath.norm(self.craft.pos - closest_point) < 20: obj.pos = closest_point obj.hit(mymath.unit(closest_point - self.craft.pos)) if type(obj) == Bullet: self.craft.hp -= 1 elif type(obj) == Missile: self.craft.hp -= 20 if self.craft.hp <= 0: self.crash() if random.uniform() < 0.03 * (30 - self.craft.hp): #emit flames from damage global fragments fragments.append( Fragment('flames', self.craft.pos + (numpy.random.rand(3, 1) - 0.5) * 10, copy(self.craft.v / 2)))
def crashtest( self): #test for ground collision and bullet/missile collision h = ground_height(self.craft.pos) altitude = self.craft.pos[1][0] - h if altitude < 0: #test for ground collision self.crash() return True for obj in bullets + missiles: #test for bullet/missile collision closest_point = mymath.closestpoint(self.craft.pos, obj.pos, obj.pos - obj.v) if mymath.norm(self.craft.pos - closest_point) < 20: obj.pos = closest_point obj.hit(mymath.unit(obj.pos - self.craft.pos)) if type(obj) == Bullet: self.craft.hp -= 1 sounds['hit' + str(random.randint(1, 5))].play() elif type(obj) == Missile: self.craft.hp -= 20 sounds['explosion'].play() if self.craft.hp <= 0: self.crash() return True return False