Force main app to respect the configured window size
[erdslangetjie.git] / erdslangetjie / __main__.py
index 3234d1b2dab8242b954c5517729ccbcc83762797..95fdf1be5d3423a6e41fc20c63dd412af89e7d16 100644 (file)
@@ -5,8 +5,8 @@ import pygame
 kivy.require('1.6.0')
 
 from kivy.app import App
 kivy.require('1.6.0')
 
 from kivy.app import App
-from kivy.core.window import Window
 from kivy.uix.widget import Widget
 from kivy.uix.widget import Widget
+from kivy.logger import Logger, LoggerHistory
 from kivy.uix.relativelayout import RelativeLayout
 from kivy.uix.scrollview import ScrollView
 from kivy.graphics import Color, Rectangle
 from kivy.uix.relativelayout import RelativeLayout
 from kivy.uix.scrollview import ScrollView
 from kivy.graphics import Color, Rectangle
@@ -14,8 +14,7 @@ from kivy.utils import platform
 
 from erdslangetjie.level import LevelList
 from erdslangetjie.player import ThePlayer, Nemesis
 
 from erdslangetjie.level import LevelList
 from erdslangetjie.player import ThePlayer, Nemesis
-
-TILE_SIZE = 40
+from erdslangetjie.constants import TILE_SIZE, QUIET
 
 
 class GameWindow(RelativeLayout):
 
 
 class GameWindow(RelativeLayout):
@@ -27,12 +26,15 @@ class GameWindow(RelativeLayout):
         self.tiles = {}
         self.view = view
 
         self.tiles = {}
         self.view = view
 
-        rows, cols = self.level_obj.get_size()
+        cols, rows = self.level_obj.get_size()
 
         super(GameWindow, self).__init__(
 
         super(GameWindow, self).__init__(
-                size=(cols*TILE_SIZE, rows*TILE_SIZE),
+                size=(cols * TILE_SIZE, rows * TILE_SIZE),
                 size_hint=(None, None))
 
                 size_hint=(None, None))
 
+        self.x_scroll_margin = float(TILE_SIZE) / self.view.size[0]
+        self.y_scroll_margin = float(TILE_SIZE) / self.view.size[1]
+
         self.mouse_move = False
 
         self.player = ThePlayer()
         self.mouse_move = False
 
         self.player = ThePlayer()
@@ -45,6 +47,9 @@ class GameWindow(RelativeLayout):
         self.player.pos = self.level_obj.enter_pos
         if platform() != 'android':
             # Very hack'ish
         self.player.pos = self.level_obj.enter_pos
         if platform() != 'android':
             # Very hack'ish
+            # We need to delay this import until after the window creation by
+            # the app, else our size config doesn't work
+            from kivy.core.window import Window
             self.keyboard = Window.request_keyboard(self._closed, self)
             self.keyboard.bind(on_key_down=self._on_key_down)
 
             self.keyboard = Window.request_keyboard(self._closed, self)
             self.keyboard.bind(on_key_down=self._on_key_down)
 
@@ -68,9 +73,6 @@ class GameWindow(RelativeLayout):
                 bx += TILE_SIZE
             by += TILE_SIZE
 
                 bx += TILE_SIZE
             by += TILE_SIZE
 
-        self.draw_player()
-        self.draw_nemesis()
-
     def draw_player(self):
         if self.player_tile:
             self.remove_widget(self.player_tile)
     def draw_player(self):
         if self.player_tile:
             self.remove_widget(self.player_tile)
@@ -83,34 +85,58 @@ class GameWindow(RelativeLayout):
             Rectangle(pos=sprite_pos, size=self.player_tile.size,
                     texture=self.player.get_texture())
         self.add_widget(self.player_tile)
             Rectangle(pos=sprite_pos, size=self.player_tile.size,
                     texture=self.player.get_texture())
         self.add_widget(self.player_tile)
