|
|
@@ -32,7 +32,8 @@ TOP_LEFT_Y = S_HEIGHT - PLAY_HEIGHT
|
|
|
|
|
|
|
|
|
def draw_text_middle(surface, text, size, color):
|
|
|
- font = pygame.font.SysFont("comicsans", size, bold=True)
|
|
|
+ font = pygame.font.SysFont(
|
|
|
+ pygame.font.get_default_font(), size, bold=True)
|
|
|
label = font.render(text, 1, color)
|
|
|
|
|
|
surface.blit(label, (TOP_LEFT_X + PLAY_WIDTH /2 - (label.get_width()/2), TOP_LEFT_Y + PLAY_HEIGHT/2 - label.get_height()/2))
|
|
|
@@ -49,8 +50,8 @@ def draw_grid(surface, grid):
|
|
|
|
|
|
|
|
|
def draw_next_shape(shape, surface):
|
|
|
- font = pygame.font.SysFont('comicsans', 30)
|
|
|
- label = font.render('Next Shape', 1, (255,255,255))
|
|
|
+ font = pygame.font.SysFont(pygame.font.get_default_font(), 30)
|
|
|
+ label = font.render("Next Shape", 1, (255,255,255))
|
|
|
|
|
|
sx = TOP_LEFT_X + PLAY_WIDTH + 0
|
|
|
sy = TOP_LEFT_Y + PLAY_HEIGHT/2 - 100
|
|
|
@@ -59,7 +60,7 @@ def draw_next_shape(shape, surface):
|
|
|
for i, line in enumerate(shape_raw):
|
|
|
row = list(line)
|
|
|
for j, column in enumerate(row):
|
|
|
- if column == '0':
|
|
|
+ if column == "0":
|
|
|
pygame.draw.rect(
|
|
|
surface, (255,0,0),
|
|
|
(sx + j*BLOCK_SIZE, sy + i*BLOCK_SIZE,
|
|
|
@@ -72,14 +73,14 @@ def draw_game_state_to_window(surface, state):
|
|
|
surface.fill((0, 0, 0))
|
|
|
|
|
|
pygame.font.init()
|
|
|
- font = pygame.font.SysFont('comicsans', 60)
|
|
|
- label = font.render('Tetris', 1, (255, 255, 255))
|
|
|
+ font = pygame.font.SysFont(pygame.font.get_default_font(), 60)
|
|
|
+ label = font.render("Tetris", 1, (255, 255, 255))
|
|
|
surface.blit(label,
|
|
|
(TOP_LEFT_X + PLAY_WIDTH / 2 - (label.get_width() / 2), 30))
|
|
|
|
|
|
# current score
|
|
|
- font = pygame.font.SysFont('comicsans', 30)
|
|
|
- label = font.render(f'Score: {state.data.score}', 1, (255,255,255))
|
|
|
+ font = pygame.font.SysFont(pygame.font.get_default_font(), 30)
|
|
|
+ label = font.render(f"Score: {state.data.score}", 1, (255,255,255))
|
|
|
sx = TOP_LEFT_X + PLAY_WIDTH + 50
|
|
|
sy = TOP_LEFT_Y + PLAY_HEIGHT/2 - 100
|
|
|
surface.blit(label, (sx + 20, sy + 160))
|
|
|
@@ -228,30 +229,25 @@ def handle_get_game_state(state, millis_before_down):
|
|
|
return state, builder
|
|
|
|
|
|
|
|
|
-def main(win):
|
|
|
- run = True
|
|
|
+def game_loop(win, poller):
|
|
|
+ is_game_running = True
|
|
|
frame_time = 0
|
|
|
clock = pygame.time.Clock()
|
|
|
|
|
|
- zmq_context = zmq.Context()
|
|
|
- socket = zmq_context.socket(zmq.REP)
|
|
|
- socket.bind("tcp://*:5555")
|
|
|
- poller = zmq.Poller()
|
|
|
- poller.register(socket, zmq.POLLIN)
|
|
|
-
|
|
|
def _next_piece_func():
|
|
|
return random.choice(range(len(tetrominos.SHAPES)))
|
|
|
state = game_state.create_initial_game_state(_next_piece_func)
|
|
|
|
|
|
- while run:
|
|
|
+ while is_game_running:
|
|
|
clock.tick()
|
|
|
dt_millis = clock.get_time()
|
|
|
frame_time += dt_millis
|
|
|
|
|
|
for event in pygame.event.get():
|
|
|
+ if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
|
|
|
+ return None, False
|
|
|
if event.type == pygame.QUIT:
|
|
|
- run = False
|
|
|
- pygame.display.quit()
|
|
|
+ return None, False
|
|
|
|
|
|
for sock, _ in poller.poll(timeout=0):
|
|
|
req_buf = sock.recv()
|
|
|
@@ -274,9 +270,8 @@ def main(win):
|
|
|
else:
|
|
|
state, builder = handle_other(state)
|
|
|
|
|
|
- socket.send(builder.Output())
|
|
|
+ sock.send(builder.Output())
|
|
|
|
|
|
- is_game_running = True
|
|
|
if frame_time >= 500:
|
|
|
state, is_game_running = state.advance()
|
|
|
frame_time = 0
|
|
|
@@ -285,28 +280,81 @@ def main(win):
|
|
|
draw_next_shape(state.data.next_piece, win)
|
|
|
pygame.display.update()
|
|
|
|
|
|
- if not is_game_running:
|
|
|
- draw_text_middle(win, "YOU LOST!", 80, (255,255,255))
|
|
|
- pygame.display.update()
|
|
|
- pygame.time.delay(1500)
|
|
|
- run = False
|
|
|
+ return state, True
|
|
|
+
|
|
|
+
|
|
|
+def server_loop(win):
|
|
|
+ zmq_context = zmq.Context()
|
|
|
+ socket = zmq_context.socket(zmq.REP)
|
|
|
+ socket.bind("tcp://*:5555")
|
|
|
+ poller = zmq.Poller()
|
|
|
+ poller.register(socket, zmq.POLLIN)
|
|
|
|
|
|
+ state = None
|
|
|
|
|
|
-def main_menu(win):
|
|
|
run = True
|
|
|
+ is_game_over_sent = True
|
|
|
while run:
|
|
|
win.fill((0,0,0))
|
|
|
- draw_text_middle(win, 'Press Any Key To Play', 60, (255,255,255))
|
|
|
+ if state is None:
|
|
|
+ draw_text_middle(
|
|
|
+ win, "Waiting for connection.", 60, (255,255,255))
|
|
|
+ else:
|
|
|
+ draw_text_middle(
|
|
|
+ win,
|
|
|
+ f"Score = {state.data.score}. "
|
|
|
+ "Reconnect?", 60, (255,255,255))
|
|
|
+
|
|
|
pygame.display.update()
|
|
|
for event in pygame.event.get():
|
|
|
- if event.type == pygame.QUIT:
|
|
|
+ if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
|
|
|
+ run = False
|
|
|
+ elif event.type == pygame.QUIT:
|
|
|
run = False
|
|
|
- if event.type == pygame.KEYDOWN:
|
|
|
- main(win)
|
|
|
+
|
|
|
+ run_game_loop = False
|
|
|
+ for sock, _ in poller.poll(timeout=0):
|
|
|
+ req_buf = sock.recv()
|
|
|
+ req = wire_protocol.CommandRequest.CommandRequest.GetRootAs(req_buf)
|
|
|
+ builder = None
|
|
|
+
|
|
|
+ if req.Command() == wire_protocol.Command.Command.StartGame:
|
|
|
+ builder = flatbuffers.Builder()
|
|
|
+ wire_protocol.CommandResponse.Start(builder)
|
|
|
+ wire_protocol.CommandResponse.AddError(
|
|
|
+ builder, wire_protocol.CommandResponseError.CommandResponseError.OK)
|
|
|
+ rsp = wire_protocol.CommandResponse.End(builder)
|
|
|
+ builder.Finish(rsp)
|
|
|
+ sock.send(builder.Output())
|
|
|
+ run_game_loop = True
|
|
|
+ elif not is_game_over_sent:
|
|
|
+ is_game_over_sent = True
|
|
|
+
|
|
|
+ builder = flatbuffers.Builder()
|
|
|
+ wire_protocol.CommandResponse.Start(builder)
|
|
|
+ wire_protocol.CommandResponse.AddError(
|
|
|
+ builder,
|
|
|
+ wire_protocol.CommandResponseError.CommandResponseError.GAME_OVER)
|
|
|
+ rsp = wire_protocol.CommandResponse.End(builder)
|
|
|
+ builder.Finish(rsp)
|
|
|
+ sock.send(builder.Output())
|
|
|
+ else:
|
|
|
+ builder = flatbuffers.Builder()
|
|
|
+ wire_protocol.CommandResponse.Start(builder)
|
|
|
+ wire_protocol.CommandResponse.AddError(
|
|
|
+ builder,
|
|
|
+ wire_protocol.CommandResponseError.CommandResponseError.INVALID_COMMAND)
|
|
|
+ rsp = wire_protocol.CommandResponse.End(builder)
|
|
|
+ builder.Finish(rsp)
|
|
|
+ sock.send(builder.Output())
|
|
|
+
|
|
|
+ if run_game_loop:
|
|
|
+ state, run = game_loop(win, poller)
|
|
|
|
|
|
pygame.display.quit()
|
|
|
|
|
|
|
|
|
-win = pygame.display.set_mode((S_WIDTH, S_HEIGHT))
|
|
|
-pygame.display.set_caption('Tetris')
|
|
|
-main_menu(win)
|
|
|
+if __name__ == "__main__":
|
|
|
+ win = pygame.display.set_mode((S_WIDTH, S_HEIGHT))
|
|
|
+ pygame.display.set_caption("Tetris")
|
|
|
+ server_loop(win)
|