From 781b347fcb96b72c46bbbe2878d499a19926fd18 Mon Sep 17 00:00:00 2001 From: Nguyễn Gia Phong Date: Tue, 27 Feb 2018 22:25:58 +0700 Subject: Make remote control sticky and revise headless server --- brutalmaze/characters.py | 8 ++++---- brutalmaze/main.py | 37 ++++++++++++++++++++++--------------- brutalmaze/maze.py | 14 ++++++++------ 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/brutalmaze/characters.py b/brutalmaze/characters.py index e72fd91..9a53a8f 100644 --- a/brutalmaze/characters.py +++ b/brutalmaze/characters.py @@ -51,9 +51,9 @@ class Hero: wound (float): amount of wound sfx_heart (pygame.mixer.Sound): heart beat sound effect """ - def __init__(self, surface, fps): + def __init__(self, surface, fps, maze_size): self.surface = surface - w, h = self.surface.get_width(), self.surface.get_height() + w, h = maze_size self.x, self.y = w >> 1, h >> 1 self.angle, self.color = pi / 4, TANGO['Aluminium'] self.R = (w * h / sin(pi*2/3) / 624) ** 0.5 @@ -99,9 +99,9 @@ class Hero: trigon = regpoly(sides, self.R, self.angle, self.x, self.y) fill_aapolygon(self.surface, trigon, self.color[int(self.wound)]) - def resize(self): + def resize(self, maze_size): """Resize the hero.""" - w, h = self.surface.get_width(), self.surface.get_height() + w, h = maze_size self.x, self.y = w >> 1, h >> 1 self.R = (w * h / sin(pi*2/3) / 624) ** 0.5 diff --git a/brutalmaze/main.py b/brutalmaze/main.py index 3236337..1da8056 100644 --- a/brutalmaze/main.py +++ b/brutalmaze/main.py @@ -124,8 +124,9 @@ class Game: self.server.listen(1) print('Socket server is listening on {}:{}'.format(config.host, config.port)) + self.sockinp = 0, 0, 225, 0, 0 # freeze and point to NW else: - self.server = None + self.server = self.sockinp = None self.headless = config.headless # self.fps is a float to make sure floordiv won't be used in Python 2 @@ -174,7 +175,7 @@ class Game: for row in walls)) x, y = self.expos(maze.x, maze.y) lines.appendleft('{} {} {} {} {} {} {:.0f} {:d} {:d}'.format( - len(walls), ne, nb, maze.get_score(), x, y, hero.wound * 100, + len(walls), ne, nb, maze.get_score(), x, y, hero.wound, hero.next_strike <= tick, hero.next_heal <= tick)) return '\n'.join(lines).encode() @@ -183,15 +184,6 @@ class Game: Return False if QUIT event is captured, True otherwise. """ - # Compare current FPS with the average of the last 10 frames - new_fps = self.clock.get_fps() - if new_fps < self.fps: - self.fps -= 1 - elif self.fps < self.max_fps and not self.paused: - self.fps += 5 - if not self.paused: self.maze.update(self.fps) - - self.clock.tick(self.fps) events = pygame.fastevent.get() for event in events: if event.type == QUIT: @@ -211,7 +203,16 @@ class Game: pygame.mixer.music.play(-1) else: pygame.mixer.quit() + + # Compare current FPS with the average of the last 10 frames + new_fps = self.clock.get_fps() + if new_fps < self.fps: + self.fps -= 1 + elif self.fps < self.max_fps and not self.paused: + self.fps += 5 + if not self.paused: self.maze.update(self.fps) if not self.headless: self.maze.draw() + self.clock.tick(self.fps) return True def move(self, x, y): @@ -251,20 +252,26 @@ class Game: This function is supposed to be run in a Thread. """ + clock = Clock() while True: connection, address = self.server.accept() print('Connected to {}:{}'.format(*address)) self.maze.reinit() while not self.hero.dead: data = self.export() - connection.send('{:06}'.format(len(data)).encode()) + connection.send('{:08}'.format(len(data)).encode()) connection.send(data) - buf = connection.recv(8) + try: + buf = connection.recv(8) + except: # client is likely to be closed + break if not buf: break move, angle, attack = (int(i) for i in buf.decode().split()) y, x = (i - 1 for i in divmod(move, 3)) - self.control(x, y, radians(angle), attack & 1, attack >> 1) + self.sockinp = x, y, radians(angle), attack & 1, attack >> 1 + clock.tick(self.fps) self.maze.lose() + self.sockinp = 0, 0, 225, 0, 0 print('{1}:{2} scored {0} points'.format( self.maze.get_score(), *address)) connection.close() @@ -355,6 +362,6 @@ def main(): socket_thread = Thread(target=game.remote_control) socket_thread.daemon = True # make it disposable socket_thread.start() - while game.update(): pass + while game.update(): game.control(*game.sockinp) else: while game.update(): game.user_control() diff --git a/brutalmaze/maze.py b/brutalmaze/maze.py index 6c5052c..ee3f82d 100644 --- a/brutalmaze/maze.py +++ b/brutalmaze/maze.py @@ -78,11 +78,13 @@ class Maze: sfx_slash (pygame.mixer.Sound): sound effect of slashed enemy sfx_lose (pygame.mixer.Sound): sound effect to be played when you lose """ - def __init__(self, fps, size, scrtype, headless=False): + def __init__(self, fps, size, scrtype, headless): self.fps = fps - if not headless: - self.w, self.h = size - self.scrtype = scrtype + self.w, self.h = size + self.scrtype = scrtype + if headless: + self.surface = None + else: self.surface = pygame.display.set_mode(size, self.scrtype) self.distance = (self.w * self.h / 416) ** 0.5 @@ -100,7 +102,7 @@ class Maze: self.bullets, self.enemies = [], [] self.enemy_weights = {color: MINW for color in ENEMIES} self.add_enemy() - self.hero = Hero(self.surface, fps) + self.hero = Hero(self.surface, fps, size) self.map[MIDDLE][MIDDLE] = HERO self.next_move = self.next_slashfx = 0 self.slashd = self.hero.R + self.distance/SQRT2 @@ -327,7 +329,7 @@ class Maze: """Resize the maze.""" self.w, self.h = size self.surface = pygame.display.set_mode(size, self.scrtype) - self.hero.resize() + self.hero.resize(size) offsetx = (self.centerx-self.x) / self.distance offsety = (self.centery-self.y) / self.distance -- cgit 1.4.1