288 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			288 lines
		
	
	
		
			9.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# This file is part of ROBOTGAME
 | 
						|
#
 | 
						|
# ROBOTGAME 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.
 | 
						|
#
 | 
						|
# ROBOTGAME 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
 | 
						|
# ROBOTGAME.  If not, see <http://www.gnu.org/licenses/>.
 | 
						|
#
 | 
						|
# ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
 | 
						|
#
 | 
						|
#                          block.py
 | 
						|
#                     --------------------
 | 
						|
#       date created : Tue Aug 7 2012
 | 
						|
#          copyright : (C) 2012 Sakse Dalum
 | 
						|
#      maintained by : Sakse Dalum <don_s@hongabar.org>
 | 
						|
 | 
						|
"""
 | 
						|
A generic block. And other block derivatives.
 | 
						|
"""
 | 
						|
 | 
						|
import pygame
 | 
						|
 | 
						|
import worldobject
 | 
						|
import copy
 | 
						|
 | 
						|
class Block(worldobject.WorldObject):
 | 
						|
    def __init__(self, level, x, y, img_str='block1',
 | 
						|
                 movable=False, visible=True,
 | 
						|
                 width=1, height=1):
 | 
						|
        self.__dict__.update(locals())
 | 
						|
        worldobject.WorldObject.__init__(self, level, x, y,
 | 
						|
                                         movable=movable, visible=visible)
 | 
						|
 | 
						|
        for i in range(width):
 | 
						|
            for j in range(height):
 | 
						|
                if width != 1 or height != 1:
 | 
						|
                    self.level.objects.append(
 | 
						|
                        InvisBlock(self.level,
 | 
						|
                                   self.x + 64 * i,
 | 
						|
                                   self.y - 48 * j))
 | 
						|
 | 
						|
        self.load()
 | 
						|
 | 
						|
        # self.orig_alphas = {
 | 
						|
        #     'normal':
 | 
						|
        #         pygame.surfarray.array_alpha(self.level.imgs[self.img_str]),
 | 
						|
        #     'lifted':
 | 
						|
        #         pygame.surfarray.array_alpha(
 | 
						|
        #         self.level.imgs[self.img_str + '_lifted'])}
 | 
						|
 | 
						|
        # self.orig_alpha = self.orig_alphas['normal']
 | 
						|
 | 
						|
    def load(self):
 | 
						|
        if not isinstance(self.img_str, str):
 | 
						|
            self.img_str = self.level.reverse_imgs[self.img_str]
 | 
						|
 | 
						|
        self.img = self.level.imgs[self.img_str]
 | 
						|
 | 
						|
    # def update_alpha(self):
 | 
						|
    #     be_opaque = not (self.y + self.z >= self.level.player.move_y
 | 
						|
    #                      + self.level.player.move_z)
 | 
						|
    #     if be_opaque and not self.is_currently_opaque:
 | 
						|
    #         self.is_currently_opaque = True
 | 
						|
    #         self.set_alpha(1)
 | 
						|
    #     elif not be_opaque and self.is_currently_opaque:
 | 
						|
    #         self.is_currently_opaque = False
 | 
						|
    #         self.set_alpha(0.5)
 | 
						|
 | 
						|
    def use(self, obj):
 | 
						|
        if self.movable:
 | 
						|
            if obj == self.holder:
 | 
						|
                obj.holding = None
 | 
						|
                self.holder = None
 | 
						|
                if hasattr(self, 'img_str'):
 | 
						|
                    self.img = self.level.imgs[self.img_str]
 | 
						|
                    # self.orig_alpha = self.orig_alphas['normal']
 | 
						|
            else:
 | 
						|
                obj.holding = self
 | 
						|
                self.holder = obj
 | 
						|
                if hasattr(self, 'img_str'):
 | 
						|
                    self.img = self.level.imgs[self.img_str + '_lifted']
 | 
						|
                    # self.orig_alpha = self.orig_alphas['lifted']
 | 
						|
 | 
						|
    def draw(self, window):
 | 
						|
        if self.visible:
 | 
						|
            window.blit(self.img, (self.x - 32 - self.level.camera_x,
 | 
						|
                                   self.y - self.img.get_size()[1] + 24
 | 
						|
                                   - self.level.camera_y))
 | 
						|
 | 
						|
class InvisBlock(Block):
 | 
						|
    def __init__(self, level, x, y):
 | 
						|
        self.__dict__.update(locals())
 | 
						|
        worldobject.WorldObject.__init__(self, level, x, y, visible=False)
 | 
						|
 | 
						|
 | 
						|
class ArrowBlock(Block):
 | 
						|
    def __init__(self, level, x, y, direction, movable=True, is_up=True):
 | 
						|
        self.__dict__.update(locals())
 | 
						|
        worldobject.WorldObject.__init__(self, level, x, y,
 | 
						|
                                         direction=direction, movable=movable)
 | 
						|
 | 
						|
        self.frame = 0
 | 
						|
        self.anim_speed = 15
 | 
						|
        self.setting = False
 | 
						|
 | 
						|
        if direction == (1, 0):
 | 
						|
            self.anim = 'arrow_right'
 | 
						|
        if direction == (-1, 0):
 | 
						|
            self.anim = 'arrow_left'
 | 
						|
        if direction == (0, -1):
 | 
						|
            self.anim = 'arrow_up'
 | 
						|
        if direction == (0, 1):
 | 
						|
            self.anim = 'arrow_down'
 | 
						|
 | 
						|
    def activate(self, setting):
 | 
						|
        self.movable = True
 | 
						|
        if not self.share_tile(worldobject.WorldObject):
 | 
						|
            self.is_up = not setting
 | 
						|
        self.movable = False
 | 
						|
 | 
						|
    def update(self, e, t, dt):
 | 
						|
        # Update the animation
 | 
						|
        if not self.is_up:
 | 
						|
            self.frame = min(self.frame + self.anim_speed * dt,
 | 
						|
                             len(self.level.imgs[self.anim]) - 1)
 | 
						|
        else:
 | 
						|
            self.frame = max(self.frame - self.anim_speed * dt,
 | 
						|
                             0)
 | 
						|
 | 
						|
        if self.frame == len(self.level.imgs[self.anim]) - 1:
 | 
						|
            self.movable = self.blocking = False
 | 
						|
            self.z = -48
 | 
						|
            if self.holder:
 | 
						|
                self.holder.holding = None
 | 
						|
                self.holder = None
 | 
						|
        else:
 | 
						|
            self.movable = self.blocking = True
 | 
						|
            self.z = 0
 | 
						|
 | 
						|
        worldobject.WorldObject.update(self, e, t, dt)
 | 
						|
 | 
						|
    def draw(self, window):
 | 
						|
        self.img = self.level.imgs[self.anim][int(self.frame)]
 | 
						|
        Block.draw(self, window)
 | 
						|
 | 
						|
class RisingBlock(Block):
 | 
						|
    def __init__(self, level, x, y, movable=False, is_up=True):
 | 
						|
        self.__dict__.update(locals())
 | 
						|
        worldobject.WorldObject.__init__(self, level, x, y, movable=movable)
 | 
						|
 | 
						|
        self.frame = 0
 | 
						|
        self.anim_speed = 15
 | 
						|
        self.setting = [0, 0]
 | 
						|
 | 
						|
        self.init_setting = self.setting
 | 
						|
 | 
						|
        self.anim = 'arrow_right'
 | 
						|
 | 
						|
    def set_init_pos(self):
 | 
						|
        worldobject.WorldObject.set_init_pos(self)
 | 
						|
        self.init_setting = [self.setting[0], self.setting[1]]
 | 
						|
 | 
						|
    def reset_pos(self):
 | 
						|
        worldobject.WorldObject.reset_pos(self)
 | 
						|
        self.setting = [self.init_setting[0], self.init_setting[1]]
 | 
						|
        self.is_up = self.setting[1] == self.setting[0]
 | 
						|
 | 
						|
    def activate(self, setting):
 | 
						|
        if setting in [2, 3]:
 | 
						|
            self.setting[1] = setting - 2
 | 
						|
        else:
 | 
						|
            self.setting[0] = setting
 | 
						|
        if not self.share_tile(worldobject.WorldObject):
 | 
						|
            self.is_up = self.setting[1] == self.setting[0]
 | 
						|
 | 
						|
    def update(self, e, t, dt):
 | 
						|
        # Update the animation
 | 
						|
        if not self.is_up:
 | 
						|
            self.frame = min(self.frame + self.anim_speed * dt,
 | 
						|
                             len(self.level.imgs[self.anim]) - 1)
 | 
						|
        else:
 | 
						|
            self.frame = max(self.frame - self.anim_speed * dt,
 | 
						|
                             0)
 | 
						|
 | 
						|
        if self.frame == len(self.level.imgs[self.anim]) - 1:
 | 
						|
            self.blocking = False
 | 
						|
            self.z = -48
 | 
						|
        else:
 | 
						|
            self.blocking = True
 | 
						|
            self.z = 0
 | 
						|
 | 
						|
        worldobject.WorldObject.update(self, e, t, dt)
 | 
						|
 | 
						|
    def draw(self, window):
 | 
						|
        self.img = self.level.imgs[self.anim][int(self.frame)]
 | 
						|
        Block.draw(self, window)
 | 
						|
 | 
						|
 | 
						|
