def on_create(self, config): Activity.on_create(self, config) self.screen_size = pygame.display.get_surface().get_size() self.victory_anim = resources.get("goalani").get_new_handle() self.enemy_anim = resources.get("enemyani").get_new_handle() self.particle_limit = settings.get("particle_limit") self.particle_fps_limit = settings.get("particle_fps_limit") self.optimize_drawing = True self.segment_renderers = [ SegmentRenderer(resources.get("woodtex"),11), SegmentRenderer(resources.get("oozetex"),11), SegmentRenderer(resources.get("icetex"),11), SegmentRenderer(resources.get("voidtex"),11), ] self.spinner_renderers = [ SpinnerRenderer(resources.get("spinner1")), SpinnerRenderer(resources.get("spinner2")), SpinnerRenderer(resources.get("spinner3")), ] self.levelnum = config["level"] self.filename = self.controller.level_path( config["level"]) #if the next level does not exist just back out to the main menu try: self.level_elements = ET.parse( self.filename).getroot() self.reload_level() except IOError: self.finish()
def __init__(self, controller): Activity.__init__(self, controller) self.script = [ ("tut1a", [ (["This is Bob","Bob is a blob"],(225,250)), (["Bob is on a magical quest", "for sparkly things"], (225,425)) ]), ("tut1b", [ (["Hold the right mouse button","to charge Bob up"],(300,250)), (["Release RMB to launch Bob","towards the mouse"],(350,250)), (["Once Bob is launched he cannot","launch again until he has collided","or interacted with some object"],(400,450)) ]), ("tut1c", [ (["These are sparkly things","Touch these to beat a level"],(550,250)) ]), ("tut2a", [ (["These are platforms and spinners"],(400,350)), (["They are made of different materials", "that have different properties"],(400,375)), ]), ("tut2b", [ (["You can manually rotate spinners","that have gears in the middle"],(200,400)), (["Left click on them and move","the mouse to rotate them"],(300,575)), ]), ("tut3a", [ (["These are gravity wells","They either push or pull you."],(300,100)), (["While you are in a gravity well","you are not subject to normal gravity."],(300,400)), ]), ("tut3b", [ (["Use them to perform","sweet orbital maneuvers."],(450,200)), ]), ("tut4", [ (["These are forcefields and magnets","They do what you might expect"],(400,350)), ]), ("tut5a", [ (["These are sheep", "Sheep are assholes", "Sheep murdered your whole family"],(200,400)), (["If you hit sheep at high speeds", "they die. If you hit them", "at low speed you die"],(350,400)), ]), ("tut5b", [ (["Kill the evil bastards", "before they kill you"],(500,600)), ]), ] self.panel = 0 self.caption = 0 self.update_tut()
def handle_event(self, event): event_handled = False if event.type == KEYDOWN: if event.key == K_SPACE: self.caption += 1 if self.caption >= len( self.script[self.panel][1]): self.caption = 0 self.panel += 1 if self.panel >= len(self.script): self.finish() return None self.update_tut() elif event.key == K_ESCAPE: self.finish() if not event_handled: Activity.handle_event( self, event)
def handle_event( self, event): event_handled = False if event.type == MOUSEMOTION: event_handled = True if self._selectedwidget is not None and not self._selectedwidget.rect.collidepoint( event.pos): self._selectedwidget.unselect() self._selectedwidget = None for x in self._widgets: if x.is_selectable() and x.rect.collidepoint(event.pos): self._selectedwidget = x self._selectedwidget.select() break elif event.type == MOUSEBUTTONDOWN: for x in self._widgets: if x.is_clickable() and x.rect.collidepoint(event.pos): if x.onclick is not None: event_handled = True x.onclick() break elif event.type == KEYDOWN: if event.key == K_UP: if self._selectedwidget is not None: index = self._widgets.index( self._selectedwidget)-1 for i in xrange(len(self._widgets)-1): index2 = (index-i)%len(self._widgets) if self._widgets[index2].is_selectable(): print "changing selection", index2 self._selectedwidget.unselect() self._selectedwidget = self._widgets[index2] self._selectedwidget.select() break else: if len( self._widgets) > 0: self._selectedwidget = self._widgets[0] self._selectedwidget.select() elif event.key == K_DOWN: if self._selectedwidget is not None: index = self._widgets.index( self._selectedwidget)+1 for i in xrange(len(self._widgets)-1): index2 = (index+i)%len(self._widgets) if self._widgets[index2].is_selectable(): print "changing selection", index2 self._selectedwidget.unselect() self._selectedwidget = self._widgets[index2] self._selectedwidget.select() break else: if len( self._widgets) > 0: self._selectedwidget = self._widgets[0] self._selectedwidget.select() elif event.key == K_SPACE or event.key == K_RETURN: if self._selectedwidget is not None and self._selectedwidget.is_clickable: if self._selectedwidget.onclick is not None: self._selectedwidget.onclick() elif event.key == K_ESCAPE: self.finish() if not event_handled: Activity.handle_event( self, event)
def update( self, timestep): Activity.update( self, timestep) for x in self._widgets: x.update(timestep)
def __init__(self, controller): Activity.__init__(self, controller) self._widgets = [] self._selectedwidget = None
def draw( self, screen): Activity.draw( self, screen) for x in self._widgets: x.draw( screen)
def draw(self, screen): Activity.draw(self, screen) screen.blit( self.img, (0,0))
def draw(self, screen): Activity.draw(self, screen) if not self.complex_drawing: pymunk.pygame_util.draw( screen, self.space) for ff in self.forcefields: pygame.draw.line( screen, (255,255,255), pymunk.pygame_util.to_pygame( ff.center, screen), pymunk.pygame_util.to_pygame( ff.center+ff.fieldforce, screen)) #draw gravity balls wavesize = 25 begin = int(0.5*self.time*wavesize)%wavesize for g in self.gravballs: if not g.shutdown: pos = pymunk.pygame_util.to_pygame( g.position, screen) if g.strength < 0: for r in xrange(begin, g.wellsize, wavesize): if r > 0: pygame.draw.circle( screen, (200,60,0), pos, r, 1) else: for r in xrange(wavesize-begin, g.wellsize, wavesize): if r > 0: pygame.draw.circle( screen, (100,0,120), pos, r, 1) else: if self.optimize_drawing: screen.blit( self.static_img, (0,0)) else: self.draw_statics(screen) #draw gravity balls wavesize = 25 begin = int(0.5*self.time*wavesize)%wavesize for g in self.gravballs: if not g.shutdown: pos = pymunk.pygame_util.to_pygame( g.position, screen) if g.strength < 0: for r in xrange(begin, g.wellsize, wavesize): if r > 0: pygame.draw.circle( screen, (200,60,0), pos, r, 1) else: for r in xrange(wavesize-begin, g.wellsize, wavesize): if r > 0: pygame.draw.circle( screen, (200,0,240), pos, r, 1) #draw forcefields img = resources.get("fieldbg") for f in self.forcefields: imgw = img.get_width() imgh = img.get_height() offset = (int(f.imgoffset[0])%imgw, int(f.imgoffset[1])%imgh) topleft = pymunk.pygame_util.to_pygame(f.topleft, screen) sub = screen.subsurface( (topleft[0], topleft[1], f.dimensions[0], f.dimensions[1])) for x in xrange( -imgw, int(f.dimensions[0])+imgw, imgw): for y in xrange( -imgh, int(f.dimensions[1])+imgh, imgh): sub.blit( img, (x+offset[0], y-offset[1])) #draw spinners conversion = 360/(2*math.pi) gear = resources.get("spingear") for s in self.spinners: pos = Vec2d( pymunk.pygame_util.to_pygame( s.position, screen)) angle = s.angle angle = int(angle*conversion) material = s.material scale = s.length/60.0 self.spinner_renderers[s.material].draw( screen, angle, scale, pos) if s.mode == "drag": img = pygame.transform.rotate( gear, angle) offset = Vec2d(img.get_width()/2, img.get_height()/2) screen.blit( img, pos-offset) #draw particles for p in self.particles: pos = pymunk.pygame_util.to_pygame( p.position, screen) pygame.draw.circle(screen, p.color, pos, 2) #draw victory locations baseimg = self.victory_anim.get_current_frame() for v in self.victories: pos = pymunk.pygame_util.to_pygame( v.topleft, screen) img = pygame.transform.scale( baseimg, v.dimensions.int_tuple) screen.blit( img, pos) #draw enemies baseimg = self.enemy_anim.get_current_frame() flipped = pygame.transform.flip( baseimg, True, False) for e in self.enemies: pos = pymunk.pygame_util.to_pygame( e.position, screen) if e.velocity[0] < 0: screen.blit( baseimg, (pos[0]-baseimg.get_width()/2, pos[1]-baseimg.get_height()/2)) else: screen.blit( flipped, (pos[0]-baseimg.get_width()/2, pos[1]-baseimg.get_height()/2)) #draw the player if not self.player.dead: if self.charging: baseimg = resources.get("player_charging") else: if self.player_impact > 0: baseimg = resources.get("player_impact") else: baseimg = resources.get("player") if self.player.facing == "left": img = pygame.transform.flip( baseimg, True, False) else: img = baseimg pos = pymunk.pygame_util.to_pygame( self.player.position, screen) offset = Vec2d( img.get_width()/2, img.get_height()/2) screen.blit( img, pos-offset) '''draw the launch indicator if the player is charging up''' mousepos = Vec2d( pygame.mouse.get_pos())#mouse position in screen coordinates playerpos = pymunk.pygame_util.to_pygame( self.player.position, screen)#player pos in screen coords if self.charging: ratio = self.charge/MAXCHARGE mousevect = (mousepos-playerpos).normalized() finalpos = playerpos + mousevect*40 r = int(ratio*LAUNCH_IND_LEN) for x in range(r,10,-3): pos = playerpos+mousevect*x pygame.draw.circle( screen, (255,255-x*2,0), pos.int_tuple, x/8) if self.status_img is not None: screen.blit( self.status_img, (0,int(self.status_offset)))
def handle_event(self, event): event_handled = False if (event.type == MOUSEBUTTONDOWN and event.button == 3) or (event.type == KEYDOWN and event.key == K_TAB): if self.player_launchable: self.charging = True elif (event.type == MOUSEBUTTONUP and event.button == 3) or (event.type == KEYUP and event.key == K_TAB): if self.charging: #figure out the impulse vector diff = self.mousepos-self.player.position dist = diff.get_length() mag = IMPULSEMOD*self.charge force = diff * mag/dist #unstick the player from any sticky objects, re-enable collisions for x in self.player.joints: self.space.remove( x) self.player.shape.collision_type = COLL_PLAYER self.player.joints = [] #finish up self.make_particles( self.player.position, int(self.charge*20), PLAYER_PARTICLE_COLOR) self.player.apply_impulse( force) self.charging = False self.player_launchable = False self.charge = 0.0 self.charge_cap = 0.0 elif event.type == MOUSEBUTTONDOWN and event.button == 1: #deal with draggable spinners mousepos = pygame.mouse.get_pos() mousepos = (mousepos[0],750-mousepos[1]) shapes = self.space.point_query( mousepos) for shape in shapes: if hasattr( shape.body, "draggable") and shape.body.draggable: self.grabbed = shape.body mousebod = pymunk.Body() mousebod.position = self.mousepos joint = pymunk.PivotJoint(mousebod, shape.body, mousepos) joint.max_force = 2e9 self.space.add(joint) self.drag_joint = joint self.drag_body = mousebod break elif event.type == MOUSEBUTTONUP and event.button == 1: #release the grabbed spinner if self.grabbed is not None: self.grabbed.velocity = Vec2d(0,0) self.grabbed.angular_velocity = 0.0 self.grabbed.position = self.grabbed.home_pos self.grabbed.shape.position = self.grabbed.position self.grabbed.reset_forces() self.grabbed = None if self.drag_joint is not None: self.space.remove( self.drag_joint) self.drag_joint = None self.drag_body = None elif event.type == KEYDOWN: if event.key == K_ESCAPE: if self.game_mode != GAME_NORMAL: self.finish() else: self.pause_game() elif event.key == K_F2: self.complex_drawing = not self.complex_drawing elif event.key == K_SPACE: if self.game_mode == GAME_WON: self.start_next_level() elif self.game_mode == GAME_OVER: self.reload_level() else: self.resume_game() elif event.key == K_r: SegmentRenderer.extended_segment_render = not SegmentRenderer.extended_segment_render print SegmentRenderer.extended_segment_render elif event.key == K_q: self.level_elements = ET.parse( self.filename).getroot() self.reload_level() elif event.key == K_1: self.complex_drawing = not self.complex_drawing elif event.key == K_z: self.reposition_player( self.mousepos, (0,0)) elif event.key == K_v: self.player_float += 100 print self.player_float elif event.key == K_b: self.player_float -= 100 print self.player_float elif event.key == K_p: self.make_particles( self.mousepos, 20, PLAYER_PARTICLE_COLOR) elif event.key == K_F12: resources.force_reload() print "schwat" elif event.key == K_d: self.optimize_drawing = not self.optimize_drawing elif event.key == K_F4: pygame.image.save(pygame.display.get_surface(), "screen.png") if not event_handled: Activity.handle_event(self, event)
def update(self, timestep): Activity.update(self, timestep) self.time += timestep pos = pygame.mouse.get_pos() self.mousepos = Vec2d( pos[0], 750-pos[1]) pressed = pygame.mouse.get_pressed() self.update_status_text( timestep) self.victory_anim.cycle( timestep) self.enemy_anim.cycle( timestep) #deal with status text/images if self.status_offset < 0.0: self.status_offset += STATUS_SCROLL_SPEED*timestep #bail out now if the game is paused (or the player won) if self.game_mode == GAME_PAUSE or self.game_mode == GAME_WON: return None #check for player off map if self.game_mode != GAME_OVER: pos = self.player.position if pos[0] < -200 or pos[1] < -200 or pos[0] > self.screen_size[0]+200 or pos[1] > self.screen_size[1]+200: self.kill_player() #enforce terminal velocity on player speed = self.player.velocity.get_length() self.max_speed = max(self.max_speed, speed) if speed > 1000.0: newspeed = (1-timestep)*1000.+timestep*speed self.player.velocity *= newspeed/speed if self.player_impact > 0.0: self.player_impact -= timestep #charge up the players launch speed if self.charging: self.charge_cap += CHARGERATE*timestep if self.charge_cap > MAXCHARGE: self.charge_cap = MAXCHARGE vec = self.mousepos - self.player.position if vec[0] > 0: self.player.facing = "right" else: self.player.facing = "left" self.charge = min(self.charge_cap, vec.get_length()/LAUNCH_IND_LEN) #handle dragging spinners if self.grabbed is not None: normvec = Vec2d(0,1) posvec = self.mousepos - self.grabbed.position self.drag_body.position = self.mousepos self.drag_body.velocity = 0, 0 self.drag_body.reset_forces() for e in self.enemies: if (e.dir > 0 and e.position[0] > e.limits[1]) or (e.dir < 0 and e.position[0] < e.limits[0]): e.dir *= -1 e.velocity = Vec2d( e.dir*100, e.velocity[1]) #do forcefield updates for ff in self.forcefields: ff.imgoffset += ff.fieldforce*5*timestep if ff.point_query( self.player.position): self.player_launchable = True self.player.apply_impulse( ff.fieldforce*FORCEFIELD_STRENGTH*timestep*self.player.mass) if PARTICLE_PHYSICS: for p in self.particles: if ff.point_query( p.position): p.apply_impulse( ff.fieldforce*FORCEFIELD_STRENGTH*timestep*p.mass) #do particle decay #print len(self.particles) for p in self.particles: p.life -= timestep if p.life <= 0: self.space.remove( p, p.shape) self.particles.remove( p) for s in self.spinners: #force any draggable spinners to stop moving, reduces jitter and stuff if s.mode == "drag" and s != self.grabbed: s.angular_velocity = 0.0 s.position = s.home_pos s.velocity = Vec2d(0,0) elif s.mode == "free": s.angular_velocity -= timestep*SPINNER_DAMPENING*s.angular_velocity #deal with gravity balls self.player_floating = False for g in self.gravballs: if g.shutdown: g.life += timestep if g.life > GRAVBALL_LIFE: g.shutdown = False g.life = GRAVBALL_LIFE continue diff = g.position - self.player.position dist = diff.get_length() if dist < g.wellsize: g.life -= timestep if g.life < 0.0: g.life = 0.0 g.shutdown = True d = max( math.pow(dist,1.25), 150) mag = (g.strength)/d*timestep force = self.player.mass*diff*mag/dist self.player.apply_impulse( force) self.player_launchable = True self.player_floating = True if PARTICLE_PHYSICS: for p in self.particles: diff = p.position - g.position dist = diff.get_length() if dist < g.wellsize: d = max( math.pow(dist,1.25), 150) mag = (g.strength)/d*timestep force = p.mass*diff*mag/dist p.apply_impulse( -force) #if the player is in a gravity well apply an impulse to cancel normal gravity if SPECIAL_GRAVITY and self.player_floating: self.player.apply_impulse( (0, self.player_float*timestep)) self.space.step( timestep)