我正在尝试使用位图在迷宫中移动角色。我对python的了解还不是很好,所以我不知道这是否显而易见。
代码如下:
# the code that works
def movePlayerRight(self):
next_tile_x = self.player_tile_x + 1
if next_tile_x > NUM_TILE_ROWS:
return
elif self.bitmap[self.player_tile_y][next_tile_x] == -1:
return
else:
self.player_tile_x = next_tile_x
# the code that doesn't
def movePlayerUp(self):
next_tile_y = self.player_tile_y - 1
if next_tile_y < 0:
return
elif self.bitmap[self.player_tile_x][next_tile_y] == 1:
return
除了这里,我想不出一种在线搜索的方法?
编辑:我把它放进去了,但是角色正在穿过墙壁,并且在某些时候说索引超出了范围?
还有一个人说他们想查看整个代码,所以:
import pygame
WHITE = ((255,255,255))
BLACK = ((0,0,0))
RED = ((255,0,0))
BLUE = ((0,0,255))
DISPLAY_HEIGHT = 600
DISPLAY_WIDTH = 800
map_bitmap = [[ 1, 1 , 1, 1, 1, 1, 1, 1],
[ 1, 1 , 0, 0, 0, 0, 0, 1],
[ 1, 1 , 1, 0, 1, 0, 0, 1],
[ 1, 0 , 0, 0, 0, 0, 0, 1],
[ 1, 0 , 0, 0, 0, 0, 0, 1],
[ 1, 1 , 1, 1, 1, 1, 1, 1]]
# These start at 0. So if there's 11 columns, it's 0 to 10
MAP_START_TILE_X = 3
MAP_START_TILE_Y = 4
MAP_END_TILE_X = 0
MAP_END_TILE_Y = 2
# Number of tiles per row/column we have
NUM_TILE_COLUMNS = len(map_bitmap[0])
NUM_TILE_ROWS = len(map_bitmap)
# Determines in pixels how wide/tall our tiles are
TILE_WIDTH = int(DISPLAY_WIDTH / NUM_TILE_COLUMNS)
TILE_HEIGHT = int(DISPLAY_HEIGHT / NUM_TILE_ROWS)
# This function is going to draw a bitmap to a surface
def draw_map(surface, bitmap):
# Loop through all indexes in our Y coordinate
for y in range(NUM_TILE_ROWS):
# Each list in this list represents a row
row = bitmap[y]
# Loop through all indexes in our X coordinate
for x in range(NUM_TILE_COLUMNS):
draw_tile = bitmap[y][x]
# If the tile value is 1, we have a wall. Draw a rectangle
if draw_tile == 1:
# render a rectangle
# Rect(left, top, width, height) -> Rect
wall_tile = pygame.Rect(TILE_WIDTH * x, TILE_HEIGHT * y, TILE_WIDTH, TILE_HEIGHT)
pygame.draw.rect(surface, BLACK, wall_tile)
# This function takes a surface and an X/Y coord and draws a red rectangle
# This rectangle represents our player.
# TODO: Figure out how to blit an image instead
def draw_player(surface, tile_x, tile_y):
# Translate tiles to pixels to draw our rectangle
player_tile = pygame.Rect(TILE_WIDTH * tile_x, TILE_HEIGHT * tile_y, TILE_WIDTH, TILE_HEIGHT)
# Draw the tile. Right now
pygame.draw.rect(surface, RED, player_tile)
def draw_fog_of_war(surface, tile_x, tile_y, radius):
# Define some new colors
TRANSPARENT = (0,0,255,0)
GREY = (220,220,220,255)
# Build our overlay surface
overlay_surface = pygame.Surface((DISPLAY_WIDTH, DISPLAY_HEIGHT), pygame.SRCALPHA)
overlay_surface.fill(GREY)
# Convert from tile position to pixels
# Note that we need to consider the CENTER of the tile, not the top-left
center_x = (tile_x * TILE_WIDTH) + (int(TILE_WIDTH / 2))
center_y = (tile_y * TILE_HEIGHT) + (int(TILE_HEIGHT / 2))
center = (center_x, center_y)
# Draw transparent circle on overlay surface
pygame.draw.circle(overlay_surface, TRANSPARENT, center, radius)
# Cover original surface with overlay surface
# blit(source, dest, area=None, special_flags=0) -> Rect
surface.blit(overlay_surface, (0,0))
# Notes:
# Don't forget "self" :)
# Methods (class functions) serve as was to change/get information about the object
# All methods have AT LEAST one parameter: self
# __init__ is called implicitly during instantiation. This is where you configure your object's attributes (class variables)
# Don't forget "self" :)
class Maze:
surface = None
bitmap = []
player_tile_x = -1
player_tile_y = -1
end_tile_x = 4
end_tile_y = 0
def __init__(self, surface, bitmap, start_tile_x, start_tile_y, end_tile_x, end_tile_y):
self.surface = surface
self.bitmap = bitmap
self.player_tile_x = start_tile_x
self.player_tile_y = start_tile_y
self.end_tile_x = end_tile_x
self.end_tile_y = end_tile_y
print("Player at: (%d, %d)" % (self.player_tile_x, self.player_tile_y))
def render(self):
# Recreate our world
self.surface.fill(WHITE)
draw_map(self.surface, self.bitmap)
draw_player(self.surface, self.player_tile_x, self.player_tile_y)
# Kinda arbitrarily setting radius, adjust as needed
radius = TILE_WIDTH * 2
# NOTE: Comment out the draw_fog_of_war to disable this
# Useful when you need to look at the whole map
draw_fog_of_war(self.surface, self.player_tile_x, self.player_tile_y, radius)
def movePlayerLeft(self):
# Shifting left means subtracting X coord by 1
next_tile_x = self.player_tile_x - 1
# Check to see if we run off the map
if next_tile_x < 0:
# Do nothing, return
return
# Check to see if we bump into a tile occupied by a wall
elif self.bitmap[self.player_tile_y][next_tile_x] == 1:
# Do nothing, return
return
# Should be an empty, available tile to move into
else:
# Update our player's X coord position
self.player_tile_x = next_tile_x
def movePlayerRight(self):
next_tile_x = self.player_tile_x + 1
if next_tile_x > NUM_TILE_ROWS:
return
elif self.bitmap[self.player_tile_y][next_tile_x] == -1:
return
else:
self.player_tile_x = next_tile_x
def movePlayerUp(self):
next_tile_y = self.player_tile_y - 1
if next_tile_y < 0:
return
elif self.bitmap[self.player_tile_x][next_tile_y] == -1:
return
else:
self.player_tile_y = next_tile_y
def movePlayerDown(self):
next_tile_y = self.player_tile_y + 1
if next_tile_y > NUM_TILE_COLUMNS:
return
elif self.bitmap[self.player_tile_y][next_tile_y] == 1:
return
else:
self.player_tile_y = next_tile_y
# How we can determine if a player has reached the file tile
def isPlayerAtEnd(self):
if (self.player_tile_x == self.end_tile_x) and (self.player_tile_y == self.end_tile_y):
return True
else:
return False
def main():
# Initialize the module
pygame.init()
# Create a display, returns the default surface to draw on which matches
# the defined resolution
surface = pygame.display.set_mode((DISPLAY_WIDTH,DISPLAY_HEIGHT))
# Create our maze
# __init__(self, surface, bitmap, start_tile_x, start_tile_y, end_tile_x, end_tile_y):
maze = Maze(surface, map_bitmap, MAP_START_TILE_X, MAP_START_TILE_Y, MAP_END_TILE_X, MAP_END_TILE_Y)
# Render the objects onto the surface
maze.render()
# Update the display
pygame.display.update()
running = True
while running:
# Wait for an event. This is different then the timer method
# We are not updating anything until an event is triggered
event = pygame.event.wait()
print(event)
if event.type == pygame.QUIT:
running = False
# Check all key press events.
# Only left movement is implemented right now
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_LEFT:
maze.movePlayerLeft()
elif event.key == pygame.K_RIGHT:
maze.movePlayerRight()
elif event.key == pygame.K_UP:
maze.movePlayerUp()
elif event.key == pygame.K_DOWN:
maze.movePlayerDown()
# Re-render our world
maze.render()
# Update the display
pygame.display.update()
# Did we win? For now, we'll just quit
# TODO: do something more elegant here
if maze.isPlayerAtEnd():
# We won! Exit
running = False
if __name__ == "__main__":
main()
pygame.quit()
quit()
答案 0 :(得分:0)
您在else
函数中缺少movePlayerUp
语句。
def movePlayerUp(self):
next_tile_y = self.player_tile_y - 1
if next_tile_y < 0:
return
elif self.bitmap[self.player_tile_x][next_tile_y] == 1:
return
else:
self.player_tile_y = next_tile_y