如何在python 3中的y轴上移动播放器?

时间:2019-11-25 18:51:20

标签: python bitmap yaxis

我正在尝试使用位图在迷宫中移动角色。我对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()

1 个答案:

答案 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