class ActionBlock(Block):
 | 
						|
    def __init__(self, level, x, y, action=None, movable=True):
 | 
						|
        self.__dict__.update(locals())
 | 
						|
        Block.__init__(
 | 
						|
            self, level, x, y, 'block1', movable=movable)
 | 
						|
        self._last_pos = None
 | 
						|
 | 
						|
    def update(self, e, t, dt):
 | 
						|
        if (self.x, self.y) != self._last_pos and not self.is_moving:
 | 
						|
            self.action(self)
 | 
						|
            self._last_pos = self.x, self.y
 | 
						|
 | 
						|
        worldobject.WorldObject.update(self, e, t, dt)
 | 
						|
 | 
						|
class ColorWell(Block):
 | 
						|
    def __init__(self, level, x, y, img_str='well'):
 | 
						|
        self.__dict__.update(locals())
 | 
						|
        worldobject.WorldObject.__init__(
 | 
						|
            self, level, x, y, movable=False)
 | 
						|
 | 
						|
        Block.load(self)
 | 
						|
 | 
						|
        self.col_img = pygame.Surface((32, 32))
 | 
						|
 | 
						|
    def set_colour(self, r, g, b):
 | 
						|
        self.well_colour = r * 255, g * 255, b * 255
 | 
						|
        self.col_img.fill(self.well_colour)
 | 
						|
 | 
						|
    def draw(self, window):
 | 
						|
        if self.visible:
 | 
						|
            window.blit(self.col_img, (self.x - self.level.camera_x + 16,
 | 
						|
                                   self.y - self.img.get_size()[1] + 52
 | 
						|
                                   - self.level.camera_y))
 | 
						|
        Block.draw(self, window)
 | 
						|
 | 
						|
class Door(Block):
 | 
						|
    def __init__(self, level, x, y, movable=False, setting=False):
 | 
						|
        self.__dict__.update(locals())
 | 
						|
        worldobject.WorldObject.__init__(self, level, x, y, movable=movable)
 | 
						|
 | 
						|
        self.frame = 0
 | 
						|
        self.anim_speed = 15
 | 
						|
 | 
						|
        self.init_setting = self.setting
 | 
						|
 | 
						|
        self.anim = 'door'
 | 
						|
 | 
						|
        self.level.objects.append(InvisBlock(self.level, self.x + 64, self.y))
 | 
						|
        self.level.objects.append(InvisBlock(self.level, self.x - 64, self.y))
 | 
						|
 | 
						|
    def set_init_pos(self):
 | 
						|
        worldobject.WorldObject.set_init_pos(self)
 | 
						|
        self.init_setting = self.setting
 | 
						|
 | 
						|
    def reset_pos(self):
 | 
						|
        worldobject.WorldObject.reset_pos(self)
 | 
						|
        self.setting = self.init_setting
 | 
						|
 | 
						|
    def activate(self, setting):
 | 
						|
        self.setting = setting
 | 
						|
 | 
						|
    def update(self, e, t, dt):
 | 
						|
        # Update the animation
 | 
						|
        if self.setting:
 | 
						|
            self.frame = min(self.frame + self.anim_speed * dt,
 | 
						|
                             len(self.level.imgs[self.anim]) - 1)
 | 
						|
        else:
 | 
						|
            self.frame = max(self.frame - self.anim_speed * dt,
 | 
						|
                             0)
 | 
						|
 | 
						|
        if self.frame == len(self.level.imgs[self.anim]) - 1:
 | 
						|
            self.blocking = False
 | 
						|
        else:
 | 
						|
            self.blocking = True
 | 
						|
 | 
						|
        worldobject.WorldObject.update(self, e, t, dt)
 | 
						|
 | 
						|
    def draw(self, window):
 | 
						|
        self.img = self.level.imgs[self.anim][int(self.frame)]
 | 
						|
        if self.visible:
 | 
						|
            window.blit(self.img, (self.x - (32 + 64) - self.level.camera_x,
 | 
						|
                                   self.y - self.img.get_size()[1] + 24
 | 
						|
                                   - self.level.camera_y))
 |