Mercurial > touhou
view pytouhou/game/item.pyx @ 612:73f134f84c7f
Request a RGB888 context, since SDL2’s default of RGB332 sucks.
On X11/GLX, it will select the first config available, that is the best
one, while on EGL it will iterate over them to select the one closest
to what the application requested.
Of course, anything lower than RGB888 looks bad and we really don’t
want that.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Thu, 26 Mar 2015 20:20:37 +0100 |
parents | 3c2f96f1d715 |
children | a6af3ff86612 |
line wrap: on
line source
# -*- encoding: utf-8 -*- ## ## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com> ## ## 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 libc.math cimport cos, sin, atan2, M_PI as pi cdef class Indicator(Element): def __init__(self, Item item): Element.__init__(self) self._item = item self.sprite = item._item_type.indicator_sprite.copy() self.x = self._item.x self.y = self.sprite._texcoords[3] / 2. cdef void update(self) nogil: #TODO: alpha self.x = self._item.x cdef class Item(Element): def __init__(self, start_pos, long _type, ItemType item_type, Game game, double angle=pi/2, player=None, end_pos=None, target=None): Element.__init__(self, start_pos) self._game = game self._type = _type self._item_type = item_type self.sprite = item_type.sprite self.frame = 0 self.angle = angle self.indicator = None # The only player allowed to collect that item. If not None, # autocollection is disabled too. self.player = player # The player who has autocollected that item. # TODO: do we allow stealing in case another player is in the way? self.target = target #TODO: find the formulae in the binary. self.speed_interpolator = None if end_pos: self.pos_interpolator = Interpolator(start_pos, 0, end_pos, 60) else: self.speed_interpolator = Interpolator((-2.,), 0, (0.,), 60) self.sprite.angle = angle property objects: def __get__(self): if self.indicator is not None: return [self.indicator] return [self] cdef void autocollect(self, Player player) except *: if self.target is None and self.player is None: self.target = player self.speed = player.sht.autocollection_speed cdef void on_collect(self, Player player) except *: cdef long level, poc if not (self.player is None or self.player is player): return old_power = player.power score = 0 label = None color = 'white' player.play_sound('item00') if self._type == 0 or self._type == 2: # power or big power if old_power < 128: player.power_bonus = 0 score = 10 player.power += (1 if self._type == 0 else 8) if player.power > 128: player.power = 128 for level in (8, 16, 32, 48, 64, 96): if old_power < level and player.power >= level: label = self._game.new_label((self.x, self.y), b':') # Actually a “PowerUp” character. color = 'blue' label.set_color(color) labeled = True else: bonus = player.power_bonus + (1 if self._type == 0 else 8) if bonus > 30: bonus = 30 if bonus < 9: score = (bonus + 1) * 10 elif bonus < 18: score = (bonus - 8) * 100 elif bonus < 30: score = (bonus - 17) * 1000 elif bonus == 30: score = 51200 color = 'yellow' player.power_bonus = bonus self._game.modify_difficulty(+1) elif self._type == 1: # point player.points += 1 poc = player.sht.point_of_collection if player.y < poc: score = 100000 self._game.modify_difficulty(+30) color = 'yellow' else: score = (728 - int(self.y)) * 100 #TODO: check the formula some more. self._game.modify_difficulty(+3) elif self._type == 3: # bomb if player.bombs < 8: player.bombs += 1 self._game.modify_difficulty(+5) elif self._type == 4: # full power score = 1000 player.power = 128 elif self._type == 5: # 1up if player.lives < 8: player.lives += 1 self._game.modify_difficulty(+200) player.play_sound('extend') elif self._type == 6: # star score = 500 if old_power < 128 and player.power == 128: #TODO: display “full power”. self._game.change_bullets_into_star_items() if score > 0: player.score += score if label is None: label = self._game.new_label((self.x, self.y), str(score).encode()) if color != 'white': label.set_color(color) self.removed = True cpdef update(self): cdef bint offscreen if self.frame == 60: self.speed_interpolator = Interpolator((0.,), 60, (3.,), 180) if self.target is not None: self.angle = atan2(self.target.y - self.y, self.target.x - self.x) self.x += cos(self.angle) * self.speed self.y += sin(self.angle) * self.speed elif self.speed_interpolator is None: self.pos_interpolator.update(self.frame) self.x, self.y = self.pos_interpolator.values else: self.speed_interpolator.update(self.frame) self.speed, = self.speed_interpolator.values dx, dy = cos(self.angle) * self.speed, sin(self.angle) * self.speed self.x += dx self.y += dy offscreen = self.y < -self.sprite._texcoords[3] / 2. if offscreen: if self.indicator is None: self.indicator = Indicator(self) self.indicator.update() else: self.indicator = None self.frame += 1