简体   繁体   中英

How do I move player on y axis in python 3?

I'm trying to move my character through a maze using bitmap. I'm not very good with python yet, so I don't know if this is obvious or not.

The code looks like this:

# 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

I couldn't think of a way to search this online besides here so...?

EDIT: I put that in, but the character was clipping through walls and, at certain points, saying the index was out of range?

Also one person said they wanted to see the whole code so:


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()

You are missing the else statement in your movePlayerUp function.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM