# HG changeset patch # User Emmanuel Gil Peyrot # Date 1329830918 -3600 # Node ID 94c636f8f863732b94320ef11e64ea90d2d64cd8 # Parent ab618c2bbce8c158abc437c3513d2d234531ad05 Add player lasers for MarisaB. diff --git a/pytouhou/game/enemy.py b/pytouhou/game/enemy.py --- a/pytouhou/game/enemy.py +++ b/pytouhou/game/enemy.py @@ -286,6 +286,21 @@ class Enemy(object): damages += bullet.damage self.drop_particles(1, 1) + # Check for enemy-laser collisions + for laser in self._game.players_lasers: + if not laser: + continue + + half_size = laser.hitbox_half_size + lx, ly = laser.x, laser.y * 2. + lx1, lx2 = lx - half_size[0], lx + half_size[0] + + if not (lx2 < ex1 or lx1 > ex2 + or ly < ey1): + if self.damageable: + damages += laser.damage + self.drop_particles(1, 1) + # Check for enemy-player collisions ex1, ex2 = ex - ehalf_size_x * 2. / 3., ex + ehalf_size_x * 2. / 3. ey1, ey2 = ey - ehalf_size_y * 2. / 3., ey + ehalf_size_y * 2. / 3. diff --git a/pytouhou/game/game.py b/pytouhou/game/game.py --- a/pytouhou/game/game.py +++ b/pytouhou/game/game.py @@ -46,6 +46,7 @@ class Game(object): self.lasers = [] self.cancelled_bullets = [] self.players_bullets = [] + self.players_lasers = [None, None] self.items = [] self.stage = stage @@ -83,6 +84,10 @@ class Game(object): return [] + def lasers_sprites(self): + return [laser for laser in self.players_lasers if laser] + + def modify_difficulty(self, diff): self.difficulty_counter += diff while self.difficulty_counter < 0: @@ -236,6 +241,10 @@ class Game(object): for bullet in self.bullets: bullet.update() + for laser in self.players_lasers: + if laser: + laser.update() + for item in self.items: item.update() @@ -315,6 +324,9 @@ class Game(object): if not bullet._removed] self.players_bullets = [bullet for bullet in self.players_bullets if not bullet._removed] + for i, laser in enumerate(self.players_lasers): + if laser and laser._removed: + self.players_lasers[i] = None self.cancelled_bullets = [bullet for bullet in self.cancelled_bullets if not bullet._removed] self.effects = [effect for effect in self.effects if not effect._removed] diff --git a/pytouhou/game/laser.py b/pytouhou/game/laser.py --- a/pytouhou/game/laser.py +++ b/pytouhou/game/laser.py @@ -192,3 +192,66 @@ class Laser(object): self.frame += 1 + +class PlayerLaser(object): + def __init__(self, laser_type, sprite_idx_offset, hitbox, damage, + angle, offset, duration, origin): + self._sprite = None + self._anmrunner = None + self._removed = False + self._laser_type = laser_type + self.origin = origin + + self.hitbox_half_size = hitbox[0] / 2., hitbox[1] / 2. + + self.frame = 0 + self.duration = duration + + self.sprite_idx_offset = sprite_idx_offset + self.angle = angle + self.offset = offset + self.damage = damage + + self.set_anim() + + + @property + def x(self): + return self.origin.x + self.offset * cos(self.angle) + + + @property + def y(self): + return self.origin.y / 2. + self.offset * sin(self.angle) + + + def set_anim(self, sprite_idx_offset=None): + if sprite_idx_offset is not None: + self.sprite_idx_offset = sprite_idx_offset + + lt = self._laser_type + self._sprite = Sprite() + self._anmrunner = ANMRunner(lt.anm_wrapper, lt.anim_index, + self._sprite, self.sprite_idx_offset) + #self._sprite.blendfunc = 1 #XXX + self._anmrunner.run_frame() + + + def cancel(self): + self._anmrunner.interrupt(1) + + + def update(self): + if self._anmrunner is not None and not self._anmrunner.run_frame(): + self._anmrunner = None + self._removed = True + + length = self.origin.y + if self.frame == self.duration: + self.cancel() + + self._sprite.height_override = length or 0.01 #TODO + self._sprite._changed = True #TODO + + self.frame += 1 + diff --git a/pytouhou/game/player.py b/pytouhou/game/player.py --- a/pytouhou/game/player.py +++ b/pytouhou/game/player.py @@ -17,6 +17,8 @@ from pytouhou.game.sprite import Sprite from pytouhou.vm.anmrunner import ANMRunner from pytouhou.game.bullettype import BulletType from pytouhou.game.bullet import Bullet +from pytouhou.game.lasertype import LaserType +from pytouhou.game.laser import PlayerLaser from math import pi @@ -110,10 +112,22 @@ class Player(object): power = min(power for power in sht.shots if self.state.power < power) bullets = self._game.players_bullets + lasers = self._game.players_lasers nb_bullets_max = self._game.nb_bullets_max for shot in sht.shots[power]: - if shot.type == 3: # TODO: Lasers aren't implemented yet + origin = self.orbs[shot.orb - 1] if shot.orb else self.state + + if shot.type == 3: + if self.fire_time != 30: + continue + + number = shot.delay #TODO: number can do very surprising things, like removing any bullet creation from enemies with 3. For now, crash when not 0 or 1. + if lasers[number]: + continue + + laser_type = LaserType(self.anm_wrapper, shot.sprite % 256, 68) + lasers[number] = PlayerLaser(laser_type, 0, shot.hitbox, shot.damage, shot.angle, shot.speed, shot.interval, origin) continue if (self.fire_time + shot.delay) % shot.interval != 0: @@ -122,7 +136,6 @@ class Player(object): if nb_bullets_max is not None and len(bullets) == nb_bullets_max: break - origin = self.orbs[shot.orb - 1] if shot.orb else self x = origin.x + shot.pos[0] y = origin.y + shot.pos[1] @@ -130,7 +143,7 @@ class Player(object): bullet_type = BulletType(self.anm_wrapper, shot.sprite % 256, shot.sprite % 256 + 32, #TODO: find the real cancel anim 0, 0, 0, 0.) - #TODO: Type 1 (homing bullets) and type 3 (laser) + #TODO: Type 1 (homing bullets) if shot.type == 2: #TODO: triple-check acceleration! bullets.append(Bullet((x, y), bullet_type, 0, diff --git a/pytouhou/ui/gamerenderer.pyx b/pytouhou/ui/gamerenderer.pyx --- a/pytouhou/ui/gamerenderer.pyx +++ b/pytouhou/ui/gamerenderer.pyx @@ -84,6 +84,7 @@ cdef class GameRenderer(Renderer): self.render_elements(enemy for enemy in game.enemies if enemy._visible) self.render_elements(game.effects) self.render_elements(chain(game.players_bullets, + game.lasers_sprites(), game.players, game.msg_sprites(), *(player.objects() for player in game.players))) diff --git a/pytouhou/vm/anmrunner.py b/pytouhou/vm/anmrunner.py --- a/pytouhou/vm/anmrunner.py +++ b/pytouhou/vm/anmrunner.py @@ -137,7 +137,8 @@ class ANMRunner(object): @instruction(4) def set_color(self, b, g, r): - self._sprite.color = (r, g, b) + if not self._sprite.fade_interpolator: + self._sprite.color = (r, g, b) @instruction(5)