about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorNguyễn Gia Phong <vn.mcsinyx@gmail.com>2018-02-27 22:25:58 +0700
committerNguyễn Gia Phong <vn.mcsinyx@gmail.com>2018-02-27 22:25:58 +0700
commit781b347fcb96b72c46bbbe2878d499a19926fd18 (patch)
tree694d780ca4b4df53327eab75f4a8496c5f9678e8
parent0cfeaf9cab423d9662f621215b2ebcaa69b13ef8 (diff)
downloadbrutalmaze-781b347fcb96b72c46bbbe2878d499a19926fd18.tar.gz
Make remote control sticky and revise headless server
-rw-r--r--brutalmaze/characters.py8
-rw-r--r--brutalmaze/main.py37
-rw-r--r--brutalmaze/maze.py14
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