From 5d0c2b6e0cc1e42281dc93919b3c04657b621313 Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 16 Apr 2013 18:08:08 +0200 Subject: [PATCH] "better" auto-scrolling support --- erdslangetjie/__main__.py | 88 ++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 28 deletions(-) diff --git a/erdslangetjie/__main__.py b/erdslangetjie/__main__.py index 6ab5b18..148236b 100644 --- a/erdslangetjie/__main__.py +++ b/erdslangetjie/__main__.py @@ -30,9 +30,12 @@ class GameWindow(RelativeLayout): cols, rows = self.level_obj.get_size() super(GameWindow, self).__init__( - size=(cols*TILE_SIZE, rows*TILE_SIZE), + size=(cols * TILE_SIZE, rows * TILE_SIZE), 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() @@ -68,9 +71,6 @@ class GameWindow(RelativeLayout): 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) @@ -83,34 +83,58 @@ class GameWindow(RelativeLayout): 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 - if point[0] >= self.view.pos[0] - TILE_SIZE: + if point[0] >= self.view.size[0] - margin: return False - if point[1] < TILE_SIZE: + if point[1] < margin: return False - if point[1] >= self.view.pos[1] - TILE_SIZE: + if point[1] >= self.view.size[1] - margin: return False + return True def draw_nemesis(self): if not self.nemesis.on_board(): @@ -155,12 +179,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() + 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.view.scroll_x = 0 + self.view.scroll_y = 0 self.build() + self.draw_nemesis() + self.draw_player() else: print 'You won!' sys.exit(1) @@ -205,7 +234,10 @@ class GameApp(App): game.build() root.add_widget(game) # Ensure the player is visible + root.scroll_x = 0 + root.scroll_y = 0 game.draw_player() + game.draw_nemesis() return root -- 2.34.1