Updates only changed tiles

Before this, after each move, the whole maze was redrawed to update
display. Now it draws only the changed tiles (current/old player
position). Changed tiles are stocked in a list, for future needs,
others changed tiles can be add here.

TODO keep maze.string updated
This commit is contained in:
Fred Z 2018-04-10 15:40:00 +02:00
parent 69be4c1753
commit eb68f7c04d
3 changed files with 49 additions and 19 deletions

29
gui.py
View File

@ -76,3 +76,32 @@ class GraphUI:
self.SURFACE.blit(h_title, (0, 0))
self.SURFACE.blit(h_status, (0, CELL_SIZE))
self.SURFACE.blit(h_items, h_items_pos)
def update(self, player):
"""
Updates GUI after a move
:param obj player: a Player object
"""
changed_tiles = [
(elmt_val('tile', 'symbol', player.ground, 0), player.old_position),
(elmt_val('tile', 'name', 'player', 0), player.current_position),
]
# [print('tile[0]:{} tile[1]:{}'.format(tile[0], tile[1])) for num, tile in enumerate(changed_tiles) if tile[0] is not False]
[self.blit(tile[0], self.coord_from_index(tile[1])) for num, tile in enumerate(changed_tiles) if False not in tile]
# Refresh
pygame.display.flip()
def coord_from_index(self, idx):
"""
Gets 2 dimensions coordinates
Converts a string index (the position in the maze.string: beware of EOL) to 2 dimensions coordinates (necessary for positionning objects in pygame)
:param int index: string index
"""
x = (idx % (MAZE_SIZE + 1)) * CELL_SIZE
y = (idx // (MAZE_SIZE + 1)) * CELL_SIZE + HEAD_SIZE_H
return (x, y)

View File

@ -29,11 +29,12 @@ game_maze = Maze(MAZE_FILE)
if game_maze.status:
macgyver = Player(game_maze)
gui = GraphUI()
# TODO include set_header() in draw()
gui.set_header(macgyver.status_message)
gui.draw(game_maze)
# game loop
while game_maze.status:
gui.set_header(macgyver.status_message)
gui.draw(game_maze)
for event in pygame.event.get():
if event.type == QUIT:
game_maze.status = False
@ -43,11 +44,14 @@ while game_maze.status:
last_message = True # executes last_message loop
if event.key in GAME_KEYS:
macgyver.key_event(event.key)
gui.set_header(macgyver.status_message)
gui.update(macgyver)
else:
macgyver.status_message['status'] = MSG_QUIT
game_maze.status = False
# displays the last_message (won, lost or quit)
while last_message:
macgyver.status_message['title'] = MSG_END

View File

@ -24,9 +24,11 @@ class Player:
:param obj maze: Maze object
"""
self.maze = maze
self.position = maze.string.find(
self.current_position = maze.string.find(
elmt_val('symbol', 'name', 'player', 0)
)
self.old_position = 0
# Element under player, default 'floor'
self.ground = elmt_val('symbol', 'name', 'floor', 0)
@ -49,16 +51,16 @@ class Player:
:param int pressed_key: direction (pygame const)
"""
if pressed_key == K_UP:
self.move_to(self.position - self.maze.COL_NB)
self.move_to(self.current_position - self.maze.COL_NB)
elif pressed_key == K_DOWN:
self.move_to(self.position + self.maze.COL_NB)
self.move_to(self.current_position + self.maze.COL_NB)
elif pressed_key == K_RIGHT:
self.move_to(self.position + 1)
self.move_to(self.current_position + 1)
elif pressed_key == K_LEFT:
self.move_to(self.position - 1)
self.move_to(self.current_position - 1)
# ++Add other treatment for key events here (help, menu, etc.)++
@ -80,14 +82,16 @@ class Player:
if next_position in self.maze.RANGE:
next_symbol = self.maze.string[next_position]
self.old_position = self.current_position
# 'floor' element
if next_symbol == elmt_val('symbol', 'name', 'floor', 0):
self.position = next_position
self.current_position = next_position
self.status_message['status'] = MSG_OK
# 'item' element
elif next_symbol in elmt_val('symbol', 'item', True):
self.position = next_position
self.current_position = next_position
self.stock.append(
elmt_val('name', 'symbol', next_symbol, 0)
)
@ -121,17 +125,10 @@ class Player:
# for all other element (wall or nline)
else:
self.status_message['status'] = MSG_WALL
self.old_position = False
# out the string range
else:
self.status_message['status'] = MSG_WALL
# Replaces player symbol on the maze by 'ground' value
self.maze.string = self.maze.string.replace(
elmt_val('symbol', 'name', 'player', 0), self.ground
)
# Sets the player's new position
self.maze.set_symbol(
elmt_val('symbol', 'name', 'player', 0), self.position
)
self.old_position = False