84
|
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 math import cos, sin, atan2, pi
|
|
16
|
|
17 from pytouhou.vm.anmrunner import ANMRunner
|
|
18 from pytouhou.game.sprite import Sprite
|
|
19
|
|
20
|
|
21 class Bullet(object):
|
|
22 __slots__ = ('x', 'y', 'angle', 'speed',
|
|
23 'flags', 'attributes', 'anim_idx', 'sprite_idx_offset', 'player',
|
|
24 '_game_state', '_sprite', '_anmrunner',
|
|
25 '_removed', '_launched')
|
|
26
|
|
27 def __init__(self, pos, anim_idx, sprite_idx_offset,
|
|
28 angle, speed, attributes, flags, player, game_state):
|
|
29 self._game_state = game_state
|
|
30 self._sprite = None
|
|
31 self._anmrunner = None
|
|
32 self._removed = False
|
|
33 self._launched = False
|
|
34
|
|
35 self.player = player
|
|
36
|
|
37 self.anim_idx = anim_idx
|
|
38 self.sprite_idx_offset = sprite_idx_offset
|
|
39
|
|
40 #TODO
|
|
41 #if flags & (2|4|8):
|
|
42 # index = {2: 11, 4: 12, 8: 13}[flags & (2|4|8)]
|
|
43 # self._sprite = Sprite()
|
|
44 # self._anmrunner = ANMRunner(self._game_state.resources.etama_anm_wrappers[0],
|
|
45 # index, self._sprite, sprite_idx_offset)
|
|
46
|
|
47 self.flags = flags
|
|
48 self.attributes = list(attributes)
|
|
49
|
|
50 self.x, self.y = pos
|
|
51 self.angle = angle
|
|
52 self.speed = speed
|
|
53
|
|
54
|
|
55 def is_visible(self, screen_width, screen_height):
|
|
56 if self._sprite:
|
|
57 tx, ty, tw, th = self._sprite.texcoords
|
|
58 if self._sprite.corner_relative_placement:
|
|
59 raise Exception #TODO
|
|
60 else:
|
|
61 tx, ty, tw, th = 0., 0., 0., 0.
|
|
62
|
|
63 max_x = tw / 2.
|
|
64 max_y = th / 2.
|
|
65 min_x = -max_x
|
|
66 min_y = -max_y
|
|
67
|
|
68 if any((min_x > screen_width - self.x,
|
|
69 max_x < -self.x,
|
|
70 min_y > screen_height - self.y,
|
|
71 max_y < -self.y)):
|
|
72 return False
|
|
73 return True
|
|
74
|
|
75
|
85
|
76 def get_objects_by_texture(self, objects_by_texture):
|
|
77 sprite = self._sprite
|
|
78 key = sprite.anm.first_name, sprite.anm.secondary_name
|
|
79 key = (key, sprite.blendfunc)
|
84
|
80 if not key in objects_by_texture:
|
|
81 objects_by_texture[key] = (0, [], [], [])
|
85
|
82 vertices = ((x + self.x, y + self.y, z) for x, y, z in sprite._vertices)
|
84
|
83 objects_by_texture[key][1].extend(vertices)
|
85
|
84 objects_by_texture[key][2].extend(sprite._uvs)
|
|
85 objects_by_texture[key][3].extend(sprite._colors)
|
84
|
86
|
|
87
|
|
88 def update(self):
|
|
89 if not self._sprite or self._sprite._removed:
|
|
90 self._launched = True
|
|
91 self._sprite = Sprite()
|
|
92 self._anmrunner = ANMRunner(self._game_state.resources.etama_anm_wrappers[0], #TODO
|
|
93 self.anim_idx, self._sprite, self.sprite_idx_offset)
|
|
94 #TODO: self._anmrunner.sprite_idx_offset = self.sprite_idx_offset
|
|
95
|
|
96 if self._anmrunner and not self._anmrunner.run_frame():
|
|
97 self._anmrunner = None
|
|
98
|
85
|
99 self._sprite.update()
|
|
100 if self._sprite._changed: #TODO
|
|
101 angle = pi/2.-self.angle if self._sprite.automatic_orientation else 0.
|
|
102 self._sprite.update_vertices_uvs_colors(angle_base=angle)
|
84
|
103
|
|
104 #TODO: flags
|
|
105 x, y = self.x, self.y
|
|
106
|
|
107 dx, dy = cos(self.angle) * self.speed, sin(self.angle) * self.speed
|
|
108 self.x, self.y = x + dx, y + dy
|
|
109
|