diff options
author | Leah Alpert <lalpert@mit.edu> | 2011-08-29 14:16:23 -0700 |
---|---|---|
committer | Leah Alpert <lalpert@mit.edu> | 2011-08-29 14:16:23 -0700 |
commit | 447198355077ab2ef71547d4a4f484705fb3bd50 (patch) | |
tree | d5d31b64bd0889721a4b5534437d0b1ddf29711f | |
parent | 48a363a21aea69a3d86d93f077f66fb8a9c1557f (diff) | |
parent | 507b67d9190697f6324006116784c4e763e969fc (diff) |
Merge branch 'master' of github.com:rcoh/Burton-Conner-Tetris-Battle
-rw-r--r-- | README | 4 | ||||
-rw-r--r-- | ddrinput.py | 124 | ||||
-rw-r--r-- | renderer.py | 55 | ||||
-rw-r--r-- | tetris.py | 15 | ||||
-rw-r--r-- | util.py | 4 |
5 files changed, 137 insertions, 65 deletions
@@ -8,8 +8,10 @@ Once all players have joined, press DOWN to start the game Use LEFT and RIGHT to move your shape, UP to rotate, and DOWN to make it drop faster When you complete a line it will disappear from the board and you gain one point. Your score is displayed in binary below your board. If you clear two or more lines at once, n-1 incomplete lines will appear at the bottom of your opponent�s board. +The blocks drop faster as players clear more lines. There are 6 possible levels + When one player�s board reaches the top of the screen, they lose and the other player wins. -If neither player loses after 3 minutes, the player with the higher score wins. +If neither player loses after 4 minutes, the player with the higher score wins. Press ESC to exit the program. diff --git a/ddrinput.py b/ddrinput.py index 19966d8..6cad156 100644 --- a/ddrinput.py +++ b/ddrinput.py @@ -1,10 +1,14 @@ import pygame +import time +======= JOY_EVENT = 7 +JOY_EVENT_2 = 10 KEY_EVENT = 2 +KEY_RELEASE = 3 X = 0 Y = 1 -(LEFT, RIGHT, UP, DOWN) = range(4) +(LEFT, RIGHT, UP, DOWN, DROP, DIE, RELEASE) = range(7) KEY_LEFT = 276 KEY_UP = 273 KEY_DOWN = 274 @@ -16,7 +20,7 @@ KEY_W = 119 KEY_SPACE = 32 KEY_ESC = 27 -DIRECTIONS = {0:'LEFT', 1:'RIGHT', 2:'UP', 3:'DOWN'} +DIRECTIONS = {0:'LEFT', 1:'RIGHT', 2:'UP', 3:'DOWN', 5:'DROP', 6:'DIE'} class DdrInput(object): """ DdrInput is a class to get input from the particular DDR pads and adapters we have. It is not @@ -37,6 +41,7 @@ class DdrInput(object): #This is just so that we can get key presses in the demo. remove when we plug it into a ui screen = pygame.display.set_mode((640, 480)) self.debug_mode = debug_mode + self.active_inputs = {} def init_joysticks(self): pygame.joystick.init() @@ -58,9 +63,41 @@ class DdrInput(object): event = pygame.event.poll() player_move = None if event.type == JOY_EVENT: + player_index, player_move = handle_joy_event(event) + if self.debug_mode: + print (player_index, player_move) + + if self.debug_mode: + if event.type == KEY_EVENT or event.type == KEY_RELEASE: + (player_index, player_move) = self.handle_key_event(event) + + + if player_move != None: + if player_move == RELEASE: + self.active_inputs[player_index] = None + return None + else: + print 'setting active input' + self.active_inputs[player_index] = (.5, time.time(), player_move) + return (player_index, player_move) + else: + for player_index in self.active_inputs: + if self.active_inputs[player_index] != None: + (fallback_start, start_time, move) = self.active_inputs[player_index] + print time.time() - start_time + if time.time() - start_time > fallback_start: + fallback_start /= 2 + fallback_start = max(.1, fallback_start) + start_time = time.time() + self.active_inputs[player_index] = (fallback_start, start_time, move) + return (player_index, move) + return None + + def handle_joy_event(self, event): player_index = event.joy #there may be a tricky quick way to code this, but this is more readable #value == 0 -> released + player_move = None if event.axis == X: if event.value < 0: player_move = LEFT @@ -71,46 +108,43 @@ class DdrInput(object): player_move = DOWN elif event.value < 0: player_move = UP - if self.debug_mode and player_move != None: - print (player_index, player_move) - if player_move != None: - return (player_index, player_move) - else: - return None - if self.debug_mode: - if event.type == KEY_EVENT: - if event.key == KEY_LEFT: - player_index = 1 - player_move = LEFT - elif event.key == KEY_RIGHT: - player_index = 1 - player_move = RIGHT - elif event.key == KEY_DOWN: - player_index = 1 - player_move = DOWN - elif event.key == KEY_UP: - player_index = 1 - player_move = UP - elif event.key == KEY_A: - player_index = 0 - player_move = LEFT - elif event.key == KEY_D: - player_index = 0 - player_move = RIGHT - elif event.key == KEY_S: - player_index = 0 - player_move = DOWN - elif event.key == KEY_W: - player_index = 0 - player_move = UP - elif event.key == KEY_ESC: - player_index = 2 - player_move = "DIE" - elif event.key == KEY_SPACE: - player_index = 1 - player_move = "DROP" - - if player_move != None: - return (player_index, player_move) - else: - return None + if event.value == 0: + player_move = RELEASE + + return player_index, player_move + + def handle_key_event(self, event): + if event.key == KEY_LEFT: + player_index = 1 + player_move = LEFT + elif event.key == KEY_RIGHT: + player_index = 1 + player_move = RIGHT + elif event.key == KEY_DOWN: + player_index = 1 + player_move = DOWN + elif event.key == KEY_UP: + player_index = 1 + player_move = UP + elif event.key == KEY_A: + player_index = 0 + player_move = LEFT + elif event.key == KEY_D: + player_index = 0 + player_move = RIGHT + elif event.key == KEY_S: + player_index = 0 + player_move = DOWN + elif event.key == KEY_W: + player_index = 0 + player_move = UP + elif event.key == KEY_ESC: + player_index = 2 + player_move = DIE + elif event.key == KEY_SPACE: + player_index = 1 + player_move = DROP + + if event.type == KEY_RELEASE: + player_move = RELEASE + return (player_index, player_move) diff --git a/renderer.py b/renderer.py index 2e13707..bd141c8 100644 --- a/renderer.py +++ b/renderer.py @@ -1,3 +1,10 @@ +from numpy import zeros + +import pygame +from pygame.locals import Color + +import util + class Renderer(object): def render_game(self, game_board): """ @@ -10,8 +17,6 @@ class Renderer(object): def color_deref(self, color_str): return Color(color_str) -import pygame -from pygame.locals import Color class PygameRenderer(Renderer): """ @@ -51,38 +56,68 @@ class PygameRenderer(Renderer): for (x,y) in game_board: disp_x = x if x >= 10: - disp_x+=3 + disp_x+=3 + x0 = self.OFFSET[0] - self.SCALE/2 - 3 + y0 = self.OFFSET[1] - 10 + x1 = self.OFFSET[0]+8 + 9*self.SCALE + y1 = self.OFFSET[1]+8 + 19*self.SCALE + b2 = self.SCALE * 13 #x offset for second board + line_endpoints = [((x0,y0), (x0,y1)), ((x0,y1), (x1,y1)), ((x1,y1), (x1,y0)), ((x1,y0), (x0,y0)), + ((x0,y1 - 16), (x1,y1 - 16)), ((x0,y1 - 31), (x1,y1 - 31))] + for p1,p2 in line_endpoints: + pygame.draw.line(self.background, self.color_deref("white"), p1, p2) + pygame.draw.line(self.background, self.color_deref("white"), (p1[0]+b2,p1[1]),(p2[0]+b2,p2[1])) + pygame.draw.circle(self.background, self.color_deref(game_board[(x,y)]), (self.OFFSET[0] + disp_x*self.SCALE, self.OFFSET[1] + y*self.SCALE), self.RADIUS) self.screen.blit(self.background, (0,0)) pygame.display.flip() -import util class LedRenderer(Renderer): """ Renderer for the LEDs. Based heavily on IndoorRenderer in Smootlight and general Smootlight abstraction patterns """ - POWER_SUPPLY_IPS = [0,0,0,0] #TODO: Fill in + POWER_SUPPLY_IPS = ['10.32.97.17',0,0,0] #TODO: Fill in SOCK_PORT = 6038 sockets = {} def render_game(self, game_board): packets = self.map_to_packets(game_board) packets_with_destinations = zip(self.POWER_SUPPLY_IPS, packets) - for (ip, (port, packet)) in packets: + for (ip, (port, packet)) in packets_with_destinations: if not ip in self.sockets: self.sockets[ip] = util.getConnectedSocket(ip, self.SOCK_PORT) final_packet = util.composePixelStripPacket(packet, port) try: - self.sockets[ip].send(packet, 0x00) + if self.sockets[ip] != None: + self.sockets[ip].send(final_packet, 0x00) except: print 'failure sending packet' - - def map_to_packets(game_board): + def color_deref(self, color): + return (255, 0, 0) + def map_to_packets(self, game_board): """ Performs the mapping between a game_board and a list of (port,packet) pairs. The port,packet pairs should line up with the ip's in IP_ADDRESSES """ - #TODO(rcoh): Write this when we decide on a layout + #This is hardcoded, mostly because I'm curious of the complexity + packets = [] + board_x_min = 0 + board_x_max = 10 + section_width = 10 + section_height = 5 + for board_x_min in [0, 10]: + packet = [] + for board_y_min in [20, 15, 10, 5]: + strip = zeros((50,3),'ubyte') + index = 0 + for y in range(board_y_min, board_y_min-section_height, -1): + for x in range(board_x_min+section_width, board_x_min, -1): + if (x,y) in game_board: + strip[index] = self.color_deref(game_board[(x,y)]) + packet.append((1+len(packet), strip)) + index += 1 + packets += packet + return packets @@ -13,6 +13,7 @@ from time import sleep, time import random import sys from renderer import PygameRenderer +from renderer import LedRenderer from tetris_shape import * from ddrinput import DdrInput from ddrinput import DIRECTIONS @@ -24,7 +25,7 @@ LEVEL_SPEEDS = [700,550,400,250,160,120] MAXX = 10 MAXY = 18 -(LEFT, RIGHT, UP, DOWN) = range(4) +(LEFT, RIGHT, UP, DOWN, DROP, DIE) = range(6) COLORS = ["orange", "red", "green", "blue", "purple", "yellow", "magenta"] LEVEL_COLORS = ["red", "orange", "yellow", "green", "blue", "purple"] @@ -185,7 +186,7 @@ class Player(): #contains variables that are shared between the players: #levels, delay time, etc class GameState(): - def __init__(self, gui): + def __init__(self): self.shapes = [square_shape, t_shape,l_shape, reverse_l_shape, z_shape, s_shape,i_shape ] self.num_players = 0 @@ -201,7 +202,7 @@ class TetrisGame(object): #one-time initialization for gui etc def __init__(self): print "initialize tetris" - self.gui = PygameRenderer() + self.gui = [PygameRenderer(), LedRenderer()] self.input = DdrInput() while True: self.init_game() @@ -211,7 +212,7 @@ class TetrisGame(object): print "init next game" self.boards = [Board(MAXX,MAXY), Board(MAXX,MAXY)] self.players = [None,None] - self.gameState = GameState(self.gui) + self.gameState = GameState() self.board_animation(0,"up_arrow") self.board_animation(1,"up_arrow") self.start_time = None @@ -260,14 +261,14 @@ class TetrisGame(object): if ev: player,direction = ev #print "Player",player,direction - if direction == "DIE": #Exit instruction + if direction == DIE: #Exit instruction game_on = False pygame.quit() sys.exit() if self.gameState.state=="playing": if self.players[player]!=None: #DROP is only for debugging purposes for now, to make the game end. - if direction == "DROP": + if direction == DROP: while self.players[player].handle_move( DOWN ): pass else: @@ -293,7 +294,7 @@ class TetrisGame(object): p.handle_move(DOWN) def update_gui(self): - self.gui.render_game(self.to_dict()) + [gui.render_game(self.to_dict()) for gui in self.gui] def end_game(self): if self.gameState.winner!=None: @@ -1,16 +1,16 @@ from numpy import zeros +import socket argDict = {'flags': 0, 'startcode': 0x0fff, 'pad':0} # Allocate a buffer for transmitted packets and fill it with magic # Only works for strips of 50 pixels xmit = zeros(174, dtype='ubyte') -xmit[:8], xmit[20:24] = [4,1,220,74,1,0,8,1], [150,0,255,15] +xmit[:8], xmit[20:25] = [4,1,220,74,1,0,8,1], [150,0,255,15,191] def composePixelStripPacket(values, port): xmit[16], xmit[24:] = port, values.ravel() return xmit -import socket def getConnectedSocket(ip,port): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) try: |