feat: complete connection scene

This commit is contained in:
2021-07-14 19:38:55 -04:00
parent 7820c21ff9
commit 6a0abfbadd
4 changed files with 84 additions and 8 deletions

View File

@@ -38,7 +38,7 @@ position:
# connection scene
game-id-label: [200, 300]
connecting-label: [280, 300]
waiting-opponent-label: [200, 300]
waiting-for-opponent-label: [200, 300]
# multi player game scene
well-player-1: [80, 80]
well-player-2: [480, 80]
@@ -61,6 +61,7 @@ engine:
cursor-blink-interval: 150
period-blink-interval: 300
lines-per-level: 55
ping-interval: 1500
# piece
piece-drop-delay: 600
piece-lock-delay: 1000

View File

@@ -342,6 +342,8 @@ class Stack(Entity):
vertex_four = (square[3][0] + (self._tile_size // 10), square[3][1] - (self._tile_size // 10))
new_square = (vertex_one, vertex_two, vertex_three, vertex_four)
pygame.draw.polygon(surface, pygame.Color(square_design.inner_color), new_square, max(self._tile_size // 6, 1))
# draw square glimmer
surface.set_at((square[0][0]+3, square[0][1]+3), pygame.Color(255, 255, 255))
surface.set_at((square[0][0]+4, square[0][1]+4), pygame.Color(255, 255, 255))
surface.set_at((square[0][0]+4, square[0][1]+5), pygame.Color(255, 255, 255))

View File

@@ -10,9 +10,14 @@ class MultiplayerService():
_thread = None
_receive_piece_queue = queue.Queue()
_send_piece_queue = queue.Queue()
_receive_message_queue = queue.Queue()
_send_message_queue = queue.Queue()
_current_game_id = None
_client_id = str(uuid.uuid4())
WAIT_FOR_OPPONENT = "wait_for_opponent"
START_GAME = "start_game"
@classmethod
def init(cls) -> None:
thread = Thread(target=asyncio.get_event_loop().run_until_complete,\
@@ -28,12 +33,28 @@ class MultiplayerService():
def send_piece(cls, piece: "PieceDto") -> None:
cls._send_piece_queue.put(piece)
@classmethod
def send_message(cls, message: str) -> None:
cls._send_message_queue.put(message)
@classmethod
def try_receive_piece(cls) -> "PieceDto":
if cls._receive_piece_queue.empty():
return None
result = cls._receive_piece_queue.get()
cls._receive_piece_queue.task_done()
return result
@classmethod
def try_receive_message(cls) -> str:
if cls._receive_message_queue.empty():
return None
result = cls._receive_message_queue.get()
cls._receive_message_queue.task_done()
return result
@classmethod
def quit(cls) -> None:
_NetworkConnectionService.close_connection()
@@ -61,6 +82,7 @@ class _NetworkConnectionService():
await cls._try_enter_game()
await cls._try_send_piece()
await cls._try_send_message()
await cls._try_receive_message()
# if conection is closed, exit loop
@@ -97,6 +119,18 @@ class _NetworkConnectionService():
await cls._websocket.send(json_message)
MultiplayerService._send_piece_queue.task_done()
@classmethod
async def _try_send_message(cls) -> None:
# if no messages to proccess, return
if MultiplayerService._send_message_queue.empty():
return
# get next message to send and send to server
message = MultiplayerService._send_message_queue.get()
await cls._websocket.send(message)
MultiplayerService._send_message_queue.task_done()
@classmethod
async def _try_receive_message(cls) -> None:
try:
@@ -104,13 +138,19 @@ class _NetworkConnectionService():
done, pending = await asyncio.wait({task}, timeout=8e-3) # TODO experiment with the timeout
if task in done:
data = json.loads(await task)
json_str = await task
if json_str == "pong":
print("pong")
cls._pending_receive_task = None
return
data = json.loads(json_str)
print(data)
if data["type"] == "wait_for_opponent":
print("Wait for my opponent!")
MultiplayerService._receive_message_queue.put(MultiplayerService.WAIT_FOR_OPPONENT)
if data["type"] == "start_game":
print("Start the game!")
MultiplayerService._receive_message_queue.put(MultiplayerService.START_GAME)
if data["type"] == "receive_piece":
print("Receive a piece!")
MultiplayerService._receive_piece_queue.put(PieceDto.create(data["piece"]))

View File

@@ -170,6 +170,7 @@ class ConnectionScene(Scene):
def __init__(self, change_scene: FunctionType) -> None:
self._background_color = pygame.Color(ConfigurationManager.get("color", "window-bg"))
self._is_connecting = False
self._waiting_for_opponent = False
self._game_id_label_pos = ConfigurationManager.get("position", "game-id-label")
self._game_id_label = "Enter Game Id: "
self._game_id = "_"
@@ -177,16 +178,24 @@ class ConnectionScene(Scene):
self._cursor_blink_acc = 0 # blink accumulator
self._connecting_label_pos = ConfigurationManager.get("position", "connecting-label")
self._connecting_label = "Connecting"
self._waiting_for_opponent_label_pos = ConfigurationManager.get("position", "waiting-for-opponent-label")
self._waiting_for_opponent_label = "Waiting for opponent"
self._period_blink_interval = ConfigurationManager.get("engine", "period-blink-interval")
self._period_blink_acc = 0 # period accumulator
self._ping_interval = ConfigurationManager.get("engine", "ping-interval")
self._ping_acc = 0 # ping accumulator
self._change_scene = change_scene
def draw(self, surface: pygame.Surface) -> None:
surface.fill(self._background_color)
if not self._is_connecting:
if not self._is_connecting and not self._waiting_for_opponent:
TextGenerator.draw(self._game_id_label + self._game_id, self._game_id_label_pos, surface)
else:
elif self._is_connecting and not self._waiting_for_opponent:
TextGenerator.draw(self._connecting_label, self._connecting_label_pos, surface)
else:
TextGenerator.draw(self._waiting_for_opponent_label, self._waiting_for_opponent_label_pos, surface)
def update(self, elapsed_time: int) -> None:
# cursor blink logic
@@ -198,8 +207,8 @@ class ConnectionScene(Scene):
else:
self._game_id += "_"
# period ellipsis logic
if self._is_connecting:
# period ellipsis logic for connecting
if self._is_connecting and not self._waiting_for_opponent:
self._period_blink_acc += elapsed_time
if self._period_blink_acc >= self._period_blink_interval:
self._period_blink_acc = 0
@@ -209,6 +218,17 @@ class ConnectionScene(Scene):
else:
self._connecting_label = self._connecting_label.replace(".", "")
# period ellipsis logic for waiting on opponent
if self._waiting_for_opponent:
self._period_blink_acc += elapsed_time
if self._period_blink_acc >= self._period_blink_interval:
self._period_blink_acc = 0
period_count = self._waiting_for_opponent_label.count(".")
if period_count < self.MAX_PERIOD_COUNT:
self._waiting_for_opponent_label += "."
else:
self._waiting_for_opponent_label = self._waiting_for_opponent_label.replace(".", "")
# keyboard input
for event in pygame.event.get(pygame.KEYDOWN):
# user input logic
@@ -225,6 +245,19 @@ class ConnectionScene(Scene):
self._is_connecting = True
MultiplayerService.init()
MultiplayerService.enter_game(self._game_id)
# server messaging logic
self._ping_acc += elapsed_time
message = MultiplayerService.try_receive_message();
if message: # TODO remove later, only for testing
print(message)
if message == MultiplayerService.WAIT_FOR_OPPONENT:
self._waiting_for_opponent = True
if message == MultiplayerService.START_GAME:
self._change_scene(MultiplayerScene(self._change_scene))
if message is None and self._ping_acc >= self._ping_interval:
self._ping_acc = 0
MultiplayerService.send_message("ping")
"""
TODO
"""