Mercurial > touhou
diff pytouhou/games/pcb.py @ 220:0595315d3880
Fix SHT handling; change a few things to be closer to ZUN’s mind; and first stub of PCB support.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sun, 18 Dec 2011 14:14:32 +0100 |
parents | |
children | 8843e26f80c3 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/pytouhou/games/pcb.py @@ -0,0 +1,142 @@ +# -*- encoding: utf-8 -*- +## +## Copyright (C) 2011 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published +## by the Free Software Foundation; version 3 only. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +from pytouhou.utils.interpolator import Interpolator + +from pytouhou.game.game import Game +from pytouhou.game.bullettype import BulletType +from pytouhou.game.itemtype import ItemType +from pytouhou.game.player import Player +from pytouhou.game.bullet import Bullet +from pytouhou.game.orb import Orb + +from math import pi + + +class PCBGame(Game): + def __init__(self, resource_loader, player_states, stage, rank, difficulty, **kwargs): + etama3 = resource_loader.get_anm_wrapper(('etama3.anm',)) + etama4 = resource_loader.get_anm_wrapper(('etama4.anm',)) + bullet_types = [BulletType(etama3, 0, 11, 14, 15, 16, hitbox_size=4), + BulletType(etama3, 1, 12, 17, 18, 19, hitbox_size=6), + BulletType(etama3, 2, 12, 17, 18, 19, hitbox_size=4), + BulletType(etama3, 3, 12, 17, 18, 19, hitbox_size=6), + BulletType(etama3, 4, 12, 17, 18, 19, hitbox_size=5), + BulletType(etama3, 5, 12, 17, 18, 19, hitbox_size=4), + BulletType(etama3, 6, 13, 20, 20, 20, hitbox_size=16), + BulletType(etama3, 7, 13, 20, 20, 20, hitbox_size=11), + BulletType(etama3, 8, 13, 20, 20, 20, hitbox_size=9), + BulletType(etama4, 0, 1, 2, 2, 2, hitbox_size=32)] + #TODO: hitbox + item_types = [ItemType(etama3, 0, 7), #Power + ItemType(etama3, 1, 8), #Point + ItemType(etama3, 2, 9), #Big power + ItemType(etama3, 3, 10), #Bomb + ItemType(etama3, 4, 11), #Full power + ItemType(etama3, 5, 12), #1up + ItemType(etama3, 6, 13)] #Star + + players = [] + for player in player_states: + players.append(PCBPlayer(player, self, resource_loader)) + + Game.__init__(self, resource_loader, players, stage, rank, difficulty, + bullet_types, item_types, nb_bullets_max=640, **kwargs) + + + +class PCBPlayer(Player): + def __init__(self, state, game, resource_loader, speed=4., hitbox_size=2.5, graze_hitbox_size=42.): + number = '%d%s' % (state.character // 2, 'b' if state.character % 2 else 'a') + self.sht = resource_loader.get_sht('ply0%s.sht' % number) + self.focused_sht = resource_loader.get_sht('ply0%ss.sht' % number) + anm_wrapper = resource_loader.get_anm_wrapper(('player0%d.anm' % (state.character // 2),)) + + Player.__init__(self, state, game, anm_wrapper, + speeds=(self.sht.horizontal_vertical_speed, + self.sht.diagonal_speed, + self.sht.horizontal_vertical_focused_speed, + self.sht.diagonal_focused_speed)) + + self.orbs = [Orb(self.anm_wrapper, 128, self.state, None), + Orb(self.anm_wrapper, 129, self.state, None)] + + self.orbs[0].offset_x = -24 + self.orbs[1].offset_x = 24 + + self.orb_dx_interpolator = None + self.orb_dy_interpolator = None + + + def start_focusing(self): + self.orb_dx_interpolator = Interpolator((24,), self._game.frame, + (8,), self._game.frame + 8, + lambda x: x ** 2) + self.orb_dy_interpolator = Interpolator((0,), self._game.frame, + (-32,), self._game.frame + 8) + self.state.focused = True + + + def stop_focusing(self): + self.orb_dx_interpolator = Interpolator((8,), self._game.frame, + (24,), self._game.frame + 8, + lambda x: x ** 2) + self.orb_dy_interpolator = Interpolator((-32,), self._game.frame, + (0,), self._game.frame + 8) + self.state.focused = False + + + def objects(self): + return self.orbs + + + def update(self, keystate): + Player.update(self, keystate) + + if self.death_time == 0 or self._game.frame - self.death_time > 60: + if self.orb_dx_interpolator: + self.orb_dx_interpolator.update(self._game.frame) + dx, = self.orb_dx_interpolator.values + self.orbs[0].offset_x = -dx + self.orbs[1].offset_x = dx + if self.orb_dy_interpolator: + self.orb_dy_interpolator.update(self._game.frame) + dy, = self.orb_dy_interpolator.values + self.orbs[0].offset_y = dy + self.orbs[1].offset_y = dy + + for orb in self.orbs: + orb.update() + + + def fire(self): + sht = self.focused_sht if self.state.focused else self.sht + power = min(power for power in sht.shots if self.state.power < power) + + bullets = self._game.players_bullets + nb_bullets_max = self._game.nb_bullets_max + + for shot in sht.shots[power]: + if self.fire_time % shot.interval == 0: + 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] + + bullets.append(Bullet((x, y), self.bullet_type, 0, + shot.angle, shot.speed, + (0, 0, 0, 0, 0., 0., 0., 0.), + 0, self, self._game, player_bullet=True, damage=shot.damage, hitbox=shot.hitbox))