def _create_sprites(self): SPEED = 0.4 logo_image = common.load_image('scene/intro/ceferino.png') logo = Sprite(logo_image) logo.scale = 4 logo.rotation = 180 logo.opacity = 0 logo.do(Place((100, 230))) logo.do(Delay(SPEED / 2) + (FadeIn(SPEED * 2) | RotateBy(180, SPEED) | ScaleTo(1, SPEED))) losers_image = common.load_image('scene/intro/losers.png') losers = Sprite(losers_image) losers.position = 300, 500 losers.rotation = 180 losers.opacity = 0 losers.do(Delay(SPEED) + (MoveTo((300, 250), SPEED) | FadeIn(SPEED) | RotateBy(180, SPEED))) juegos_image = common.load_image('scene/intro/juegos.png') juegos = Sprite(juegos_image) juegos.position = 500, 0 juegos.rotation = -180 juegos.opacity = 0 juegos.do(Delay(SPEED/2 * 3) + (MoveTo((520, 250), SPEED) | FadeIn(SPEED) | RotateBy(180, SPEED)) + Delay(2) + CallFunc(self.skip_scene)) self.add(logo) self.add(losers) self.add(juegos) self.juegos = juegos
def check_queue(self, dt=0): width, height = cocos.director.director.get_window_size() image = fetch_image() sprite = Sprite(image) sprite.rotation = random.randint(-25, 25) end_scale = 1024.0 / image.width sw = int((image.width * end_scale) / 2) sh = int((image.height * end_scale) / 2) sprite.x = random.randint(sw, width - sw) sprite.y = random.randint(sh, height - sh) sprite.opacity = 0 sprite.scale = end_scale * 1.5 sprite.do( spawn( FadeIn(.2), AccelDeccel(ScaleTo(end_scale, duration=.4))) + Delay(15) + FadeOut(.5) + CallFunc(sprite.kill)) self.z += 1 self.add(sprite, z=self.z)
def draw( self ): super(GameCtrl, self).draw() glLoadIdentity() bodies = self.model.world.GetBodyList() i = 0 for b in bodies: props = b.GetUserData() if not props: continue sprite = props.get_sprite() if not sprite: if props.isCharacter: sprite = Sprite(self.image) elif props.isBlock: shape = b.GetShapeList()[0] vertices = shape.getVertices_b2Vec2() sprite = RectBlock(vertices) print sprite.p1, sprite.p2, sprite.p3, sprite.p4 else: continue props.set_sprite(sprite) self.add(sprite) sprite.position = (b.position.x * self.model.zoom), \ (b.position.y * self.model.zoom) degrees = -(b.GetAngle() * 180) / math.pi sprite.rotation = degrees # center the image glTranslatef(-320, -240, -320.0)
def draw( self ): super(cocos_box2d_layer,self).draw() glLoadIdentity() bodies = self.world.GetBodyList() i = 0 for b in bodies: userdata = b.GetUserData() if not userdata: userdata = {} b.SetUserData(userdata) sprite = userdata.get("sprite") if not sprite: if userdata.get("sister1"): sprite = Sprite(self.image_sister1) elif userdata.get("sister2"): sprite = Sprite(self.image_sister2) else: sprite = Sprite(self.image) self.add(sprite) userdata["sprite"] = sprite sprite.position = (b.position.x * self.zoom), (b.position.y * self.zoom) degrees = (b.GetAngle() * 180) / math.pi sprite.rotation = degrees # center the image glTranslatef(-320, -240, -320.0)
def __init__(self, layer): super(Light, self).__init__() for c in layer.get_children(): sp = Sprite(c.image) sp.source_position = c.position sp.position = c.position sp.scale = c.scale sp.source_scale = c.scale sp.rotation = c.rotation sp.opacity = c.opacity sp.dx = 0 sp.dy = 0 sp.dt = random.random()*3.15 self.add( sp )
def __init__(self): super( TestLayer, self ).__init__() x,y = director.get_window_size() self.boids = [] for i in range(20): b = Sprite('boid.png') b.x = random.randint(0, x) b.y = random.randint(0, y) b.rotation = 0 #random.randint(0, 360) b.speed = 26#200 #random.randint(0, 400) self.boids.append(b) self.add(b) self.mouse = cocos.cocosnode.CocosNode() self.schedule(self.update)
def draw( self ): super(GameCtrl, self).draw() glLoadIdentity() bodies = self.model.world.GetBodyList() i = 0 for b in bodies: props = b.GetUserData() if not props: continue sprite, dsprite = props.get_sprite() if not sprite: if props.isCharacter: shape = b.GetShapeList()[0] vertices = shape.getVertices_b2Vec2() if self.debug: dsprite = RectBlock(vertices, zoom=self.model.zoom, color=(255,0,0,255)) sprite = Sprite(self.image) elif props.isBlock: shape = b.GetShapeList()[0] vertices = shape.getVertices_b2Vec2() sprite = RectBlock(vertices, zoom=self.model.zoom) dsprite = None else: continue props.set_sprite(sprite, dsprite) self.add(sprite) if dsprite: self.add(dsprite) sprite.position = (b.position.x * self.model.zoom), \ (b.position.y * self.model.zoom) degrees = -(b.GetAngle() * 180) / math.pi sprite.rotation = degrees if dsprite: dsprite.position = (b.position.x * self.model.zoom), \ (b.position.y * self.model.zoom) degrees = -(b.GetAngle() * 180) / math.pi dsprite.rotation = degrees # center the image glTranslatef(-400, -300, -800.0)
def __init__(self): super(TestLayer, self).__init__() x, y = director.get_window_size() sprite1 = Sprite("grossini.png") self.add(sprite1) sprite1.position = 300, 300 sprite2 = Sprite("grossini.png") sprite1.add(sprite2) sprite2.position = -50, -50 sprite3 = Sprite("grossini.png") sprite2.add(sprite3) sprite3.position = 150, 150 sprite3.rotation = 0 sprite3.opacity = 128 self.sprite3 = sprite3 sprite1.do(ScaleBy(1.5, 10)) sprite2.do(MoveBy((100, -150), 5)) sprite3.do(RotateBy(360, 20))
def __init__(self): super( TestLayer, self ).__init__() x,y = director.get_window_size() sprite1 = Sprite('grossini.png') self.add( sprite1 ) sprite1.position = 300,300 sprite2 = Sprite('grossini.png') sprite1.add( sprite2 ) sprite2.position = -50,-50 sprite3 = Sprite('grossini.png') sprite2.add( sprite3 ) sprite3.position = 150,150 sprite3.rotation = 0 sprite3.opacity = 128 self.sprite3 = sprite3 sprite1.do( ScaleBy(1.5, 10) ) sprite2.do( MoveBy((100,-150),5) ) sprite3.do( RotateBy(360,20) )
def performAttackOnUnit(board, target_unit, overheat=0): # perform an attack on the given target BattleUnit battle = board.battle turn_unit = battle.getTurnUnit() if turn_unit is None or target_unit is None\ or turn_unit.isDestroyed() or target_unit.isDestroyed(): # TODO: make sure it is a player unit's turn return 0 src_cell = turn_unit.col, turn_unit.row dest_cell = target_unit.col, target_unit.row # minimum travel time to target used to determine when to show the damage floater min_travel_time = 0 # maximum travel time to target used to determine when all animations are finished max_travel_time = 0 # cell distance used to determine which range of weapons will fire cell_distance = Battle.getCellDistance(src_cell, dest_cell) target_range = Battle.getDistanceRange(cell_distance) print(target_range + ": " + str(src_cell) + " -> " + str(dest_cell) + " = " + str(cell_distance)) # perform the attack and show the results attack_results = battle.performAttack(turn_unit, target_unit, overheat=overheat) attack_damage = attack_results.attack_damage critical_type = attack_results.critical_type # determine actual target point based on the target unit sprite size target_sprite = target_unit.getSprite() real_x = (dest_cell[0] * Board.TILE_SIZE) + Board.TILE_SIZE // 2 real_y = (dest_cell[1] * Board.TILE_SIZE) + (2 * target_sprite.get_height() // 3) # if missed, show a visible weapon miss if attack_damage == 0: real_x += random.choice([-1, 1]) * Board.TILE_SIZE real_y += random.choice([-1, 0, 1]) * Board.TILE_SIZE for weaponMap in turn_unit.mech.weapons: for weapon in weaponMap.iterkeys(): if not weapon.inRange(cell_distance): continue weapon_data = weaponMap[weapon] # get sound channel to use just for this weapon weapon_channel = pygame.mixer.find_channel() if weapon_channel is None: weapon_channel = pygame.mixer.Channel(0) weapon_channel.set_volume(Settings.get_volume_fx()) weapon_offset = weapon_data.get('offset', [0, 0]) weapon_x = turn_unit.sprite.x + weapon_offset[0] weapon_y = turn_unit.sprite.y - (Board.TILE_SIZE // 2) + weapon_offset[1] weapon_color = weapon.get_color() if weapon.isPPC(): # fire test ppcs ppc = Meteor() ppc.size = 10 ppc.speed = 20 ppc.gravity = Point2(0, 0) # TODO: offer decreased particle emission rate to improve performance ppc.emission_rate = 100 ppc.life = 0.5 ppc.life_var = 0.1 ppc.position = weapon_x, weapon_y board.add(ppc, z=1000) target_x = real_x + random_offset() target_y = real_y + random_offset() target_pos = target_x, target_y # figure out the duration based on speed and distance ppc_speed = weapon.get_speed() # pixels per second distance = Point2(ppc.x, ppc.y).distance(Point2(target_x, target_y)) ppc_t = distance / ppc_speed ppc_sound = Resources.ppc_sound weapon_channel.play(ppc_sound) action = Delay(0.5) + MoveTo((target_x, target_y), duration=ppc_t) \ + CallFunc(impact_ppc, ppc) \ + Delay(0.5) + CallFunc(ppc.kill) \ + Delay(ppc_sound.get_length()) \ + CallFunc(weapon_channel.stop) ppc.do(action) travel_time = 0.5 + ppc_t if min_travel_time == 0 or min_travel_time > travel_time: min_travel_time = travel_time if travel_time > max_travel_time: max_travel_time = travel_time elif weapon.isFlamer(): # fire test flamer flamer = Fire() flamer.size = 25 flamer.speed = 300 flamer.gravity = Point2(0, 0) # TODO: offer decreased particle emission rate to improve performance flamer.emission_rate = 100 dx = real_x - weapon_x dy = real_y - weapon_y rads = atan2(-dy, dx) rads %= 2 * pi angle = degrees(rads) + 90 flamer.rotation = angle flamer.angle_var = 5 flamer.pos_var = Point2(5, 5) flamer.position = weapon_x, weapon_y board.add(flamer, z=1000) target_x = real_x + random_offset() target_y = real_y + random_offset() target_pos = target_x, target_y # figure out the duration based on speed and distance flamer_speed = weapon.get_speed() # pixels per second distance = Point2(flamer.x, flamer.y).distance(Point2(target_x, target_y)) flamer_t = 1 flamer.life = distance / flamer_speed flamer.life_var = 0 flamer_sound = Resources.flamer_sound weapon_channel.play(flamer_sound) action = Delay(flamer_t) \ + CallFunc(impact_flamer, flamer) \ + CallFunc(weapon_channel.fadeout, 750) \ + Delay(flamer_t) + CallFunc(flamer.kill) \ + CallFunc(weapon_channel.stop) flamer.do(action) travel_time = flamer_t if min_travel_time == 0 or min_travel_time > travel_time: min_travel_time = travel_time if travel_time > max_travel_time: max_travel_time = travel_time elif weapon.isLaser(): # fire test laser las_life = 1.0 las_size = (1, 1, 1) if weapon.isShort(): las_size = (2, 1, 0.5) las_life = 0.5 elif weapon.isMedium(): las_size = (3, 2, 1) las_life = 0.75 elif weapon.isLong(): las_size = (6, 4, 2) las_life = 1.0 target_x = real_x + random_offset() target_y = real_y + random_offset() target_pos = target_x, target_y las_outer = gl.SingleLine((weapon_x, weapon_y), (target_x, target_y), width=las_size[0], color=(weapon_color[0], weapon_color[1], weapon_color[2], 50)) las_middle = gl.SingleLine((weapon_x, weapon_y), (target_x, target_y), width=las_size[1], color=(weapon_color[0], weapon_color[1], weapon_color[2], 125)) las_inner = gl.SingleLine((weapon_x, weapon_y), (target_x, target_y), width=las_size[2], color=(weapon_color[0], weapon_color[1], weapon_color[2], 200)) las_outer.visible = False las_middle.visible = False las_inner.visible = False node = cocos.layer.Layer() node.add(las_outer, z=1) node.add(las_middle, z=2) node.add(las_inner, z=3) board.add(node, z=1000) # give lasers a small particle pre-fire effect laser_charge = Galaxy() laser_charge.angle = 270 laser_charge.angle_var = 180 laser_charge.position = weapon_x, weapon_y laser_charge.size = 10 laser_charge.size_var = 5 laser_charge.emission_rate = 15 laser_charge.life = 0.5 laser_charge.speed = 0 laser_charge.speed_var = 0 laser_charge.start_color = Color(weapon_color[0] / 255, weapon_color[1] / 255, weapon_color[2] / 255, 1.0) laser_charge.end_color = Color(weapon_color[0] / 255, weapon_color[1] / 255, weapon_color[2] / 255, 1.0) node.add(laser_charge, z=0) laser_drift = random.uniform(-15.0, 15.0), random.uniform(-15.0, 15.0) las_action = Delay(0.5) + ToggleVisibility() \ + CallFunc(create_laser_impact, board, target_pos, laser_drift, las_life) \ + gl.LineDriftBy(laser_drift, las_life) \ + CallFunc(laser_charge.stop_system) + CallFunc(node.kill) las_outer.do(las_action) las_middle.do(las_action) las_inner.do(las_action) las_sound = Resources.las_sound weapon_channel.play(las_sound) las_duration_ms = int(las_action.duration * 1000) weapon_channel.fadeout(las_duration_ms) travel_time = 0.5 if min_travel_time == 0 or min_travel_time > travel_time: min_travel_time = travel_time if travel_time > max_travel_time: max_travel_time = travel_time elif weapon.isBallistic(): # fire test ballistic projectile num_ballistic = weapon.get_projectiles() if weapon.isGauss(): ballistic_img = Resources.gauss_img elif weapon.isLBX(): # LBX fires only one projectile, but will appear to have multiple random impacts num_ballistic = 1 ballistic_img = Resources.buckshot_img else: ballistic_img = Resources.ballistic_img # machine gun sound only plays once instead of per projectile cannon_sound = None if weapon.isMG(): cannon_sound = Resources.machinegun_sound elif weapon.isGauss(): cannon_sound = Resources.gauss_sound for i in range(num_ballistic): ballistic = Sprite(ballistic_img) ballistic.visible = False ballistic.position = weapon_x, weapon_y ballistic.scale = weapon.get_scale() ballistic.anchor = 0, 0 dx = real_x - weapon_x dy = real_y - weapon_y rads = atan2(-dy, dx) rads %= 2 * pi angle = degrees(rads) ballistic.rotation = angle target_x = real_x + random_offset() target_y = real_y + random_offset() target_pos = target_x, target_y # figure out the duration based on speed and distance ballistic_speed = weapon.get_speed() # pixels per second distance = Point2(weapon_x, weapon_y).distance(Point2(target_x, target_y)) ballistic_t = distance / ballistic_speed # setup the firing sound if cannon_sound is None: cannon_sound = Resources.cannon_sound impact_func = create_ballistic_impact if weapon.isLBX(): impact_func = create_lbx_impact action = Delay(i * 0.1) + ToggleVisibility() \ + CallFunc(weapon_channel.play, cannon_sound) \ + MoveTo((target_x, target_y), ballistic_t) \ + CallFunc(impact_func, weapon, board, target_pos) \ + CallFunc(ballistic.kill) if weapon.isGauss(): # give gauss sound a bit more time to stop action += Delay(cannon_sound.get_length()) if i == num_ballistic - 1: # stop the sound channel after the last projectile only action += CallFunc(weapon_channel.stop) ballistic.do(action) board.add(ballistic, z=1000 + i) travel_time = (i * 0.1) + ballistic_t if min_travel_time == 0 or min_travel_time > travel_time: min_travel_time = travel_time if travel_time > max_travel_time: max_travel_time = travel_time elif weapon.isMissile(): # get another sound channel to use just for the explosions explosion_channel = pygame.mixer.find_channel() if explosion_channel is None: explosion_channel = pygame.mixer.Channel(1) explosion_channel.set_volume(Settings.get_volume_fx()) # fire test missile projectile missile_img = Resources.missile_img num_missile = weapon_data.get('count', 1) num_per_row = 1 if weapon.isLRM(): num_per_row = 5 elif weapon.isSRM(): num_per_row = 2 for i in range(num_missile): tube_x = i % num_per_row tube_y = i // num_per_row missile = Sprite(missile_img) missile.visible = False missile.position = weapon_x + tube_x, weapon_y + tube_y missile.scale = weapon.get_scale() missile.anchor = 0, 0 dx = real_x - weapon_x dy = real_y - weapon_y rads = atan2(-dy, dx) rads %= 2 * pi angle = degrees(rads) missile.rotation = angle target_x = real_x + random_offset() target_y = real_y + random_offset() target_pos = target_x, target_y # figure out the duration based on speed and distance missile_speed = weapon.get_speed() # pixels per second distance = Point2(weapon_x, weapon_y).distance(Point2(target_x, target_y)) missile_t = distance / missile_speed rand_missile_sound = random.randint(0, 7) missile_sound = Resources.missile_sounds[rand_missile_sound] explosion_sound = Resources.impact_sound action = Delay(i * 0.05) + ToggleVisibility() \ + CallFunc(weapon_channel.play, missile_sound) \ + MoveTo((target_x, target_y), missile_t) \ + CallFunc(create_missile_impact, board, target_pos) \ + CallFunc(missile.kill) \ + CallFunc(explosion_channel.play, explosion_sound) \ + Delay(0.5) if i == num_missile - 1: # stop the sound channels after the last missile only action += CallFunc(weapon_channel.stop) + CallFunc(explosion_channel.stop) missile.do(action) board.add(missile, z=1000 + i) travel_time = (i * 0.05) + missile_t if min_travel_time == 0 or min_travel_time > travel_time: min_travel_time = travel_time if travel_time > max_travel_time: max_travel_time = travel_time # scroll focus over to the target area halfway through the travel time target_area = Board.board_to_layer(target_unit.col, target_unit.row) # show damage floater after the travel time of the first projectile to hit floater_text = "%i" % attack_damage if attack_damage == 0: floater_text = "MISS" floater = floaters.TextFloater(floater_text) floater.visible = False floater.position = real_x, real_y + target_sprite.get_height() // 3 board.add(floater, z=2000) action = Delay(min_travel_time / 2) + CallFunc(board.scroller.set_focus, *target_area) \ + Delay(min_travel_time / 2) + ToggleVisibility() \ + Delay(0.25) + MoveBy((0, Board.TILE_SIZE), 1.0) \ + FadeOut(1.0) + CallFunc(floater.kill) floater.do(action) if critical_type is not None: crit_floater = floaters.TextFloater(critical_type) crit_floater.visible = False crit_floater.position = real_x, real_y + target_sprite.get_height() // 3 board.add(crit_floater, z=2000) action = Delay(min_travel_time) + Delay(1.0) + ToggleVisibility() \ + Delay(0.25) + MoveBy((0, Board.TILE_SIZE), 1.5) \ + FadeOut(1.5) + CallFunc(crit_floater.kill) crit_floater.do(action) if action.duration > max_travel_time: max_travel_time = action.duration stats_action = Delay(min_travel_time) + CallFunc(target_sprite.updateStatsIndicators) \ + CallFunc(Interface.UI.updateTargetUnitStats, target_unit) target_sprite.do(stats_action) if target_unit.structure > 0: print("Remaining %i/%i" % (target_unit.armor, target_unit.structure)) else: print("Target destroyed!") # show destroyed floater after the travel time of the first projectile to hit destroyed = floaters.TextFloater("DESTROYED") destroyed.visible = False destroyed.position = real_x, real_y + target_sprite.get_height() // 3 board.add(destroyed, z=5000) action = Delay(max_travel_time) + ToggleVisibility() \ + (MoveBy((0, Board.TILE_SIZE), 1.0) | CallFunc(create_destruction_explosions, board, target_unit)) \ + Delay(0.5) + CallFunc(target_sprite.destroy) + FadeOut(2.0) + CallFunc(destroyed.kill) destroyed.do(action) # give a bit of extra time to explode max_travel_time = action.duration return max_travel_time
def update(self, dt): # Create a list of pressed keys key_names = [symbol_string(k) for k in self.keys_being_pressed] # Turn player angle to radians # Get the vector angle of the player player2_radians = self.player2.rotation * (pi/180) player_radians = self.player.rotation * (pi/180) self.player.vector_angle = xAngle, yAngle = sin(player_radians), cos(player_radians) self.player2.vector_angle = xAngle, yAngle = sin(player2_radians), cos(player2_radians) for key in key_names: # Handle player input if key == "LEFT": self.player2.rotation -= 1 elif key == "RIGHT": self.player2.rotation += 1 elif key == "UP": self.player2.body.apply_impulse ( (self.player2.vector_angle[0] * 20, self.player2.vector_angle[1] * 20) ) elif key == "DOWN": self.player2.body.apply_impulse( (-self.player2.vector_angle[0] * 20, -self.player2.vector_angle[1] * 20) ) if key == "BACKSPACE": if self.player2.cooldown >= 20: laser = Sprite('weapons/LaserMKI.png') laser.rotation = self.player2.rotation laser.position = self.player2.get_rect().center laser.vector = self.player2.vector_angle laser.owner = self.player2 laser.damage = 100 self.weapon_batch.add(laser) self.laser_count.add(laser) self.player2.cooldown = 0 if key == "A": self.player.rotation -= 1 elif key == "D": self.player.rotation += 1 elif key == "W": self.player.body.apply_impulse ( (self.player.vector_angle[0] * 20, self.player.vector_angle[1] * 20) ) elif key == "S": self.player.body.apply_impulse( (-self.player.vector_angle[0] * 20, -self.player.vector_angle[1] * 20) ) if key == "SPACE": if self.player.cooldown >= 20: laser = Sprite('weapons/LaserMKI.png') laser.rotation = self.player.rotation laser.position = self.player.get_rect().center laser.vector = self.player.vector_angle laser.owner = self.player laser.damage = 100 self.weapon_batch.add(laser) self.laser_count.add(laser) self.player.cooldown = 0 for laser in self.laser_count: laser.position = laser.position[0] + laser.vector[0] * dt * 2000, laser.position[1] + laser.vector[1] * dt * 2000 # Update asteroids and planetary gravity self.planetoid_gravity(self.player.body, 5000000, 1.0, dt) self.planetoid_gravity(self.player2.body, 5000000, 1.0, dt) self.update_asteroids(dt) if self.destroy_flag == True: if len(self.asteroids.asteroid_count) <= 5: #print "There are %s asteroids in the scene" % (str(len(self.asteroids.asteroid_count))) self.asteroids.create_asteroid("garbage input", 'new') self.destroy_flag = False # Step the simulation self.space.step(0.05) self.player_player_damage() # Update player position self.player.position = self.player.body.position self.player2.position = self.player2.body.position # Update player tails self.update_trail(self.trail_list[0], self.player) self.update_trail(self.trail_list[1], self.player2) if self.player.health <= 0 or self.player2.health <= 0: director.replace(SplitColsTransition(GameOver(self.player.score, self.player2.score)))
def updateWithSize(self, ws, so, zm): self._stageOrigin[0] = int(self._stageOrigin[0]) self._stageOrigin[1] = int(self._stageOrigin[1]) if self._winSize == ws and self._stageOrigin == so and self._zoom == zm: return self._winSize = ws self._stageOrigin = so self._zoom = zm # TODO:@twenty0ne # CCScale9Sprite.preferedSize # Resize backrounds self._bgHorizontal.scale_x = self._winSize[0]/self._bgHorizontal.width self._bgHorizontal.scale_y = self._kCCBRulerWidth/self._bgHorizontal.height self._bgVertical.scale_x = self._kCCBRulerWidth/self._bgVertical.width self._bgVertical.scale_y = self._winSize[1]/self._bgVertical.height # Add marks and numbers for obj in self._marksVertical.get_children(): self._marksVertical.remove(obj) for obj in self._marksHorizontal.get_children(): self._marksHorizontal.remove(obj) # Vertical marks y = int(so[1]) - (int(so[1])/10)*10 while y < ws[1]: yDist = abs(y - int(self._stageOrigin[1])) mark = None addLabel = False if yDist == 0: mark = Sprite("images/ruler-mark-origin.png") addLabel = True elif yDist%50 == 0: mark = Sprite("images/ruler-mark-major.png") addLabel = True else: mark = Sprite("images/ruler-mark-minor.png") mark.image_anchor = 0,0.5 mark.position = 0,y self._marksVertical.add(mark) if addLabel: displayDist = yDist / self._zoom strDist = str(displayDist) strLen = len(strDist) for i in range(0, strLen): lbl = Label(strDist[i], color=(0,0,0,255), font_size=8) lbl.anchor = 0,0 lbl.position = 2,(y+1+10*(strLen-i-1)) self._marksVertical.add(lbl) y = y + 10 # Horizontal marks x = int(so[0]) - (int(so[0])/10)*10 while x < ws[0]: xDist = abs(x - int(self._stageOrigin[0])) mark = None addLabel = False if xDist == 0: mark = Sprite("images/ruler-mark-origin.png") addLabel = True elif xDist%50 == 0: mark = Sprite("images/ruler-mark-major.png") addLabel = True else: mark = Sprite("images/ruler-mark-minor.png") mark.image_anchor = 0,0.5 mark.position = x,0 mark.rotation = -90 self._marksHorizontal.add(mark) if addLabel: displayDist = xDist / self._zoom lbl = Label(str(displayDist), color=(0,0,0,255), font_size=8) lbl.anchor = 0,0 lbl.position = x+1,1 self._marksHorizontal.add(lbl) x = x + 10
def __init__(self): super(RulersLayer, self).__init__() self._kCCBRulerWidth = 15 self._stageOrigin = [0,0] self._winSize = [0,0] self._zoom = 1.0 # TODO:@twenty0ne # CCScale9Sprite bgVertical = Sprite('images/ruler-bg-vertical.png') # TODO:@twenty0ne # notice image_anchor, anchor, transform_anchor difference bgVertical.image_anchor = 0,0 self.add(bgVertical) self._bgVertical = bgVertical bgHorizontal = Sprite('images/ruler-bg-horizontal.png') bgHorizontal.image_anchor = 0,0 self.add(bgHorizontal, z=2) self._bgHorizontal = bgHorizontal marksVertical = CocosNode() self.add(marksVertical, z=1) self._marksVertical = marksVertical marksHorizontal = CocosNode() self.add(marksHorizontal, z=3) self._marksHorizontal = marksHorizontal mouseMarkVertical = Sprite('images/ruler-guide.png') mouseMarkVertical.image_anchor = 0,0.5 mouseMarkVertical.visible = False self.add(mouseMarkVertical, z=4) self._mouseMarkVertical = mouseMarkVertical mouseMarkHorizontal = Sprite('images/ruler-guide.png') mouseMarkHorizontal.rotation = -90 mouseMarkHorizontal.image_anchor = 0,0.5 mouseMarkHorizontal.visible = False self.add(mouseMarkHorizontal, z=4) self._mouseMarkHorizontal = mouseMarkHorizontal xyBg = Sprite('images/ruler-xy.png') xyBg.image_anchor = 0,0 xyBg.position = 0,0 self.add(xyBg, z=5) lblX = Label("0", position=(40,3), color=(0,0,0,255), font_size=8, anchor_x="right") #lblX.anchor = 1,0 #lblX.position = 47,3 lblX.visible = False self.add(lblX, z=6) self._lblX = lblX lblY = Label("0", position=(90,3), color=(0,0,0,255), font_size=8, anchor_x="right") #lblY.anchor = 1,0 #lblY.position = 97,3 lblY.visible = False self.add(lblY, z=6) self._lblY = lblY
def performAttackOnUnit(battle, target_unit): # perform an attack on the given target BattleUnit turn_unit = battle.getTurnUnit() if turn_unit is None or target_unit is None\ or turn_unit.isDestroyed() or target_unit.isDestroyed(): # TODO: make sure it is a player unit's turn return 0 src_cell = turn_unit.col, turn_unit.row dest_cell = target_unit.col, target_unit.row # minimum travel time to target used to determine when to show the damage floater min_travel_time = 0 # maximum travel time to target used to determine when all animations are finished max_travel_time = 0 # cell distance used to determine which range of weapons will fire cell_distance = Battle.getCellDistance(src_cell, dest_cell) target_range = Battle.getDistanceRange(cell_distance) print(target_range + ": " + str(src_cell) + " -> " + str(dest_cell) + " = " + str(cell_distance)) # TODO: introduce dynamic damage (optional?) attack_damage = int(getattr(turn_unit, target_range)) # apply damage to model before animating attack_remainder = target_unit.applyDamage(attack_damage) # determine actual target point based on the target unit sprite size target_sprite = target_unit.getSprite() real_x = (dest_cell[0] * Board.TILE_SIZE) + Board.TILE_SIZE // 2 real_y = (dest_cell[1] * Board.TILE_SIZE) + (2 * target_sprite.get_height() // 3) for weaponMap in turn_unit.mech.weapons: for weapon in weaponMap.iterkeys(): if not weapon.inRange(cell_distance): continue weapon_data = weaponMap[weapon] # get sound channel to use just for this weapon weapon_channel = pygame.mixer.find_channel() if weapon_channel is None: weapon_channel = pygame.mixer.Channel(0) weapon_offset = weapon_data.get('offset', [0, 0]) weapon_x = turn_unit.sprite.position[0] + weapon_offset[0] weapon_y = turn_unit.sprite.position[1] + weapon_offset[1] weapon_color = weapon.get_color() if weapon.isPPC(): # fire test ppcs ppc = Meteor() ppc.size = 10 ppc.speed = 20 ppc.gravity = Point2(0, 0) # TODO: offer decreased particle emission rate to improve performance ppc.emission_rate = 100 ppc.life = 0.5 ppc.life_var = 0.1 ppc.position = weapon_x, weapon_y battle.board.add(ppc, z=1000) target_x = real_x + random_offset() target_y = real_y + random_offset() target_pos = target_x, target_y # figure out the duration based on speed and distance ppc_speed = weapon.get_speed() # pixels per second distance = Point2(ppc.x, ppc.y).distance(Point2(target_x, target_y)) ppc_t = distance / ppc_speed ppc_sound = Resources.ppc_sound weapon_channel.play(ppc_sound) action = Delay(0.5) + MoveTo((target_x, target_y), duration=ppc_t) \ + CallFunc(impact_ppc, ppc) \ + Delay(0.5) + CallFunc(ppc.kill) \ + Delay(ppc_sound.get_length()) \ + CallFunc(weapon_channel.stop) ppc.do(action) travel_time = 0.5 + ppc_t if min_travel_time == 0 or min_travel_time > travel_time: min_travel_time = travel_time if travel_time > max_travel_time: max_travel_time = travel_time elif weapon.isFlamer(): # fire test flamer flamer = Fire() flamer.size = 25 flamer.speed = 300 flamer.gravity = Point2(0, 0) # TODO: offer decreased particle emission rate to improve performance flamer.emission_rate = 100 dx = real_x - weapon_x dy = real_y - weapon_y rads = atan2(-dy, dx) rads %= 2 * pi angle = degrees(rads) + 90 flamer.rotation = angle flamer.angle_var = 5 flamer.pos_var = Point2(5, 5) flamer.position = weapon_x, weapon_y battle.board.add(flamer, z=1000) target_x = real_x + random_offset() target_y = real_y + random_offset() target_pos = target_x, target_y # figure out the duration based on speed and distance flamer_speed = weapon.get_speed() # pixels per second distance = Point2(flamer.x, flamer.y).distance( Point2(target_x, target_y)) flamer_t = 1 flamer.life = distance / flamer_speed flamer.life_var = 0 flamer_sound = Resources.flamer_sound weapon_channel.play(flamer_sound) action = Delay(flamer_t) \ + CallFunc(impact_flamer, flamer) \ + CallFunc(weapon_channel.fadeout, 750) \ + Delay(flamer_t) + CallFunc(flamer.kill) \ + CallFunc(weapon_channel.stop) flamer.do(action) travel_time = flamer_t if min_travel_time == 0 or min_travel_time > travel_time: min_travel_time = travel_time if travel_time > max_travel_time: max_travel_time = travel_time elif weapon.isLaser(): # fire test laser las_life = 1.0 las_size = (1, 1, 1) if weapon.isShort(): las_size = (2, 1, 0.5) las_life = 0.5 elif weapon.isMedium(): las_size = (3, 2, 1) las_life = 0.75 elif weapon.isLong(): las_size = (6, 4, 2) las_life = 1.0 target_x = real_x + random_offset() target_y = real_y + random_offset() target_pos = target_x, target_y las_outer = gl.SingleLine( (weapon_x, weapon_y), (target_x, target_y), width=las_size[0], color=(weapon_color[0], weapon_color[1], weapon_color[2], 50)) las_middle = gl.SingleLine( (weapon_x, weapon_y), (target_x, target_y), width=las_size[1], color=(weapon_color[0], weapon_color[1], weapon_color[2], 125)) las_inner = gl.SingleLine( (weapon_x, weapon_y), (target_x, target_y), width=las_size[2], color=(weapon_color[0], weapon_color[1], weapon_color[2], 200)) las_outer.visible = False las_middle.visible = False las_inner.visible = False node = cocos.layer.Layer() node.add(las_outer, z=1) node.add(las_middle, z=2) node.add(las_inner, z=3) battle.board.add(node, z=1000) # give lasers a small particle pre-fire effect laser_charge = Galaxy() laser_charge.angle = 270 laser_charge.angle_var = 180 laser_charge.position = weapon_x, weapon_y laser_charge.size = 10 laser_charge.size_var = 5 laser_charge.emission_rate = 15 laser_charge.life = 0.5 laser_charge.speed = 0 laser_charge.speed_var = 0 laser_charge.start_color = Color(weapon_color[0] / 255, weapon_color[1] / 255, weapon_color[2] / 255, 1.0) laser_charge.end_color = Color(weapon_color[0] / 255, weapon_color[1] / 255, weapon_color[2] / 255, 1.0) node.add(laser_charge, z=0) laser_drift = random.uniform(-15.0, 15.0), random.uniform( -15.0, 15.0) las_action = Delay(0.5) + ToggleVisibility() \ + CallFunc(create_laser_impact, battle.board, target_pos, laser_drift, las_life) \ + gl.LineDriftBy(laser_drift, las_life) \ + CallFunc(laser_charge.stop_system) + CallFunc(node.kill) las_outer.do(las_action) las_middle.do(las_action) las_inner.do(las_action) las_sound = Resources.las_sound weapon_channel.play(las_sound) las_duration_ms = int(las_action.duration * 1000) weapon_channel.fadeout(las_duration_ms) travel_time = 0.5 if min_travel_time == 0 or min_travel_time > travel_time: min_travel_time = travel_time if travel_time > max_travel_time: max_travel_time = travel_time elif weapon.isBallistic(): # fire test ballistic projectile num_ballistic = weapon.get_projectiles() if weapon.isGauss(): ballistic_img = Resources.gauss_img elif weapon.isLBX(): # LBX fires only one projectile, but will appear to have multiple random impacts num_ballistic = 1 ballistic_img = Resources.buckshot_img else: ballistic_img = Resources.ballistic_img # machine gun sound only plays once instead of per projectile cannon_sound = None if weapon.isMG(): cannon_sound = Resources.machinegun_sound elif weapon.isGauss(): cannon_sound = Resources.gauss_sound for i in range(num_ballistic): ballistic = Sprite(ballistic_img) ballistic.visible = False ballistic.position = weapon_x, weapon_y ballistic.scale = weapon.get_scale() ballistic.anchor = 0, 0 dx = real_x - weapon_x dy = real_y - weapon_y rads = atan2(-dy, dx) rads %= 2 * pi angle = degrees(rads) ballistic.rotation = angle target_x = real_x + random_offset() target_y = real_y + random_offset() target_pos = target_x, target_y # figure out the duration based on speed and distance ballistic_speed = weapon.get_speed() # pixels per second distance = Point2(weapon_x, weapon_y).distance( Point2(target_x, target_y)) ballistic_t = distance / ballistic_speed # setup the firing sound if cannon_sound is None: cannon_sound = Resources.cannon_sound impact_func = create_ballistic_impact if weapon.isLBX(): impact_func = create_lbx_impact action = Delay(i * 0.1) + ToggleVisibility() \ + CallFunc(weapon_channel.play, cannon_sound) \ + MoveTo((target_x, target_y), ballistic_t) \ + CallFunc(impact_func, weapon, battle.board, target_pos) \ + CallFunc(ballistic.kill) if weapon.isGauss(): # give gauss sound a bit more time to stop action += Delay(cannon_sound.get_length()) if i == num_ballistic - 1: # stop the sound channel after the last projectile only action += CallFunc(weapon_channel.stop) ballistic.do(action) battle.board.add(ballistic, z=1000 + i) travel_time = (i * 0.1) + ballistic_t if min_travel_time == 0 or min_travel_time > travel_time: min_travel_time = travel_time if travel_time > max_travel_time: max_travel_time = travel_time elif weapon.isMissile(): # get another sound channel to use just for the explosions explosion_channel = pygame.mixer.find_channel() if explosion_channel is None: explosion_channel = pygame.mixer.Channel(1) # fire test missile projectile missile_img = Resources.missile_img num_missile = weapon_data.get('count', 1) num_per_row = 1 if weapon.isLRM(): num_per_row = 5 elif weapon.isSRM(): num_per_row = 2 for i in range(num_missile): tube_x = i % num_per_row tube_y = i // num_per_row missile = Sprite(missile_img) missile.visible = False missile.position = weapon_x + tube_x, weapon_y + tube_y missile.scale = weapon.get_scale() missile.anchor = 0, 0 dx = real_x - weapon_x dy = real_y - weapon_y rads = atan2(-dy, dx) rads %= 2 * pi angle = degrees(rads) missile.rotation = angle target_x = real_x + random_offset() target_y = real_y + random_offset() target_pos = target_x, target_y # figure out the duration based on speed and distance missile_speed = weapon.get_speed() # pixels per second distance = Point2(weapon_x, weapon_y).distance( Point2(target_x, target_y)) missile_t = distance / missile_speed rand_missile_sound = random.randint(0, 7) missile_sound = Resources.missile_sounds[ rand_missile_sound] explosion_sound = Resources.explosion_sound action = Delay(i * 0.05) + ToggleVisibility() \ + CallFunc(weapon_channel.play, missile_sound) \ + MoveTo((target_x, target_y), missile_t) \ + CallFunc(create_missile_impact, battle.board, target_pos) \ + CallFunc(missile.kill) \ + CallFunc(explosion_channel.play, explosion_sound) \ + Delay(0.5) if i == num_missile - 1: # stop the sound channels after the last missile only action += CallFunc(weapon_channel.stop) + CallFunc( explosion_channel.stop) missile.do(action) battle.board.add(missile, z=1000 + i) travel_time = (i * 0.05) + missile_t if min_travel_time == 0 or min_travel_time > travel_time: min_travel_time = travel_time if travel_time > max_travel_time: max_travel_time = travel_time # scroll focus over to the target area halfway through the travel time target_area = Board.board_to_layer(target_unit.col, target_unit.row) # show damage floater after the travel time of the first projectile to hit floater = floaters.TextFloater("%i" % attack_damage) floater.visible = False floater.position = real_x, real_y + target_sprite.get_height() // 3 battle.board.add(floater, z=2000) action = Delay(min_travel_time / 2) + CallFunc(battle.scroller.set_focus, *target_area) \ + Delay(min_travel_time / 2) + ToggleVisibility() \ + Delay(0.25) + MoveBy((0, Board.TILE_SIZE), 1.0) \ + FadeOut(1.0) + CallFunc(floater.kill) floater.do(action) if action.duration > max_travel_time: max_travel_time = action.duration stats_action = Delay(min_travel_time) + CallFunc(target_sprite.updateStatsIndicators) \ + CallFunc(Interface.UI.updateTargetUnitStats, target_unit) target_sprite.do(stats_action) if attack_remainder > 0: print("Overkill by %i!" % attack_remainder) if target_unit.structure > 0: print("Remaining %i/%i" % (target_unit.armor, target_unit.structure)) else: print("Target destroyed!") # show destroyed floater after the travel time of the first projectile to hit destroyed = floaters.TextFloater("DESTROYED") destroyed.visible = False destroyed.position = real_x, real_y + target_sprite.get_height() // 3 battle.board.add(destroyed, z=5000) # get another sound channel to use just for the explosions explosion_channel = pygame.mixer.find_channel() if explosion_channel is None: explosion_channel = pygame.mixer.Channel(1) explosion_sound = Resources.explosion_multiple_sound action = Delay(max_travel_time) + ToggleVisibility() \ + CallFunc(explosion_channel.play, explosion_sound) \ + (MoveBy((0, Board.TILE_SIZE), 1.0) | CallFunc(create_destruction_explosions, battle.board, target_unit)) \ + Delay(0.5) + CallFunc(target_sprite.destroy) + FadeOut(2.0) + CallFunc(destroyed.kill) destroyed.do(action) # give a bit of extra time to explode max_travel_time = action.duration return max_travel_time