aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ddrinput.py124
-rw-r--r--renderer.py55
-rw-r--r--tetris.py15
-rw-r--r--util.py4
4 files changed, 134 insertions, 64 deletions
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
diff --git a/tetris.py b/tetris.py
index 64b3eed..9bab2ad 100644
--- a/tetris.py
+++ b/tetris.py
@@ -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,150,110]
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"]
@@ -187,7 +188,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
@@ -203,7 +204,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()
@@ -213,7 +214,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
@@ -263,14 +264,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:
@@ -296,7 +297,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:
diff --git a/util.py b/util.py
index 97982e1..bb6779a 100644
--- a/util.py
+++ b/util.py
@@ -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: