Source

Fat x Fast / FatxFast / physics / axismoving.py

# This file is part of FatxFast.                                                
#                                                                               
#    FatxFast 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, either version 3 of the License, or          
#    (at your option) any later version.                                        
#                                                                               
#    FatxFast 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.                               
#                                                                               
#    You should have received a copy of the GNU General Public License          
#    along with FatxFast.  If not, see <http://www.gnu.org/licenses/>.          
                                                                                
# Versioning based on:                                                          
# http://en.wikipedia.org/wiki/Versioning#Designating_development_stage         
__author__ = "dryatu (c) 2013"                                                  
__version__ = "1.2.5"

class MoveOnAxis(object):
    
    _component = None

    def __init__(self, physics):
        self._physics = physics
        self._xtile = None
        self._ytile = None
        self._extile = None
        self._eytile = None
    
    def __call__(self):
        self._fetch_current_tiles()
        if self._physics.collides:
            if getattr(self._physics.speedvector, self._component) < 0:
                self._get_negative_speed_collision_effects()
            elif getattr(self._physics.speedvector, self._component) > 0:
                self._get_positive_speed_collision_effects()
            self._physics.set_bounding_box_rect(self._component, 
                getattr(self._physics.speedvector, self._component))
            self._physics.trigger_events()
        self._move()
    
    def _deal_with_collision(self, fstep, sstep, collision_vertice_of_intrest,
        entity_vertice_of_intrest):
        col = self._physics.get_first_obstacle(
            self._xtile, self._extile, self._ytile, self._eytile, 
            fstep=fstep, sstep=sstep)
        if col:
            speed_fix_value = getattr(col.rect, collision_vertice_of_intrest)-\
                getattr(self._physics.entity.rect, entity_vertice_of_intrest)
            setattr(
                self._physics.speedvector, self._component, speed_fix_value)
                

    def _fetch_current_tiles(self):
        # Defines border area tile positions
        self._xtile = self._physics.worldmap.get_tile_xpos(
            self._physics.entity.rect.x)
        self._ytile = self._physics.worldmap.get_tile_ypos(
            self._physics.entity.rect.y)

    def _get_negative_speed_collision_effects(self):
        pass

    def _get_positive_speed_collision_effects(self):
        pass

    def _move(self):
        pass 


class MoveOnXAxis(MoveOnAxis): 
    """Move physics by x speed and check for collisions on x axis. 
    
    There's a collision => speedvector has to be resized to the colliding
    edge of the tile. Create a collision rect => trigger events. If there's
    a place changing trigger => Use a linear interpretation
    of the path triggers i.e. speedvector.x > 0 => trigger events from
    current_pos_x -> place_change_trigger"""
    _component = 'x'
    
    def _fetch_current_tiles(self):
        super(MoveOnXAxis, self)._fetch_current_tiles()
        self._eytile = self._physics.worldmap.get_tile_ypos(
            self._physics.entity.rect.bottom-1)

    def _get_negative_speed_collision_effects(self):
        self._extile = self._physics.worldmap.get_tile_xpos(
            self._physics.entity.rect.x+self._physics.speedvector.x)
        self._deal_with_collision(1, -1, 'right','x')

    def _get_positive_speed_collision_effects(self):
        self._extile = self._physics.worldmap.get_tile_xpos(
            self._physics.entity.rect.right-1+self._physics.speedvector.x)
        self._deal_with_collision(1, 1, 'x', 'right')

    def _move(self):
        self._physics.entity.move(self._physics.speedvector.x, 0)

class MoveOnYAxis(MoveOnAxis):

    _component = 'y'
    
    def _fetch_current_tiles(self):
        # Defines border area tile positions
        super(MoveOnYAxis, self)._fetch_current_tiles()
        self._extile = self._physics.worldmap.get_tile_xpos(
            self._physics.entity.rect.right-1)

    def _get_negative_speed_collision_effects(self):
        self._eytile = self._physics.worldmap.get_tile_ypos(
            self._physics.entity.rect.y+self._physics.speedvector.y)
        self._deal_with_collision(-1, 1, 'bottom', 'y')

    def _get_positive_speed_collision_effects(self):
        self._eytile = self._physics.worldmap.get_tile_ypos(
            self._physics.entity.rect.bottom-1+self._physics.speedvector.y)
        self._deal_with_collision(1, 1, 'y', 'bottom')
    
    def _move(self):
        self._physics.entity.move(0, self._physics.speedvector.y)