comparison 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
comparison
equal deleted inserted replaced
219:091301805cce 220:0595315d3880
1 # -*- encoding: utf-8 -*-
2 ##
3 ## Copyright (C) 2011 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
4 ##
5 ## This program is free software; you can redistribute it and/or modify
6 ## it under the terms of the GNU General Public License as published
7 ## by the Free Software Foundation; version 3 only.
8 ##
9 ## This program is distributed in the hope that it will be useful,
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ## GNU General Public License for more details.
13 ##
14
15 from pytouhou.utils.interpolator import Interpolator
16
17 from pytouhou.game.game import Game
18 from pytouhou.game.bullettype import BulletType
19 from pytouhou.game.itemtype import ItemType
20 from pytouhou.game.player import Player
21 from pytouhou.game.bullet import Bullet
22 from pytouhou.game.orb import Orb
23
24 from math import pi
25
26
27 class PCBGame(Game):
28 def __init__(self, resource_loader, player_states, stage, rank, difficulty, **kwargs):
29 etama3 = resource_loader.get_anm_wrapper(('etama3.anm',))
30 etama4 = resource_loader.get_anm_wrapper(('etama4.anm',))
31 bullet_types = [BulletType(etama3, 0, 11, 14, 15, 16, hitbox_size=4),
32 BulletType(etama3, 1, 12, 17, 18, 19, hitbox_size=6),
33 BulletType(etama3, 2, 12, 17, 18, 19, hitbox_size=4),
34 BulletType(etama3, 3, 12, 17, 18, 19, hitbox_size=6),
35 BulletType(etama3, 4, 12, 17, 18, 19, hitbox_size=5),
36 BulletType(etama3, 5, 12, 17, 18, 19, hitbox_size=4),
37 BulletType(etama3, 6, 13, 20, 20, 20, hitbox_size=16),
38 BulletType(etama3, 7, 13, 20, 20, 20, hitbox_size=11),
39 BulletType(etama3, 8, 13, 20, 20, 20, hitbox_size=9),
40 BulletType(etama4, 0, 1, 2, 2, 2, hitbox_size=32)]
41 #TODO: hitbox
42 item_types = [ItemType(etama3, 0, 7), #Power
43 ItemType(etama3, 1, 8), #Point
44 ItemType(etama3, 2, 9), #Big power
45 ItemType(etama3, 3, 10), #Bomb
46 ItemType(etama3, 4, 11), #Full power
47 ItemType(etama3, 5, 12), #1up
48 ItemType(etama3, 6, 13)] #Star
49
50 players = []
51 for player in player_states:
52 players.append(PCBPlayer(player, self, resource_loader))
53
54 Game.__init__(self, resource_loader, players, stage, rank, difficulty,
55 bullet_types, item_types, nb_bullets_max=640, **kwargs)
56
57
58
59 class PCBPlayer(Player):
60 def __init__(self, state, game, resource_loader, speed=4., hitbox_size=2.5, graze_hitbox_size=42.):
61 number = '%d%s' % (state.character // 2, 'b' if state.character % 2 else 'a')
62 self.sht = resource_loader.get_sht('ply0%s.sht' % number)
63 self.focused_sht = resource_loader.get_sht('ply0%ss.sht' % number)
64 anm_wrapper = resource_loader.get_anm_wrapper(('player0%d.anm' % (state.character // 2),))
65
66 Player.__init__(self, state, game, anm_wrapper,
67 speeds=(self.sht.horizontal_vertical_speed,
68 self.sht.diagonal_speed,
69 self.sht.horizontal_vertical_focused_speed,
70 self.sht.diagonal_focused_speed))
71
72 self.orbs = [Orb(self.anm_wrapper, 128, self.state, None),
73 Orb(self.anm_wrapper, 129, self.state, None)]
74
75 self.orbs[0].offset_x = -24
76 self.orbs[1].offset_x = 24
77
78 self.orb_dx_interpolator = None
79 self.orb_dy_interpolator = None
80
81
82 def start_focusing(self):
83 self.orb_dx_interpolator = Interpolator((24,), self._game.frame,
84 (8,), self._game.frame + 8,
85 lambda x: x ** 2)
86 self.orb_dy_interpolator = Interpolator((0,), self._game.frame,
87 (-32,), self._game.frame + 8)
88 self.state.focused = True
89
90
91 def stop_focusing(self):
92 self.orb_dx_interpolator = Interpolator((8,), self._game.frame,
93 (24,), self._game.frame + 8,
94 lambda x: x ** 2)
95 self.orb_dy_interpolator = Interpolator((-32,), self._game.frame,
96 (0,), self._game.frame + 8)
97 self.state.focused = False
98
99
100 def objects(self):
101 return self.orbs
102
103
104 def update(self, keystate):
105 Player.update(self, keystate)
106
107 if self.death_time == 0 or self._game.frame - self.death_time > 60:
108 if self.orb_dx_interpolator:
109 self.orb_dx_interpolator.update(self._game.frame)
110 dx, = self.orb_dx_interpolator.values
111 self.orbs[0].offset_x = -dx
112 self.orbs[1].offset_x = dx
113 if self.orb_dy_interpolator:
114 self.orb_dy_interpolator.update(self._game.frame)
115 dy, = self.orb_dy_interpolator.values
116 self.orbs[0].offset_y = dy
117 self.orbs[1].offset_y = dy
118
119 for orb in self.orbs:
120 orb.update()
121
122
123 def fire(self):
124 sht = self.focused_sht if self.state.focused else self.sht
125 power = min(power for power in sht.shots if self.state.power < power)
126
127 bullets = self._game.players_bullets
128 nb_bullets_max = self._game.nb_bullets_max
129
130 for shot in sht.shots[power]:
131 if self.fire_time % shot.interval == 0:
132 if nb_bullets_max is not None and len(bullets) == nb_bullets_max:
133 break
134
135 origin = self.orbs[shot.orb - 1] if shot.orb else self
136 x = origin.x + shot.pos[0]
137 y = origin.y + shot.pos[1]
138
139 bullets.append(Bullet((x, y), self.bullet_type, 0,
140 shot.angle, shot.speed,
141 (0, 0, 0, 0, 0., 0., 0., 0.),
142 0, self, self._game, player_bullet=True, damage=shot.damage, hitbox=shot.hitbox))