2014-06-02 23:13:23 -07:00
|
|
|
import pygame
|
2014-06-04 07:27:30 -07:00
|
|
|
import time
|
|
|
|
|
import random
|
2014-06-06 01:37:57 -07:00
|
|
|
import os
|
2014-06-06 08:16:35 -07:00
|
|
|
import inspect
|
2014-06-06 01:37:57 -07:00
|
|
|
|
|
|
|
|
levelTitles = [
|
|
|
|
|
[
|
|
|
|
|
[1,0,0, 0, 1,3,2, 0, 1,0,3, 0, 3,1,4, 0, 4,0,0, 0, 0,1,0],
|
|
|
|
|
[2,0,0, 0, 2,0,0, 0, 3,0,4, 0, 1,0,0, 0, 2,0,0, 0, 2,3,0],
|
|
|
|
|
[1,0,0, 0, 3,1,4, 0, 4,0,2, 0, 2,4,2, 0, 1,0,0, 0, 0,1,0],
|
|
|
|
|
[3,0,0, 0, 4,0,0, 0, 0,1,0, 0, 4,0,0, 0, 3,0,0, 0, 0,4,0],
|
|
|
|
|
[4,3,2, 0, 1,2,1, 0, 0,3,0, 0, 3,1,2, 0, 4,1,2, 0, 1,2,4],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[1,0,0, 0, 1,3,2, 0, 1,0,3, 0, 3,1,4, 0, 4,0,0, 0, 0,1,0],
|
|
|
|
|
[2,0,0, 0, 2,0,0, 0, 3,0,4, 0, 1,0,0, 0, 2,0,0, 0, 2,0,3],
|
|
|
|
|
[1,0,0, 0, 3,1,4, 0, 4,0,2, 0, 2,4,2, 0, 1,0,0, 0, 0,0,1],
|
|
|
|
|
[3,0,0, 0, 4,0,0, 0, 0,1,0, 0, 4,0,0, 0, 3,0,0, 0, 1,2,0],
|
|
|
|
|
[4,3,2, 0, 1,2,1, 0, 0,3,0, 0, 3,1,2, 0, 4,1,2, 0, 3,2,1]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[1,0,0, 0, 1,3,2, 0, 1,0,3, 0, 3,1,4, 0, 4,0,0, 0, 4,1,3],
|
|
|
|
|
[2,0,0, 0, 2,0,0, 0, 3,0,4, 0, 1,0,0, 0, 2,0,0, 0, 0,0,3],
|
|
|
|
|
[1,0,0, 0, 3,1,4, 0, 4,0,2, 0, 2,4,2, 0, 1,0,0, 0, 1,1,2],
|
|
|
|
|
[3,0,0, 0, 4,0,0, 0, 0,1,0, 0, 4,0,0, 0, 3,0,0, 0, 0,0,4],
|
|
|
|
|
[4,3,2, 0, 1,2,1, 0, 0,3,0, 0, 3,1,2, 0, 4,1,2, 0, 3,2,1],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[1,0,0, 0, 1,3,2, 0, 1,0,3, 0, 3,1,4, 0, 4,0,0, 0, 4,0,2],
|
|
|
|
|
[2,0,0, 0, 2,0,0, 0, 3,0,4, 0, 1,0,0, 0, 2,0,0, 0, 2,0,3],
|
|
|
|
|
[1,0,0, 0, 3,1,4, 0, 4,0,2, 0, 2,4,2, 0, 1,0,0, 0, 3,1,2],
|
|
|
|
|
[3,0,0, 0, 4,0,0, 0, 0,1,0, 0, 4,0,0, 0, 3,0,0, 0, 0,0,3],
|
|
|
|
|
[4,3,2, 0, 1,2,1, 0, 0,3,0, 0, 3,1,2, 0, 4,1,2, 0, 0,0,4],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[1,0,0, 0, 1,3,2, 0, 1,0,3, 0, 3,1,4, 0, 4,0,0, 0, 1,2,1],
|
|
|
|
|
[2,0,0, 0, 2,0,0, 0, 3,0,4, 0, 1,0,0, 0, 2,0,0, 0, 4,0,0],
|
|
|
|
|
[1,0,0, 0, 3,1,4, 0, 4,0,2, 0, 2,4,2, 0, 1,0,0, 0, 1,3,4],
|
|
|
|
|
[3,0,0, 0, 4,0,0, 0, 0,1,0, 0, 4,0,0, 0, 3,0,0, 0, 0,0,1],
|
|
|
|
|
[4,3,2, 0, 1,2,1, 0, 0,3,0, 0, 3,1,2, 0, 4,1,2, 0, 4,3,2],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[1,0,0, 0, 1,3,2, 0, 1,0,3, 0, 3,1,4, 0, 4,0,0, 0, 1,1,4],
|
|
|
|
|
[2,0,0, 0, 2,0,0, 0, 3,0,4, 0, 1,0,0, 0, 2,0,0, 0, 2,0,0],
|
|
|
|
|
[1,0,0, 0, 3,1,4, 0, 4,0,2, 0, 2,4,2, 0, 1,0,0, 0, 1,3,1],
|
|
|
|
|
[3,0,0, 0, 4,0,0, 0, 0,1,0, 0, 4,0,0, 0, 3,0,0, 0, 4,0,1],
|
|
|
|
|
[4,3,2, 0, 1,2,1, 0, 0,3,0, 0, 3,1,2, 0, 4,1,2, 0, 3,2,4],
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[1,0,0, 0, 1,3,2, 0, 1,0,3, 0, 3,1,4, 0, 4,0,0, 0, 3,1,4],
|
|
|
|
|
[2,0,0, 0, 2,0,0, 0, 3,0,4, 0, 1,0,0, 0, 2,0,0, 0, 0,0,2],
|
|
|
|
|
[1,0,0, 0, 3,1,4, 0, 4,0,2, 0, 2,4,2, 0, 1,0,0, 0, 0,4,0],
|
|
|
|
|
[3,0,0, 0, 4,0,0, 0, 0,1,0, 0, 4,0,0, 0, 3,0,0, 0, 0,3,0],
|
|
|
|
|
[4,3,2, 0, 1,2,1, 0, 0,3,0, 0, 3,1,2, 0, 4,1,2, 0, 0,1,0],
|
|
|
|
|
]
|
2014-06-02 23:13:23 -07:00
|
|
|
]
|
2014-06-06 01:37:57 -07:00
|
|
|
|
|
|
|
|
maps = [
|
|
|
|
|
[
|
|
|
|
|
[4,2,1,3,2,1],
|
|
|
|
|
[3,4,4,4,1,3],
|
|
|
|
|
[2,3,2,3,3,3],
|
|
|
|
|
[4,4,3,1,3,3],
|
|
|
|
|
[3,1,4,2,2,1],
|
|
|
|
|
[2,3,1,1,4,2]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[4,1,3,4,2,2,4],
|
|
|
|
|
[1,4,4,2,1,4,4],
|
|
|
|
|
[1,1,4,2,1,3,1],
|
|
|
|
|
[4,1,1,3,1,3,4],
|
|
|
|
|
[2,4,4,3,1,4,2],
|
|
|
|
|
[4,3,2,4,3,4,3],
|
|
|
|
|
[3,4,1,3,3,3,3]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[4,1,2,2,4,3,1,3],
|
|
|
|
|
[2,3,1,3,2,1,3,1],
|
|
|
|
|
[3,4,1,3,2,4,1,1],
|
|
|
|
|
[4,3,1,3,4,1,1,4],
|
|
|
|
|
[2,4,2,1,1,2,4,1],
|
|
|
|
|
[1,3,2,1,2,1,1,2],
|
|
|
|
|
[4,3,1,3,4,3,1,2],
|
|
|
|
|
[1,1,3,2,4,2,2,1]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[2,3,3,3,2,2,3,4,4],
|
|
|
|
|
[4,4,3,3,1,3,2,1,3],
|
|
|
|
|
[4,3,4,2,1,3,4,1,2],
|
|
|
|
|
[4,3,1,1,1,1,3,1,1],
|
|
|
|
|
[4,2,3,3,1,1,4,4,2],
|
|
|
|
|
[2,4,2,2,3,1,2,2,2],
|
|
|
|
|
[1,4,3,2,4,4,1,3,1],
|
|
|
|
|
[1,3,4,4,2,1,3,4,1],
|
|
|
|
|
[2,1,2,2,1,4,4,3,2]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[2,2,3,4,4,1,3,4,3,1],
|
|
|
|
|
[1,2,1,4,3,1,4,1,1,1],
|
|
|
|
|
[1,2,3,4,2,4,1,1,3,3],
|
|
|
|
|
[3,4,1,4,2,4,4,2,4,4],
|
|
|
|
|
[3,3,1,1,2,1,2,2,2,1],
|
|
|
|
|
[4,1,2,4,4,2,3,4,1,1],
|
|
|
|
|
[2,2,4,3,2,4,3,1,1,1],
|
|
|
|
|
[4,3,1,2,3,1,1,1,3,3],
|
|
|
|
|
[2,2,3,3,1,4,1,3,1,1],
|
|
|
|
|
[3,3,4,2,2,4,3,4,1,4]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[1,1,1,4,3,2,2,2,4,2,1],
|
|
|
|
|
[2,3,3,2,2,2,1,2,1,1,1],
|
|
|
|
|
[4,3,2,3,1,3,2,4,4,2,2],
|
|
|
|
|
[1,4,3,2,2,2,2,1,3,3,3],
|
|
|
|
|
[3,2,2,3,1,4,3,1,4,3,2],
|
|
|
|
|
[3,1,1,1,1,3,1,2,3,2,4],
|
|
|
|
|
[1,2,4,1,1,2,1,1,4,1,4],
|
|
|
|
|
[3,2,4,1,3,2,3,3,4,1,4],
|
|
|
|
|
[2,4,3,4,2,3,1,2,1,2,3],
|
|
|
|
|
[1,2,1,2,3,3,4,4,3,2,3],
|
|
|
|
|
[3,3,3,3,3,4,1,4,4,2,3]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[4,4,1,3,2,4,4,2,3,2,2,3],
|
|
|
|
|
[2,4,1,3,2,3,3,4,4,3,1,2],
|
|
|
|
|
[1,3,3,4,3,1,4,3,1,1,3,2],
|
|
|
|
|
[4,2,2,1,2,2,3,3,1,3,4,1],
|
|
|
|
|
[3,2,2,3,4,4,2,2,3,2,2,2],
|
|
|
|
|
[1,1,3,3,1,4,3,2,2,4,4,2],
|
|
|
|
|
[3,1,3,3,3,2,2,3,3,1,4,3],
|
|
|
|
|
[2,3,2,3,4,4,3,3,3,4,2,3],
|
|
|
|
|
[1,4,2,3,2,1,3,4,2,3,4,2],
|
|
|
|
|
[1,2,3,2,1,4,2,2,3,1,3,3],
|
|
|
|
|
[4,4,4,2,2,4,3,4,2,2,2,1],
|
|
|
|
|
[4,1,1,3,2,1,3,3,1,1,4,2]
|
|
|
|
|
],
|
|
|
|
|
[
|
|
|
|
|
[4,4,1,3,2,4,4,2,3,2,2,3,2],
|
|
|
|
|
[2,4,1,3,2,3,3,4,4,3,1,2,3],
|
|
|
|
|
[1,3,3,4,3,1,4,3,1,1,3,2,1],
|
|
|
|
|
[4,2,2,1,2,2,3,3,1,3,4,1,1],
|
|
|
|
|
[3,2,2,3,4,4,2,2,3,2,2,2,3],
|
|
|
|
|
[1,1,3,3,1,4,3,2,2,4,4,2,3],
|
|
|
|
|
[3,1,3,3,3,2,2,3,3,1,4,3,2],
|
|
|
|
|
[2,3,2,3,4,4,3,3,3,4,2,3,4],
|
|
|
|
|
[1,4,2,3,2,1,3,4,2,3,4,2,4],
|
|
|
|
|
[1,2,3,2,1,4,2,2,3,1,3,3,1],
|
|
|
|
|
[4,4,4,2,2,4,3,4,2,2,2,1,4],
|
|
|
|
|
[4,1,1,3,2,1,3,3,1,1,4,2,2],
|
|
|
|
|
[3,2,2,3,4,4,2,2,3,2,2,2,3]
|
|
|
|
|
]
|
|
|
|
|
]
|
2014-06-04 07:27:30 -07:00
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
class Game:
|
2014-06-06 08:16:35 -07:00
|
|
|
LOAD_PATH = os.path.dirname(inspect.stack()[0][1])
|
2014-06-04 07:27:30 -07:00
|
|
|
# Debug flags, disable these before production
|
2014-06-06 01:37:57 -07:00
|
|
|
DEBUG_MODE = False
|
|
|
|
|
DRAW_MOVES = True
|
2014-06-04 07:27:30 -07:00
|
|
|
# -----
|
|
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
MARBLE_WIDTH = 40
|
|
|
|
|
MARBLE_HEIGHT = 40
|
2014-06-04 08:44:31 -07:00
|
|
|
MARBLE_CENTER_X = 20
|
|
|
|
|
MARBLE_CENTER_Y = 20
|
|
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
COLOR_MAGICPINK = (255, 0, 255, 0)
|
|
|
|
|
COLOR_WHITE = (255, 255, 255, 255)
|
|
|
|
|
COLOR_BLACK = (0, 0, 0, 255)
|
2014-06-06 01:37:57 -07:00
|
|
|
SCREEN_WIDTH = 960
|
|
|
|
|
SCREEN_HEIGHT = 540
|
2014-06-03 17:28:13 -07:00
|
|
|
|
|
|
|
|
STATE_NONE = 0
|
|
|
|
|
STATE_FALLING = 1
|
2014-06-04 07:27:30 -07:00
|
|
|
STATE_SELECTED = 1 << 1
|
|
|
|
|
STATE_DEAD = 1 << 2
|
|
|
|
|
STATE_PLAYERTOUCHED = 1 << 3
|
2014-06-04 08:44:31 -07:00
|
|
|
STATE_DRAGGING = 1 << 4
|
2014-06-02 23:13:23 -07:00
|
|
|
|
2014-06-06 01:37:57 -07:00
|
|
|
STATE_GAME_MAIN = 1 << 1
|
|
|
|
|
STATE_GAME_TITLE = 1 << 2
|
|
|
|
|
STATE_GAME_TITLE_FALLING = 1 << 3
|
|
|
|
|
STATE_GAME_WIN = 1 << 5
|
|
|
|
|
|
2014-06-03 17:28:13 -07:00
|
|
|
M_IDX_MOVES = 0
|
|
|
|
|
M_IDX_TYPE = 1
|
|
|
|
|
M_IDX_STATE = 2
|
|
|
|
|
M_IDX_POS = 3
|
|
|
|
|
M_IDX_VEL = 4
|
|
|
|
|
|
|
|
|
|
P_IDX_X = 0
|
|
|
|
|
P_IDX_Y = 1
|
|
|
|
|
|
2014-06-06 01:37:57 -07:00
|
|
|
VELOCITY_CUMULATIVE = 1
|
|
|
|
|
VELOCITY_STATIC = 2
|
|
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
def __init__(self):
|
|
|
|
|
pygame.init()
|
2014-06-06 01:37:57 -07:00
|
|
|
pygame.mixer.init()
|
|
|
|
|
self.__velocity_mode__ = Game.VELOCITY_CUMULATIVE
|
|
|
|
|
self.__gamestate__ = Game.STATE_GAME_TITLE
|
2014-06-02 23:13:23 -07:00
|
|
|
self.__display__ = pygame.display.set_mode((Game.SCREEN_WIDTH, Game.SCREEN_HEIGHT))
|
|
|
|
|
self.__blitTarget__ = self.__display__.convert_alpha()
|
|
|
|
|
self.__marbles__ = []
|
|
|
|
|
pygame.display.set_caption("Fuck This Collapse")
|
|
|
|
|
self.__load_marbles__()
|
2014-06-06 08:16:35 -07:00
|
|
|
self.__sound_falling__ = pygame.mixer.Sound(self.__loadpath__(['snd', 'marblefall.wav']))
|
|
|
|
|
self.__sound_click__ = pygame.mixer.Sound(self.__loadpath__(['snd', 'marbleclick.wav']))
|
|
|
|
|
self.__sound_level__ = pygame.mixer.Sound(self.__loadpath__(['snd', 'newlevel.wav']))
|
|
|
|
|
pygame.mixer.music.load(self.__loadpath__(['snd', 'POL-lurking-short.wav']))
|
2014-06-06 01:37:57 -07:00
|
|
|
pygame.mixer.music.play(-1)
|
|
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
self.__curMap__ = None
|
|
|
|
|
self.__curMapRect__ = None
|
|
|
|
|
self.__moves__ = 0
|
|
|
|
|
self.__maxMarbleMoves__ = 4
|
|
|
|
|
|
2014-06-04 07:27:30 -07:00
|
|
|
self.__selectedMarble__ = [-1, -1]
|
2014-06-03 17:28:13 -07:00
|
|
|
self.__setSelectedMarble__([-1, -1])
|
2014-06-02 23:13:23 -07:00
|
|
|
self.__selectionRect__ = None
|
|
|
|
|
self.__selectionSurface__ = pygame.Surface(
|
|
|
|
|
(Game.MARBLE_WIDTH, Game.MARBLE_HEIGHT),
|
|
|
|
|
pygame.SRCALPHA | pygame.HWSURFACE)
|
|
|
|
|
self.__selectionSurface__.fill((255,255,255, 128))
|
|
|
|
|
|
|
|
|
|
self.__gameFont__ = pygame.font.SysFont(pygame.font.get_default_font(), 18)
|
2014-06-04 07:27:30 -07:00
|
|
|
self.__debugFont__ = pygame.font.SysFont(pygame.font.get_default_font(), 12)
|
2014-06-02 23:37:29 -07:00
|
|
|
self.__mapIndex__ = 0
|
2014-06-06 01:37:57 -07:00
|
|
|
self.__setMap__(levelTitles[self.__mapIndex__], isTitle = True)
|
2014-06-02 23:13:23 -07:00
|
|
|
|
2014-06-06 08:16:35 -07:00
|
|
|
def __loadpath__(self, items):
|
|
|
|
|
return os.path.join(Game.LOAD_PATH, *items)
|
|
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
def __load_marbles__(self):
|
|
|
|
|
self.__marbles__.append(None)
|
2014-06-06 08:16:35 -07:00
|
|
|
self.__marbles__.append(pygame.image.load(self.__loadpath__(['gfx', 'BlueSwirl.png'])))
|
|
|
|
|
self.__marbles__.append(pygame.image.load(self.__loadpath__(['gfx', 'MochaVolcano.png'])))
|
|
|
|
|
self.__marbles__.append(pygame.image.load(self.__loadpath__(['gfx', 'SwirlyEyeball.png'])))
|
|
|
|
|
self.__marbles__.append(pygame.image.load(self.__loadpath__(['gfx', 'ZebraGum.png'])))
|
2014-06-02 23:13:23 -07:00
|
|
|
|
2014-06-06 01:37:57 -07:00
|
|
|
def __setMap__(self, maparray, isTitle=False):
|
2014-06-02 23:13:23 -07:00
|
|
|
self.__curMap__ = []
|
2014-06-03 17:28:13 -07:00
|
|
|
self.__curMapRect__ = pygame.Rect(
|
|
|
|
|
((Game.SCREEN_WIDTH - (Game.MARBLE_WIDTH * len(maparray[0])))/2),
|
2014-06-04 07:27:30 -07:00
|
|
|
0,
|
2014-06-03 17:28:13 -07:00
|
|
|
(Game.MARBLE_WIDTH * len(maparray[0])),
|
|
|
|
|
(Game.MARBLE_HEIGHT * len(maparray))
|
|
|
|
|
)
|
|
|
|
|
|
2014-06-06 01:37:57 -07:00
|
|
|
initState = Game.STATE_NONE
|
2014-06-03 17:28:13 -07:00
|
|
|
x = self.__curMapRect__.left
|
|
|
|
|
y = self.__curMapRect__.top
|
2014-06-06 01:37:57 -07:00
|
|
|
self.__gamestate__ = Game.STATE_GAME_MAIN
|
|
|
|
|
self.__velocity_mode__ = Game.VELOCITY_CUMULATIVE
|
|
|
|
|
Game.DRAW_MOVES = True
|
|
|
|
|
|
|
|
|
|
if isTitle:
|
|
|
|
|
Game.DRAW_MOVES = False
|
|
|
|
|
self.__gamestate__ = Game.STATE_GAME_TITLE
|
|
|
|
|
self.__sound_level__.play()
|
|
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
for row in maparray:
|
2014-06-03 17:28:13 -07:00
|
|
|
x = self.__curMapRect__.left
|
2014-06-02 23:13:23 -07:00
|
|
|
mrow = []
|
2014-06-03 17:28:13 -07:00
|
|
|
self.__curMap__.append(mrow)
|
2014-06-02 23:13:23 -07:00
|
|
|
for col in row:
|
2014-06-03 17:28:13 -07:00
|
|
|
mrow.append(
|
|
|
|
|
[self.__maxMarbleMoves__,
|
|
|
|
|
col,
|
2014-06-06 01:37:57 -07:00
|
|
|
initState,
|
2014-06-03 17:28:13 -07:00
|
|
|
[x, y],
|
2014-06-06 01:37:57 -07:00
|
|
|
[0.0, 0.0]])
|
2014-06-03 17:28:13 -07:00
|
|
|
x += Game.MARBLE_WIDTH
|
|
|
|
|
y += Game.MARBLE_HEIGHT
|
2014-06-02 23:13:23 -07:00
|
|
|
|
2014-06-03 17:28:13 -07:00
|
|
|
def __update__(self):
|
2014-06-06 01:37:57 -07:00
|
|
|
if self.__gamestate__ == Game.STATE_GAME_WIN:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
all_are_dead = True
|
|
|
|
|
|
2014-06-04 07:27:30 -07:00
|
|
|
for ri in range(len(self.__curMap__)-1, -1, -1):
|
|
|
|
|
row = self.__curMap__[ri]
|
|
|
|
|
ci = 0
|
|
|
|
|
for col in row:
|
|
|
|
|
if ( (col[Game.M_IDX_TYPE]) and (not self.__hasMarbleState__([ci, ri], Game.STATE_DEAD)) ):
|
|
|
|
|
if ( self.__curMap__[ri][ci][Game.M_IDX_TYPE] == 0 ):
|
|
|
|
|
self.__curMap__[ri][ci][Game.M_IDX_STATE] = Game.STATE_DEAD
|
|
|
|
|
elif ( self.__hasMarbleState__([ci, ri], Game.STATE_FALLING) ):
|
2014-06-06 01:37:57 -07:00
|
|
|
all_are_dead = False
|
|
|
|
|
if ( col[Game.M_IDX_POS][Game.P_IDX_Y] > Game.SCREEN_HEIGHT ):
|
|
|
|
|
self.__sound_falling__.play()
|
|
|
|
|
self.__curMap__[ri][ci] = [99999999,
|
|
|
|
|
0,
|
|
|
|
|
Game.STATE_DEAD,
|
|
|
|
|
[ self.__curMapRect__.left + (ci * Game.MARBLE_WIDTH),
|
|
|
|
|
self.__curMapRect__.top + (ri * Game.MARBLE_HEIGHT) ],
|
|
|
|
|
[0, 0]
|
|
|
|
|
]
|
2014-06-04 07:27:30 -07:00
|
|
|
continue
|
2014-06-06 01:37:57 -07:00
|
|
|
col[Game.M_IDX_VEL][Game.P_IDX_Y] += 0.2
|
2014-06-04 07:27:30 -07:00
|
|
|
|
|
|
|
|
# OH GOD, MY EYES
|
|
|
|
|
nextri = (col[Game.M_IDX_POS][Game.P_IDX_Y] + (Game.MARBLE_HEIGHT)) / Game.MARBLE_HEIGHT
|
|
|
|
|
if ( ( (nextri) >= (len(self.__curMap__)) ) or
|
|
|
|
|
( self.__hasMarbleState__([ci, nextri], Game.STATE_FALLING) ) or
|
|
|
|
|
( self.__hasMarbleState__([ci, nextri], Game.STATE_DEAD) ) ):
|
2014-06-06 01:37:57 -07:00
|
|
|
col[Game.M_IDX_POS][Game.P_IDX_Y] += int(col[Game.M_IDX_VEL][Game.P_IDX_Y])
|
2014-06-04 07:27:30 -07:00
|
|
|
else:
|
2014-06-06 01:37:57 -07:00
|
|
|
self.__flipMarbles__([ci, ri], [ci, nextri-1])
|
|
|
|
|
self.__delMarbleState__([ci, nextri-1], Game.STATE_FALLING)
|
2014-06-04 07:27:30 -07:00
|
|
|
# --- THE GOGGLES DO NOTHING
|
2014-06-06 01:37:57 -07:00
|
|
|
elif ( not self.__hasMarbleState__([ci, ri], Game.STATE_DEAD) ):
|
|
|
|
|
all_are_dead = False
|
2014-06-04 07:27:30 -07:00
|
|
|
ci += 1
|
|
|
|
|
ri += 1
|
2014-06-06 01:37:57 -07:00
|
|
|
if ( all_are_dead ) and ( self.__gamestate__ == Game.STATE_GAME_TITLE_FALLING ):
|
|
|
|
|
self.__setMap__(maps[self.__mapIndex__])
|
|
|
|
|
elif ( all_are_dead ) and ( self.__gamestate__ == Game.STATE_GAME_MAIN ):
|
|
|
|
|
if ( (self.__mapIndex__ + 1) >= (len(maps)-1) ):
|
|
|
|
|
self.__gamestate__ = Game.STATE_GAME_WIN
|
|
|
|
|
return
|
|
|
|
|
self.__mapIndex__ += 1
|
|
|
|
|
self.__setMap__(levelTitles[self.__mapIndex__], isTitle = True)
|
2014-06-03 17:28:13 -07:00
|
|
|
return
|
2014-06-02 23:13:23 -07:00
|
|
|
|
2014-06-04 08:44:31 -07:00
|
|
|
def __draw_marble__(self, mx, my, marble):
|
2014-06-06 01:37:57 -07:00
|
|
|
if ( (marble[Game.M_IDX_TYPE] or Game.DEBUG_MODE ) and (marble[Game.M_IDX_STATE] != Game.STATE_DEAD)):
|
2014-06-04 08:44:31 -07:00
|
|
|
if self.__hasMarbleState__([mx, my], Game.STATE_DRAGGING):
|
|
|
|
|
mpos = pygame.mouse.get_pos()
|
|
|
|
|
x = mpos[Game.P_IDX_X] - Game.MARBLE_CENTER_X
|
|
|
|
|
y = mpos[Game.P_IDX_Y] - Game.MARBLE_CENTER_Y
|
|
|
|
|
else:
|
|
|
|
|
x = marble[Game.M_IDX_POS][Game.P_IDX_X]
|
|
|
|
|
y = marble[Game.M_IDX_POS][Game.P_IDX_Y]
|
2014-06-06 01:37:57 -07:00
|
|
|
if ( marble[Game.M_IDX_TYPE] ):
|
|
|
|
|
self.__blitTarget__.blit(self.__marbles__[marble[Game.M_IDX_TYPE]], (x, y))
|
|
|
|
|
if ( Game.DRAW_MOVES ):
|
|
|
|
|
text = self.__gameFont__.render("{}".format(marble[Game.M_IDX_MOVES]), 1, Game.COLOR_WHITE)
|
|
|
|
|
textpos = text.get_rect(right = x + (Game.MARBLE_WIDTH),
|
|
|
|
|
top = y)
|
|
|
|
|
self.__blitTarget__.blit(text, textpos)
|
2014-06-04 08:44:31 -07:00
|
|
|
|
|
|
|
|
if Game.DEBUG_MODE:
|
|
|
|
|
text = self.__gameFont__.render("{}".format(marble[Game.M_IDX_STATE]), 1, Game.COLOR_WHITE)
|
|
|
|
|
textpos = text.get_rect(left = x,
|
|
|
|
|
bottom = y + Game.MARBLE_HEIGHT)
|
|
|
|
|
self.__blitTarget__.blit(text, textpos)
|
|
|
|
|
text = self.__gameFont__.render("{},{}".format(mx, my), 1, Game.COLOR_BLACK)
|
|
|
|
|
textpos = text.get_rect(centerx = x + (Game.MARBLE_WIDTH/2),
|
|
|
|
|
centery = y + (Game.MARBLE_HEIGHT/2))
|
|
|
|
|
self.__blitTarget__.blit(text, textpos)
|
|
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
def __draw__(self):
|
|
|
|
|
self.__display__.fill(Game.COLOR_BLACK)
|
|
|
|
|
self.__blitTarget__.fill(Game.COLOR_MAGICPINK)
|
2014-06-06 01:37:57 -07:00
|
|
|
|
|
|
|
|
if self.__gamestate__ == Game.STATE_GAME_WIN:
|
|
|
|
|
text = self.__gameFont__.render("CONGLATURATIONS! YOU HAVE COMPLETED A GREAT GAME!", 1, Game.COLOR_WHITE)
|
|
|
|
|
textpos = text.get_rect(centerx = Game.SCREEN_WIDTH / 2,
|
|
|
|
|
centery = Game.SCREEN_HEIGHT / 2)
|
|
|
|
|
self.__blitTarget__.blit(text, textpos)
|
|
|
|
|
|
|
|
|
|
text = self.__gameFont__.render("NOW GO, AND REST OUR HEROS!", 1, Game.COLOR_WHITE)
|
|
|
|
|
textpos = text.get_rect(centerx = Game.SCREEN_WIDTH / 2,
|
|
|
|
|
centery = ( Game.SCREEN_HEIGHT / 2) + 40)
|
|
|
|
|
self.__blitTarget__.blit(text, textpos)
|
|
|
|
|
|
|
|
|
|
self.__display__.blit(self.__blitTarget__, (0, 0))
|
|
|
|
|
return
|
|
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
if not self.__curMap__:
|
|
|
|
|
return
|
2014-06-06 01:37:57 -07:00
|
|
|
|
|
|
|
|
if self.__gamestate__ == Game.STATE_GAME_MAIN and self.__mapIndex__ == 0:
|
|
|
|
|
y = Game.SCREEN_HEIGHT / 2
|
|
|
|
|
for textline in ["* Make vertical lines of 3 marbles of the same color",
|
|
|
|
|
"* Click and Drag to Move Marbles",
|
|
|
|
|
"* Marbles can move horizontal, vertical, and diagonal",
|
|
|
|
|
"* Marbles can move one space at a time only",
|
|
|
|
|
"* Lines will collapse onto marbles beneath them",
|
|
|
|
|
"* Lines will fall completely if there is nothing below them",
|
|
|
|
|
"* The number shows how many times a marble can be moved",
|
|
|
|
|
"* Levels end when no more moves can be made",
|
|
|
|
|
"* Get as many lines off the screen as you can"]:
|
|
|
|
|
text = self.__gameFont__.render(textline, 1, Game.COLOR_WHITE)
|
|
|
|
|
textpos = text.get_rect(left = (Game.SCREEN_WIDTH / 3),
|
|
|
|
|
centery = y)
|
|
|
|
|
self.__blitTarget__.blit(text, textpos)
|
|
|
|
|
y += textpos.height
|
|
|
|
|
|
2014-06-04 08:44:31 -07:00
|
|
|
drawLast = []
|
2014-06-04 07:27:30 -07:00
|
|
|
ri = 0
|
2014-06-02 23:13:23 -07:00
|
|
|
for row in self.__curMap__:
|
2014-06-04 07:27:30 -07:00
|
|
|
ci = 0
|
2014-06-02 23:13:23 -07:00
|
|
|
for col in row:
|
2014-06-04 08:44:31 -07:00
|
|
|
if self.__hasMarbleState__([ci, ri], Game.STATE_DRAGGING):
|
|
|
|
|
drawLast = [ci, ri, col]
|
|
|
|
|
else:
|
|
|
|
|
self.__draw_marble__(ci, ri, col)
|
2014-06-04 07:27:30 -07:00
|
|
|
ci += 1
|
|
|
|
|
ri += 1
|
2014-06-04 08:44:31 -07:00
|
|
|
if drawLast:
|
|
|
|
|
self.__draw_marble__(drawLast[0], drawLast[1], drawLast[2])
|
2014-06-04 07:27:30 -07:00
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
if self.__selectionRect__ :
|
|
|
|
|
self.__blitTarget__.blit(
|
|
|
|
|
self.__selectionSurface__,
|
|
|
|
|
(self.__selectionRect__.left, self.__selectionRect__.top)
|
|
|
|
|
)
|
2014-06-06 01:37:57 -07:00
|
|
|
|
|
|
|
|
if self.__gamestate__ == Game.STATE_GAME_TITLE and self.__mapIndex__ == 0:
|
|
|
|
|
text = self.__gameFont__.render("Fuck This Collapse", 1, Game.COLOR_WHITE)
|
|
|
|
|
textpos = text.get_rect(centerx = Game.SCREEN_WIDTH / 2,
|
|
|
|
|
centery = Game.SCREEN_HEIGHT / 2)
|
|
|
|
|
self.__blitTarget__.blit(text, textpos)
|
|
|
|
|
|
|
|
|
|
text = self.__gameFont__.render("for Fuck This Jam", 1, Game.COLOR_WHITE)
|
|
|
|
|
textpos = text.get_rect(centerx = Game.SCREEN_WIDTH / 2,
|
|
|
|
|
centery = ( Game.SCREEN_HEIGHT / 2) + (textpos.height * 2))
|
|
|
|
|
self.__blitTarget__.blit(text, textpos)
|
|
|
|
|
|
|
|
|
|
text = self.__gameFont__.render("Andrew Kesterson <andrew@aklabs.net>", 1, Game.COLOR_WHITE)
|
|
|
|
|
textpos = text.get_rect(centerx = Game.SCREEN_WIDTH / 2,
|
|
|
|
|
centery = ( Game.SCREEN_HEIGHT / 2) + (textpos.height * 3))
|
|
|
|
|
self.__blitTarget__.blit(text, textpos)
|
|
|
|
|
|
|
|
|
|
text = self.__gameFont__.render("https://www.github.com/akesterson/", 1, Game.COLOR_WHITE)
|
|
|
|
|
textpos = text.get_rect(centerx = Game.SCREEN_WIDTH / 2,
|
|
|
|
|
centery = ( Game.SCREEN_HEIGHT / 2) + (textpos.height * 4))
|
|
|
|
|
self.__blitTarget__.blit(text, textpos)
|
|
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
self.__display__.blit(self.__blitTarget__, (0, 0))
|
|
|
|
|
|
|
|
|
|
def __canSelectMarble__(self, x, y):
|
2014-06-06 01:37:57 -07:00
|
|
|
if ( (self.__curMap__[y][x][Game.M_IDX_STATE] == Game.STATE_DEAD) and
|
|
|
|
|
(not self.__hasMarbleState__(self.__selectedMarble__, Game.STATE_DRAGGING)) ):
|
2014-06-04 07:27:30 -07:00
|
|
|
return False
|
2014-06-02 23:13:23 -07:00
|
|
|
if self.__selectedMarble__ == [-1, -1]:
|
|
|
|
|
return True
|
2014-06-04 08:44:31 -07:00
|
|
|
left = self.__selectedMarble__[Game.P_IDX_X]
|
|
|
|
|
top = self.__selectedMarble__[Game.P_IDX_Y]
|
|
|
|
|
if ( left > 0 ):
|
|
|
|
|
left -= 1
|
|
|
|
|
if ( top > 0 ):
|
|
|
|
|
top -= 1
|
|
|
|
|
|
|
|
|
|
selectable = pygame.Rect(left, top, 3, 3)
|
|
|
|
|
return selectable.collidepoint(x, y)
|
2014-06-02 23:13:23 -07:00
|
|
|
|
2014-06-04 07:27:30 -07:00
|
|
|
def __flipMarbles__(self, m1, m2, force=False):
|
2014-06-06 01:37:57 -07:00
|
|
|
if ( m1 == m2 ):
|
|
|
|
|
return
|
|
|
|
|
# Skip empty (black) marbles (unless we're dragging or falling)
|
|
|
|
|
if ( ( not self.__hasMarbleState__(self.__selectedMarble__, Game.STATE_DRAGGING)) and
|
|
|
|
|
( ( not self.__hasMarbleState__(m1, Game.STATE_FALLING)) and
|
|
|
|
|
( not self.__hasMarbleState__(m2, Game.STATE_FALLING)) ) and
|
|
|
|
|
( ( self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]][Game.M_IDX_TYPE] == 0 ) or
|
|
|
|
|
( self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]][Game.M_IDX_TYPE] == 0 ) )
|
|
|
|
|
):
|
2014-06-02 23:13:23 -07:00
|
|
|
return
|
2014-06-04 07:27:30 -07:00
|
|
|
if ( ( self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]][Game.M_IDX_MOVES] <= 0 ) or
|
|
|
|
|
( self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]][Game.M_IDX_MOVES] <= 0 ) ):
|
|
|
|
|
return
|
2014-06-02 23:50:02 -07:00
|
|
|
|
2014-06-03 17:28:13 -07:00
|
|
|
# Swap marbles
|
|
|
|
|
tmp = self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]]
|
|
|
|
|
self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]] = self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]]
|
|
|
|
|
self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]] = tmp
|
|
|
|
|
|
2014-06-06 01:37:57 -07:00
|
|
|
# FIX positions of the marbles
|
|
|
|
|
for m in [m1, m2]:
|
|
|
|
|
self.__curMap__[m[Game.P_IDX_Y]][m[Game.P_IDX_X]][Game.M_IDX_POS] = [
|
|
|
|
|
self.__curMapRect__.left + (m[Game.P_IDX_X] * Game.MARBLE_WIDTH),
|
|
|
|
|
self.__curMapRect__.top + (m[Game.P_IDX_Y] * Game.MARBLE_HEIGHT)
|
|
|
|
|
]
|
|
|
|
|
|
2014-06-03 17:28:13 -07:00
|
|
|
# Decrement movecount remaining on both marbles
|
|
|
|
|
self.__curMap__[m1[Game.P_IDX_Y]][m1[Game.P_IDX_X]][Game.M_IDX_MOVES] -= 1
|
|
|
|
|
self.__curMap__[m2[Game.P_IDX_Y]][m2[Game.P_IDX_X]][Game.M_IDX_MOVES] -= 1
|
2014-06-02 23:13:23 -07:00
|
|
|
|
2014-06-04 07:27:30 -07:00
|
|
|
def __setMarbleState__(self, pos, state):
|
|
|
|
|
self.__curMap__[pos[Game.P_IDX_Y]][pos[Game.P_IDX_X]][Game.M_IDX_STATE] = state
|
|
|
|
|
|
|
|
|
|
def __addMarbleState__(self, pos, state):
|
|
|
|
|
cs = self.__curMap__[pos[Game.P_IDX_Y]][pos[Game.P_IDX_X]][Game.M_IDX_STATE]
|
|
|
|
|
cs = ( cs | state )
|
|
|
|
|
self.__curMap__[pos[Game.P_IDX_Y]][pos[Game.P_IDX_X]][Game.M_IDX_STATE] = cs
|
|
|
|
|
|
|
|
|
|
def __delMarbleState__(self, pos, state):
|
|
|
|
|
if ( not self.__hasMarbleState__(pos, state) ):
|
|
|
|
|
return
|
|
|
|
|
cs = self.__curMap__[pos[Game.P_IDX_Y]][pos[Game.P_IDX_X]][Game.M_IDX_STATE]
|
|
|
|
|
cs = ( cs ^ state )
|
|
|
|
|
self.__curMap__[pos[Game.P_IDX_Y]][pos[Game.P_IDX_X]][Game.M_IDX_STATE] = cs
|
|
|
|
|
|
|
|
|
|
def __hasMarbleState__(self, pos, state):
|
|
|
|
|
return ( (self.__curMap__[pos[Game.P_IDX_Y]][pos[Game.P_IDX_X]][Game.M_IDX_STATE] & state) == state)
|
2014-06-02 23:13:23 -07:00
|
|
|
|
2014-06-03 17:28:13 -07:00
|
|
|
def __setSelectedMarble__(self, pos):
|
2014-06-04 07:27:30 -07:00
|
|
|
if self.__selectedMarble__ != [-1, -1]:
|
|
|
|
|
self.__delMarbleState__(self.__selectedMarble__, Game.STATE_SELECTED)
|
2014-06-03 17:28:13 -07:00
|
|
|
self.__selectedMarble__ = pos
|
|
|
|
|
if pos == [-1, -1]:
|
|
|
|
|
self.__selectionRect__ = None
|
|
|
|
|
return
|
2014-06-04 07:27:30 -07:00
|
|
|
if ((self.__curMap__) and (self.__curMap__[pos[Game.P_IDX_Y]][pos[Game.P_IDX_X]][Game.M_IDX_STATE] == Game.STATE_DEAD)):
|
|
|
|
|
self.__setSelectedMarble__([-1, -1])
|
|
|
|
|
return
|
2014-06-03 17:28:13 -07:00
|
|
|
self.__selectionRect__ = pygame.Rect(
|
|
|
|
|
(self.__curMapRect__.left + (pos[Game.P_IDX_X] * Game.MARBLE_WIDTH)),
|
|
|
|
|
(self.__curMapRect__.top + (pos[Game.P_IDX_Y] * Game.MARBLE_HEIGHT)),
|
|
|
|
|
Game.MARBLE_WIDTH,
|
|
|
|
|
Game.MARBLE_HEIGHT)
|
2014-06-04 07:27:30 -07:00
|
|
|
self.__addMarbleState__(pos, Game.STATE_SELECTED)
|
2014-06-03 17:28:13 -07:00
|
|
|
|
2014-06-04 08:44:31 -07:00
|
|
|
def __mouseReleased__(self, event):
|
2014-06-06 01:37:57 -07:00
|
|
|
if self.__gamestate__ == Game.STATE_GAME_WIN:
|
|
|
|
|
return
|
|
|
|
|
elif self.__gamestate__ == Game.STATE_GAME_TITLE:
|
|
|
|
|
return
|
|
|
|
|
elif self.__gamestate__ == Game.STATE_GAME_TITLE_FALLING:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
self.__sound_click__.play()
|
|
|
|
|
|
2014-06-03 17:28:13 -07:00
|
|
|
mouse_x = event.pos[Game.P_IDX_X]
|
|
|
|
|
mouse_y = event.pos[Game.P_IDX_Y]
|
2014-06-02 23:13:23 -07:00
|
|
|
marble_x = ( (mouse_x - self.__curMapRect__.left) / Game.MARBLE_WIDTH)
|
|
|
|
|
marble_y = ( (mouse_y - self.__curMapRect__.top) / Game.MARBLE_HEIGHT)
|
2014-06-03 17:28:13 -07:00
|
|
|
|
2014-06-06 01:37:57 -07:00
|
|
|
if ( ( not self.__curMapRect__.collidepoint((mouse_x, mouse_y)) ) or
|
|
|
|
|
( (not self.__hasMarbleState__(self.__selectedMarble__, Game.STATE_DRAGGING)) and
|
|
|
|
|
self.__curMap__[marble_y][marble_x][Game.M_IDX_TYPE] == 0 )
|
|
|
|
|
):
|
|
|
|
|
self.__delMarbleState__(self.__selectedMarble__, Game.STATE_SELECTED)
|
2014-06-04 08:44:31 -07:00
|
|
|
self.__delMarbleState__(self.__selectedMarble__, Game.STATE_DRAGGING)
|
2014-06-03 17:28:13 -07:00
|
|
|
self.__setSelectedMarble__([-1, -1])
|
2014-06-02 23:13:23 -07:00
|
|
|
self.__selectionRect__ = None
|
|
|
|
|
return
|
2014-06-04 08:44:31 -07:00
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
if event.button == 1:
|
2014-06-04 08:44:31 -07:00
|
|
|
if self.__hasMarbleState__(self.__selectedMarble__,
|
|
|
|
|
Game.STATE_DRAGGING):
|
|
|
|
|
flipMarble = self.__selectedMarble__
|
|
|
|
|
if not self.__canSelectMarble__(marble_x, marble_y):
|
2014-06-06 01:37:57 -07:00
|
|
|
self.__delMarbleState__(self.__selectedMarble__, Game.STATE_DRAGGING)
|
|
|
|
|
self.__delMarbleState__(self.__selectedMarble__, Game.STATE_SELECTED)
|
2014-06-04 08:44:31 -07:00
|
|
|
self.__setSelectedMarble__([-1, -1])
|
|
|
|
|
return
|
2014-06-06 01:37:57 -07:00
|
|
|
self.__addMarbleState__(flipMarble, Game.STATE_PLAYERTOUCHED)
|
|
|
|
|
self.__addMarbleState__([marble_x, marble_y], Game.STATE_PLAYERTOUCHED)
|
2014-06-04 08:44:31 -07:00
|
|
|
self.__flipMarbles__(flipMarble, [marble_x, marble_y])
|
2014-06-06 01:37:57 -07:00
|
|
|
self.__setSelectedMarble__([-1, -1])
|
|
|
|
|
for marble in [[marble_x, marble_y], flipMarble]:
|
|
|
|
|
for state in [Game.STATE_SELECTED, Game.STATE_DRAGGING]:
|
|
|
|
|
self.__delMarbleState__(marble, state)
|
|
|
|
|
|
2014-06-04 08:44:31 -07:00
|
|
|
self.__setGroupState__()
|
|
|
|
|
else:
|
|
|
|
|
self.__setSelectedMarble__([marble_x, marble_y])
|
|
|
|
|
self.__addMarbleState__([marble_x, marble_y], Game.STATE_PLAYERTOUCHED)
|
|
|
|
|
self.__setGroupState__()
|
2014-06-02 23:13:23 -07:00
|
|
|
return
|
|
|
|
|
|
2014-06-04 08:44:31 -07:00
|
|
|
def __mouseClicked__(self, event):
|
2014-06-06 01:37:57 -07:00
|
|
|
self.__sound_click__.play()
|
|
|
|
|
|
|
|
|
|
if self.__gamestate__ == Game.STATE_GAME_WIN:
|
|
|
|
|
return
|
|
|
|
|
elif self.__gamestate__ == Game.STATE_GAME_TITLE:
|
|
|
|
|
self.__sound_falling__.play()
|
|
|
|
|
self.__gamestate__ = Game.STATE_GAME_TITLE_FALLING
|
|
|
|
|
for row in self.__curMap__:
|
|
|
|
|
for col in row:
|
|
|
|
|
col[Game.M_IDX_STATE] = Game.STATE_PLAYERTOUCHED | Game.STATE_FALLING
|
|
|
|
|
return
|
|
|
|
|
|
2014-06-04 08:44:31 -07:00
|
|
|
mouse_x = event.pos[Game.P_IDX_X]
|
|
|
|
|
mouse_y = event.pos[Game.P_IDX_Y]
|
|
|
|
|
marble_x = ( (mouse_x - self.__curMapRect__.left) / Game.MARBLE_WIDTH)
|
|
|
|
|
marble_y = ( (mouse_y - self.__curMapRect__.top) / Game.MARBLE_HEIGHT)
|
|
|
|
|
|
|
|
|
|
if ( ( not self.__curMapRect__.collidepoint((mouse_x, mouse_y))) or
|
|
|
|
|
(self.__curMap__[marble_y][marble_x][Game.M_IDX_TYPE] == 0 ) ):
|
|
|
|
|
# We can't drag empty space or space outside the map
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if not self.__canSelectMarble__(marble_x, marble_y):
|
|
|
|
|
return
|
|
|
|
|
self.__setSelectedMarble__([marble_x, marble_y])
|
|
|
|
|
self.__addMarbleState__([marble_x, marble_y], Game.STATE_DRAGGING)
|
|
|
|
|
self.__addMarbleState__([marble_x, marble_y], Game.STATE_PLAYERTOUCHED)
|
|
|
|
|
|
2014-06-04 07:27:30 -07:00
|
|
|
def __setGroupState__(self, zap=False):
|
2014-06-06 01:37:57 -07:00
|
|
|
amount_by_type_with_moves = {
|
|
|
|
|
1: 0,
|
|
|
|
|
2: 0,
|
|
|
|
|
3: 0,
|
|
|
|
|
4: 0
|
|
|
|
|
}
|
2014-06-03 17:28:13 -07:00
|
|
|
groups = {
|
|
|
|
|
0: [],
|
|
|
|
|
1: [],
|
|
|
|
|
2: [],
|
|
|
|
|
3: [],
|
|
|
|
|
4: []
|
|
|
|
|
}
|
|
|
|
|
groups_of_3 = [
|
|
|
|
|
[],
|
|
|
|
|
[],
|
|
|
|
|
[],
|
2014-06-04 07:27:30 -07:00
|
|
|
[],
|
2014-06-03 17:28:13 -07:00
|
|
|
[]
|
|
|
|
|
]
|
|
|
|
|
x = 0
|
|
|
|
|
y = 0
|
|
|
|
|
curMatchMarble = 0
|
|
|
|
|
prevy = 0
|
|
|
|
|
group = None
|
|
|
|
|
for row in self.__curMap__:
|
|
|
|
|
x = 0
|
|
|
|
|
for col in row:
|
|
|
|
|
if col[Game.M_IDX_TYPE] != 0:
|
2014-06-06 01:37:57 -07:00
|
|
|
if col[Game.M_IDX_MOVES] > 0 and col[Game.M_IDX_MOVES] < 99 :
|
|
|
|
|
amount_by_type_with_moves[col[Game.M_IDX_TYPE]] += 1
|
2014-06-03 17:28:13 -07:00
|
|
|
candidates = [
|
2014-06-04 07:27:30 -07:00
|
|
|
# --X--
|
2014-06-03 17:28:13 -07:00
|
|
|
[x, y + 1] # --C--
|
|
|
|
|
]
|
|
|
|
|
for c in candidates:
|
2014-06-04 07:27:30 -07:00
|
|
|
cx = c[Game.P_IDX_X]
|
|
|
|
|
cy = c[Game.P_IDX_Y]
|
|
|
|
|
if ( (cy >= len(self.__curMap__)) or
|
|
|
|
|
(cy < 0 ) or
|
|
|
|
|
(cx >= len(self.__curMap__[cy])) or
|
|
|
|
|
(cx < 0 ) ):
|
|
|
|
|
continue
|
|
|
|
|
if ( self.__curMap__[cy][cx][Game.M_IDX_TYPE] == col[Game.M_IDX_TYPE] ):
|
|
|
|
|
curMatchMarble = col[Game.M_IDX_TYPE]
|
|
|
|
|
group = None
|
|
|
|
|
for group in groups[curMatchMarble]:
|
|
|
|
|
if ( ( [cx, cy] in group ) or
|
|
|
|
|
( [x, y] in group ) ):
|
|
|
|
|
break
|
2014-06-03 17:28:13 -07:00
|
|
|
group = None
|
2014-06-04 07:27:30 -07:00
|
|
|
if not group:
|
|
|
|
|
group = [[x, y]]
|
|
|
|
|
groups[curMatchMarble].append(group)
|
|
|
|
|
if [cx, cy] in group:
|
|
|
|
|
group.append([x, y])
|
|
|
|
|
else:
|
|
|
|
|
group.append([cx, cy])
|
|
|
|
|
|
2014-06-03 17:28:13 -07:00
|
|
|
x += 1
|
|
|
|
|
y += 1
|
2014-06-04 07:27:30 -07:00
|
|
|
|
2014-06-06 01:37:57 -07:00
|
|
|
game_can_continue = False
|
|
|
|
|
for k, v in amount_by_type_with_moves.iteritems():
|
|
|
|
|
if v >= 3:
|
|
|
|
|
game_can_continue = True
|
|
|
|
|
if not game_can_continue:
|
|
|
|
|
for row in self.__curMap__:
|
|
|
|
|
for col in row:
|
|
|
|
|
col[Game.M_IDX_STATE] = Game.STATE_DEAD
|
|
|
|
|
|
2014-06-03 17:28:13 -07:00
|
|
|
for marble, group in groups.iteritems():
|
|
|
|
|
for grp in group:
|
2014-06-04 07:27:30 -07:00
|
|
|
if len(grp) < 3:
|
|
|
|
|
continue
|
|
|
|
|
# At least one marble in the set has to have been touched by the player
|
|
|
|
|
for tpair in grp:
|
|
|
|
|
if self.__hasMarbleState__([tpair[Game.P_IDX_X], tpair[Game.P_IDX_Y]],
|
|
|
|
|
Game.STATE_PLAYERTOUCHED):
|
|
|
|
|
break
|
|
|
|
|
tpair = None
|
|
|
|
|
if not tpair:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
for pair in grp:
|
|
|
|
|
if self.__hasMarbleState__([tpair[Game.P_IDX_X], tpair[Game.P_IDX_Y]],
|
|
|
|
|
Game.STATE_SELECTED):
|
|
|
|
|
self.__setSelectedMarble__([-1, -1])
|
|
|
|
|
if zap:
|
|
|
|
|
self.__curMap__[pair[Game.P_IDX_Y]][pair[Game.P_IDX_X]][Game.M_IDX_STATE] = Game.STATE_DEAD
|
|
|
|
|
else:
|
|
|
|
|
self.__addMarbleState__(pair, Game.STATE_FALLING)
|
2014-06-03 17:28:13 -07:00
|
|
|
|
2014-06-02 23:13:23 -07:00
|
|
|
def run(self):
|
|
|
|
|
while True:
|
2014-06-03 17:28:13 -07:00
|
|
|
self.__update__()
|
2014-06-02 23:13:23 -07:00
|
|
|
self.__draw__()
|
|
|
|
|
|
|
|
|
|
for event in pygame.event.get():
|
|
|
|
|
if event.type == pygame.QUIT:
|
|
|
|
|
pygame.quit()
|
|
|
|
|
return
|
2014-06-02 23:37:29 -07:00
|
|
|
elif event.type == pygame.KEYUP:
|
2014-06-06 01:37:57 -07:00
|
|
|
if ( Game.DEBUG_MODE ):
|
|
|
|
|
if ( (pygame.key.get_pressed()[pygame.K_LCTRL]) and
|
|
|
|
|
(event.key == pygame.K_LEFT) and
|
|
|
|
|
(self.__mapIndex__ > 0) ):
|
|
|
|
|
self.__mapIndex__ -= 1
|
|
|
|
|
self.__setMap__(maps[self.__mapIndex__])
|
|
|
|
|
self.__setSelectedMarble__([-1, -1])
|
|
|
|
|
elif ( (pygame.key.get_pressed()[pygame.K_LCTRL]) and
|
|
|
|
|
(event.key == pygame.K_RIGHT) and
|
|
|
|
|
(self.__mapIndex__ < (len(maps)-1))):
|
|
|
|
|
self.__mapIndex__ += 1
|
|
|
|
|
self.__setMap__(maps[self.__mapIndex__])
|
|
|
|
|
self.__setSelectedMarble__([-1, -1])
|
2014-06-02 23:37:29 -07:00
|
|
|
|
2014-06-04 08:44:31 -07:00
|
|
|
elif event.type == pygame.MOUSEBUTTONDOWN:
|
2014-06-02 23:13:23 -07:00
|
|
|
self.__mouseClicked__(event)
|
2014-06-04 08:44:31 -07:00
|
|
|
elif event.type == pygame.MOUSEBUTTONUP:
|
|
|
|
|
self.__mouseReleased__(event)
|
2014-06-02 23:13:23 -07:00
|
|
|
pygame.display.update()
|
|
|
|
|
return
|