-        # Player position in viewpoint coordinates
-        check_point = (sprite_pos[0] + TILE_SIZE / 2,
-                sprite_pos[1] + TILE_SIZE / 2)
-        true_point = self.to_parent(*check_point)
-        if not self.included(true_point):
-            # Scroll ourselves
-            while true_point[0] >= self.view.size[0] - TILE_SIZE:
-                self.pos = (self.pos[0] - 1.5 * TILE_SIZE, self.pos[1])
-                true_point = self.to_parent(*check_point)
-            while true_point[0] < TILE_SIZE:
-                self.pos = (self.pos[0] + 1.5 * TILE_SIZE, self.pos[1])
-                true_point = self.to_parent(*check_point)
-            while true_point[1] >= self.view.size[1] - TILE_SIZE:
-                self.pos = (self.pos[0], self.pos[1] - 1.5 * TILE_SIZE)
-                true_point = self.to_parent(*check_point)
-            while true_point[1] < TILE_SIZE:
-                self.pos = (self.pos[0], self.pos[1] + 1.5 * TILE_SIZE)
-                true_point = self.to_parent(*check_point)
-
-    def included(self, point):
-        if point[0] < TILE_SIZE:
+        for offset in [(TILE_SIZE - 1, TILE_SIZE - 1),
+                (-TILE_SIZE + 1, TILE_SIZE - 1),
+                (TILE_SIZE - 1, -TILE_SIZE + 1),
+                (-TILE_SIZE + 1, -TILE_SIZE + 1),
+                (0, 2 * TILE_SIZE - 2),
+                (-2 * TILE_SIZE + 2, 0),
+                (2 * TILE_SIZE - 2, 0),
+                (0, -2 * TILE_SIZE + 2),
+                (0, 0)]:
+            # Aim is to ensure a 'neighbourhood' around the player
+            # is visible if possible
+            check_point = (sprite_pos[0] + offset[0] + TILE_SIZE / 2,
+                    sprite_pos[1] + offset[1] + TILE_SIZE / 2)
+            true_point = self.to_parent(*check_point)
+            if check_point[0] < 0:
+                continue
+            if check_point[1] < 0:
+                continue
+            if check_point[0] >= self.size[0]:
+                continue
+            if check_point[1] >= self.size[1]:
+                continue
+            while not self.included(true_point, 0):
+                # Scroll ourselves
+                if true_point[0] >= self.view.size[0]:
+                    self.view.scroll_x += self.x_scroll_margin
+                    true_point = self.to_parent(*check_point)
+                    #print '-x', self.view.scroll_x, self.view.scroll_y
+                elif true_point[0] < 0:
+                    self.view.scroll_x -= self.x_scroll_margin
+                    true_point = self.to_parent(*check_point)
+                    #print '+x', self.view.scroll_x, self.view.scroll_y
+                elif true_point[1] >= self.view.size[1]:
+                    self.view.scroll_y += self.y_scroll_margin
+                    true_point = self.to_parent(*check_point)
+                    #print '+y', self.view.scroll_x, self.view.scroll_y
+                elif true_point[1] < 0:
+                    self.view.scroll_y -= self.y_scroll_margin
+                    true_point = self.to_parent(*check_point)
+                    #print '-y', self.view.scroll_x, self.view.scroll_y
+                #print true_point, self.view.size
+
+    def included(self, point, margin):
+        if point[0] < margin:
             return False
             return False
-        if point[0] >= self.view.pos[0] - TILE_SIZE:
+        if point[0] >= self.view.size[0] - margin:
             return False
             return False
-        if point[1] < TILE_SIZE:
+        if point[1] < margin:
             return False
             return False
-        if point[1] >= self.view.pos[1] - TILE_SIZE:
+        if point[1] >= self.view.size[1] - margin:
             return False
             return False
+        return True
 
     def draw_nemesis(self):
         if not self.nemesis.on_board():
 
     def draw_nemesis(self):
         if not self.nemesis.on_board():
@@ -155,12 +181,17 @@ class GameWindow(RelativeLayout):
         if self.level_obj.at_exit(self.player.pos):
             # Jump to next level
             self.level_obj = self.level_list.advance_to_next_level()
         if self.level_obj.at_exit(self.player.pos):
             # Jump to next level
             self.level_obj = self.level_list.advance_to_next_level()
+            self.remove_widget(self.nemesis_tile)
             self.nemesis.reset_pos()
             if self.level_obj:
                 self.level_obj.load_tiles()
                 self.player.pos = self.level_obj.enter_pos
                 self.remove_widget(self.player_tile)
             self.nemesis.reset_pos()
             if self.level_obj:
                 self.level_obj.load_tiles()
                 self.player.pos = self.level_obj.enter_pos
                 self.remove_widget(self.player_tile)
+                self.view.scroll_x = 0
+                self.view.scroll_y = 0
                 self.build()
                 self.build()
+                self.draw_nemesis()
+                self.draw_player()
             else:
                 print 'You won!'
                 sys.exit(1)
             else:
                 print 'You won!'
                 sys.exit(1)
@@ -195,21 +226,37 @@ class GameWindow(RelativeLayout):
 
 class GameApp(App):
 
 
 class GameApp(App):
 
+    title = "Peter's thread snake"
+
     def __init__(self):
         self.levels = LevelList()
         super(GameApp, self).__init__()
 
     def build(self):
     def __init__(self):
         self.levels = LevelList()
         super(GameApp, self).__init__()
 
     def build(self):
-        root = ScrollView(size=(640, 480), size_hint=(None, None))
-        game = GameWindow(self.levels, root)
+        root = ScrollView(size_hint=(None, None))
+        return root
+
+    def on_start(self):
+        from kivy.base import EventLoop
+        window = EventLoop.window
+        if platform() == 'android':
+            window.fullscreen = True
+        self.root.size = window.size
+        game = GameWindow(self.levels, self.root)
         game.build()
         game.build()
-        root.add_widget(game)
+        self.root.add_widget(game)
         # Ensure the player is visible
         # Ensure the player is visible
+        self.root.scroll_x = 0
+        self.root.scroll_y = 0
         game.draw_player()
         game.draw_player()
-        return root
+        game.draw_nemesis()
 
 
 def main():
     """ Erdslangetjie, a maze game of eluding nemesis
     """
 
 
 def main():
     """ Erdslangetjie, a maze game of eluding nemesis
     """
+    if QUIET:
+        for hdlr in Logger.handlers[:]:
+            if not isinstance(hdlr, LoggerHistory):
+                Logger.removeHandler(hdlr)
     GameApp().run()
     GameApp().run()