comparison pytouhou/game/item.pyx @ 446:3a33ed7f3b85

Make pytouhou.game.item an extension type.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sat, 17 Aug 2013 06:01:45 +0200
parents pytouhou/game/item.py@b0abb05811f7
children 78e1c3864e73
comparison
equal deleted inserted replaced
445:b0abb05811f7 446:3a33ed7f3b85
1 # -*- encoding: utf-8 -*-
2 ##
3 ## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com>
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 libc.math cimport cos, sin, atan2, M_PI as pi
16
17
18 cdef class Indicator(Element):
19 def __init__(self, Item item):
20 Element.__init__(self)
21
22 self._item = item
23 self.sprite = item._item_type.indicator_sprite.copy()
24
25 self.x = self._item.x
26 self.y = self.sprite.texcoords[2] / 2.
27
28
29 cpdef update(self):
30 #TODO: alpha
31 self.x = self._item.x
32
33
34
35 cdef class Item(Element):
36 def __init__(self, start_pos, long _type, item_type, game, double angle=pi/2, Player player=None, end_pos=None):
37 Element.__init__(self, start_pos)
38
39 self._game = game
40 self._type = _type
41 self._item_type = item_type
42 self.sprite = item_type.sprite
43
44 self.frame = 0
45 self.angle = angle
46 self.indicator = None
47
48 if player is not None:
49 self.autocollect(player)
50 else:
51 self.player = None
52
53 #TODO: find the formulae in the binary.
54 self.speed_interpolator = None
55 if end_pos:
56 self.pos_interpolator = Interpolator(start_pos, 0,
57 end_pos, 60)
58 else:
59 self.speed_interpolator = Interpolator((-2.,), 0,
60 (0.,), 60)
61
62 self.sprite.angle = angle
63
64
65 property objects:
66 def __get__(self):
67 if self.indicator is not None:
68 return [self.indicator]
69 return [self]
70
71
72 cpdef autocollect(self, Player player):
73 if self.player is None:
74 self.player = player
75 self.speed = player.sht.autocollection_speed
76
77
78 cpdef on_collect(self, Player player):
79 cdef long level, poc
80
81 player_state = player.state
82 old_power = player_state.power
83 score = 0
84 label = None
85 color = 'white'
86 player.play_sound('item00')
87
88 if self._type == 0 or self._type == 2: # power or big power
89 if old_power < 128:
90 player_state.power_bonus = 0
91 score = 10
92 player_state.power += (1 if self._type == 0 else 8)
93 if player_state.power > 128:
94 player_state.power = 128
95 for level in (8, 16, 32, 48, 64, 96):
96 if old_power < level and player_state.power >= level:
97 label = self._game.new_label((self.x, self.y), ':') # Actually a “PowerUp” character.
98 color = 'blue'
99 label.set_color(color)
100 labeled = True
101 else:
102 bonus = player_state.power_bonus + (1 if self._type == 0 else 8)
103 if bonus > 30:
104 bonus = 30
105 if bonus < 9:
106 score = (bonus + 1) * 10
107 elif bonus < 18:
108 score = (bonus - 8) * 100
109 elif bonus < 30:
110 score = (bonus - 17) * 1000
111 elif bonus == 30:
112 score = 51200
113 color = 'yellow'
114 player_state.power_bonus = bonus
115 self._game.modify_difficulty(+1)
116
117 elif self._type == 1: # point
118 player_state.points += 1
119 poc = player.sht.point_of_collection
120 if player_state.y < poc:
121 score = 100000
122 self._game.modify_difficulty(+30)
123 color = 'yellow'
124 else:
125 #score = #TODO: find the formula.
126 self._game.modify_difficulty(+3)
127
128 elif self._type == 3: # bomb
129 if player_state.bombs < 8:
130 player_state.bombs += 1
131 self._game.modify_difficulty(+5)
132
133 elif self._type == 4: # full power
134 score = 1000
135 player_state.power = 128
136
137 elif self._type == 5: # 1up
138 if player_state.lives < 8:
139 player_state.lives += 1
140 self._game.modify_difficulty(+200)
141 player.play_sound('extend')
142
143 elif self._type == 6: # star
144 score = 500
145
146 if old_power < 128 and player_state.power == 128:
147 #TODO: display “full power”.
148 self._game.change_bullets_into_star_items()
149
150 if score > 0:
151 player_state.score += score
152 if label is None:
153 label = self._game.new_label((self.x, self.y), str(score))
154 if color != 'white':
155 label.set_color(color)
156
157 self.removed = True
158
159
160 cpdef update(self):
161 cdef bint offscreen
162
163 if self.frame == 60:
164 self.speed_interpolator = Interpolator((0.,), 60,
165 (3.,), 180)
166
167 if self.player is not None:
168 player_state = self.player.state
169 self.angle = atan2(player_state.y - self.y, player_state.x - self.x)
170 self.x += cos(self.angle) * self.speed
171 self.y += sin(self.angle) * self.speed
172 elif self.speed_interpolator is None:
173 self.pos_interpolator.update(self.frame)
174 self.x, self.y = self.pos_interpolator.values
175 else:
176 self.speed_interpolator.update(self.frame)
177 self.speed, = self.speed_interpolator.values
178 dx, dy = cos(self.angle) * self.speed, sin(self.angle) * self.speed
179 self.x += dx
180 self.y += dy
181
182 offscreen = self.y < -(<double>self.sprite.texcoords[2] / 2.)
183 if offscreen:
184 if self.indicator is None:
185 self.indicator = Indicator(self)
186 self.indicator.update()
187 else:
188 self.indicator = None
189
190 self.frame += 1