# rocket from math import * from miscmath import * import random import pygame from pygame.locals import * import game, gfx from baseairobj import AirObj STARTIMAGE = 0 MAXIMAGE = 63 DIRECTION = 150 FACING = 300 FRICTION = 0.97 THRUST = 0.11 THRUST_INTERVAL = 5 LOCK_ON = 0 FUEL = 150 THRUST_MULTIPLIER = 1.0 START_SEQ = 10 images = [] def load_game_resources(): global images for loop in range(0,64): filename = "bomb%02d.gif" % loop images.append(gfx.load(filename)) class Rocket(AirObj): """parameters: lock = None, 0, 1 - If 1, rocket 'locks on' to player fuel = None, integer - Units of fuel thrust = None, float - constant multiplier of standard thrust """ def __init__(self,x,y,exhaustobj, start_seq=START_SEQ,lock_on=LOCK_ON,fuel=FUEL,thrust_multiplier=THRUST_MULTIPLIER): """create a new rocket""" AirObj.__init__(self,'rocket',None) global images self.pointvalue = game.point_tbl[self.name] self.dead = 0 self.images = images self.imagenum = STARTIMAGE self.maximage = MAXIMAGE # angles self.direction = DIRECTION # angle we are going toward self.facing = FACING # set proper image for our angle self.imagenum = int( (self.facing-(360.0/128.0)) / (360.0/64.0) ) % 64 self.image = self.images[self.imagenum] self.rect = self.image.get_rect() self.lastrect = None self.x = x self.y = y self.dx = 0.0 self.dy = 0.0 self.rect.topleft = [self.x,self.y] self.xoffset = self.rect.centerx - self.rect.left self.yoffset = self.rect.centery - self.rect.top self.range_left = game.arena.left - game.rocket_range self.range_right = game.arena.right + game.rocket_range self.range_top = game.groundarena.top - game.rocket_range self.range_bottom = game.groundarena.bottom - self.rect.height self.gravity = game.rocket_gravity self.launched = 0 self.exhaustobj = exhaustobj self.lock_on = lock_on self.maxthrust = game.rocket_maxthrust self.friction = FRICTION self.thrustval = THRUST * thrust_multiplier self.fuel = fuel self.thrusttimer = 0 self.thrustinterval = THRUST_INTERVAL # tick interval for course adjustments # how many thrust intervals to go before targeting player self.startseq_timer = start_seq # how many frames we wait until dying self.collidetimer = game.collision_timer # rocket thrust in the direction we're pointing self.thrust = 0.0 self.xthrust = 0.0 self.ythrust = 0.0 self.player_dist = 200 self.exhaustobj.add_particle(self.x,self.y) #print "lockon: %d fuel:%d thrustm:%f" % (lock_on, fuel, thrust_multiplier) def erase(self, background): background(self.lastrect) if self.dead: gfx.dirty(self.lastrect) def draw(self, gfx): r = gfx.surface.blit(self.image, self.rect) gfx.dirty2(r, self.lastrect) self.lastrect = r def collide(self,rect): if self.rect.colliderect(rect): return 1 else: return 0 def tick(self, speedadjust): self.think() self.physics() self.dx += self.xthrust self.dy += self.ythrust if self.dx < -game.rocket_max_vel: self.dx = -game.rocket_max_vel elif self.dx > game.rocket_max_vel: self.dx = game.rocket_max_vel if self.dy < -game.rocket_max_vel: self.dy = -game.rocket_max_vel elif self.dy > game.rocket_max_vel: self.dy = game.rocket_max_vel self.x += self.dx * speedadjust - game.groundspeed self.y += self.dy * speedadjust # out of range? if self.x < self.range_left: self.dead = 1 elif self.x > self.range_right: self.dead = 1 if self.y < self.range_top: self.dead = 1 if self.y > self.range_bottom: self.y = self.range_bottom self.dy = 0 self.exploding = 1 self.image = self.images[self.imagenum] self.rect = self.image.get_rect() self.rect.topleft = [self.x,self.y] # rocket brain - targeting def think(self): self.thrusttimer += 1 if self.thrusttimer % self.thrustinterval != 0: return self.startseq_timer += -1 if self.startseq_timer > 0: # start seq stuff - start climbing in self.direction for startseq thrust intervals # compensate for -game.groundspeed motion dx = 0 dy = self.dy else: dx,dy = self.dx,self.dy # past start sequence - target player xdist = float(game.player.x - self.x) ydist = float(game.player.y - self.y) self.player_dist = sqrt(xdist**2 + ydist**2) if ydist == 0: angle_to_player = 180.0 else: angle_to_player = - deg(atan2(ydist,xdist)) # only target if player is alive, otherwise keep going in old direction if game.player.dead == 0: self.direction = angle_to_player # change image based on direction of motion if dx != 0 and dy != 0: facing = fmod(deg(atan2(dy,dx)) + 90,360) if facing < 0: facing = 360 + facing self.facing = facing else: facing = self.facing self.imagenum = int( (facing-(360.0/128.0)) / (360.0/64.0) ) % 64 self.image = self.images[self.imagenum] self.rect = self.image.get_rect() # thrust self.thrust = self.impulse() rad_angle = rad(self.direction) self.xthrust = cos(rad_angle) * self.thrust self.ythrust = - sin(rad_angle) * self.thrust #print "direction: %f facing: %f a2p: %f" % (self.direction,facing,self.direction) def physics(self): self.dy = self.dy * self.friction if self.fuel == 0: self.dy = self.dy + self.gravity def impulse(self): self.fuel += -1 if self.fuel < 0: self.fuel = 0 return 0 else: if self.fuel % 3 == 0: x=self.x+self.xoffset y=self.y+self.yoffset if game.groundarena.contains((x,y,1,1)): self.exhaustobj.add_particle(x,y) # missile lock on if self.lock_on == 1: if self.player_dist < 150: #print "lock on!" self.fuel += -1 return self.thrustval * 2 else: return self.thrustval # no lock on else: return self.thrustval