Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
625 views
in Technique[技术] by (71.8m points)

python - Is there a way to use for loops to make a game map in pygame?

So I want to make a gamemap in my pygame using for loops, but apparently the way I am doing it does not work. The code is below and if you can take a look at it, that would be nice!

Pygame

import pygame
import sys
import random
import subprocess


# _______initiate Game______________ #
class Game:
    pygame.init()
    width = 800
    height = 800
    screen = pygame.display.set_mode((width, height))
    pygame.display.set_caption("Maze Game")
    pygame.draw.circle(screen, (0, 0, 255), (250, 250), 75)

    white = [255, 255, 255]
    black = [0, 0, 0]
    lblue = [159, 210, 255]
    background = input(
        "What color background would you like? (White, Black, or Light Blue): ")
    if background == "White":
        screen.fill(white)
        pygame.display.flip()
    elif background == "Black":
        screen.fill(black)
        pygame.display.update()
    elif background == "Light Blue":
        screen.fill(lblue)
        pygame.display.update()
    else:
        screen.fill(black)
        pygame.display.update()
    for "." in "map1.txt":
        pygame.image.load("winter.Wall.png")



# ___________________TO RUN___________________________ #
run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    if event.type == pygame.KEYDOWN:
        command = "python JakeGame.py"
        subprocess.call(command)

for event in pygame.event.get():
    if event.type == pygame.KEYDOWN:
        if event.type == pygame.K_ESCAPE:
            pygame.quit()
# _______________________________________________ #

pygame.quit()

This is the map txt file and the error I am getting

...1...........................................
...11111111111111..............................
1111............11111111111111.................
1............................111...............
111............................................
1..............................................
111111111111111111111111111....................
..................1............................
1111111111111111111............................
..................1............................
..................11111111.....................
..........111111111......111111111.............
.................................1.............

So basically, what I am trying to do is convert all those periods to be loaded with an image called winterWall.png .

The error I am getting is "can't assign literal" Thank you guys for helping :p

question from:https://stackoverflow.com/questions/65947554/is-there-a-way-to-use-for-loops-to-make-a-game-map-in-pygame

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It's a bit more complicated than just what you propose (which is invalid syntax).

The code needs to open the file, then iterate over the rows and columns of map data. Then, for each type of letter it finds, render some kind of tile-based representation - here I've just used red and green blocks. An alternate version could just as easily render bitmaps.

The first thing you need to do is open the file and read the text into a list of strings - one for each line:

map_data = open( map_filename, "rt" ).readlines()

One caveat to this method, is that each line still has its end-of-line on the end. And it would be better to handle errors (like the file being missing), rather than crashing.

Then we create a Surface, which is just an off-screen image. It needs to be as big as the map is, times the size of the tiles. Since this is created inside the TileMap class, this gets stored in TileMap.image (i.e: self.image).

Next the code iterates through each line, and then each letter drawing a rectangle. The code just uses the constant TILE_SIZE for this. You need to decide if this is going to work with coloured squares, or bitmaps, etc. - but obviously all your tiles need to use the same size.

    # iterate over the map data, drawing the tiles to the surface
    x_cursor = 0  # tile position
    y_cursor = 0
    for map_line in map_data:             # for each row of tiles
        x_cursor = 0
        for map_symbol in map_line:       # for each tile in the row
            tile_rect = pygame.Rect( x_cursor, y_cursor, TileMap.TILE_SIZE, TileMap.TILE_SIZE )
            if ( map_symbol == '.' ):
                pygame.draw.rect( self.image, RED, tile_rect )
            elif ( map_symbol == '1' ):
                pygame.draw.rect( self.image, GREEN, tile_rect )
            else:
                pass  # ignore 
 etc.
            x_cursor += TileMap.TILE_SIZE
        y_cursor += TileMap.TILE_SIZE

Note that we make an x_cursor and y_cursor. This is the top-left corner of the map-tile about to be drawn. As we step through each character, we update this to the next position on the map.

At each point, the map has a TILE_SIZE by TILE_SIZE (16x16) "cell" into which we draw a coloured square, depending on the type of map item.

At the end of the operation, we have loaded in all the map tiles, and draw the map to an off-screen Surface (self.image), which can be draw to the screen quickly and easily.

The TileMap class, simply wraps all this together.

screenshot.png

Reference Code:

import pygame

WINDOW_WIDTH = 800
WINDOW_HEIGHT= 600
SURFACE = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE

#define colours
BLACK = (0,0,0)
RED   = ( 200, 0, 0 )
GREEN = (0,255,0)


### Class to render map-data to a surface image
class TileMap:
    TILE_SIZE=16    # size of map elements

    def __init__( self, map_filename ):
        """ Load in the map data, generating a tiled-image """
        map_data = open( map_filename, "rt" ).readlines()     # Load in map data  TODO: handle errors
        map_width  = len( map_data[0] ) - 1  
        map_length = len( map_data )
        # Create an image to hold all the map tiles
        self.image = pygame.Surface( ( map_width * TileMap.TILE_SIZE, map_length * TileMap.TILE_SIZE ) )
        self.rect  = self.image.get_rect()
        # iterate over the map data, drawing the tiles to the surface
        x_cursor = 0  # tile position
        y_cursor = 0
        for map_line in map_data:             # for each row of tiles
            x_cursor = 0
            for map_symbol in map_line:       # for each tile in the row
                tile_rect = pygame.Rect( x_cursor, y_cursor, TileMap.TILE_SIZE, TileMap.TILE_SIZE )
                if ( map_symbol == '.' ):
                    pygame.draw.rect( self.image, RED, tile_rect )
                elif ( map_symbol == '1' ):
                    pygame.draw.rect( self.image, GREEN, tile_rect )
                else:
                    pass  # ignore 
 etc.
                x_cursor += TileMap.TILE_SIZE
            y_cursor += TileMap.TILE_SIZE

    def draw( self, surface, position=(0,0) ):
        """ Draw the map onto the given surface """
        self.rect.topleft = position
        surface.blit( self.image, self.rect )


### initialisation
pygame.init()
pygame.mixer.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), SURFACE )
pygame.display.set_caption("Render Tile Map")

### Load the map
tile_map = TileMap( "map1.txt" )


### Main Loop
clock = pygame.time.Clock()
done = False
while not done:

    # Handle user-input
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            done = True

    # Update the window, but not more than 60fps
    window.fill( BLACK )

    # Draw the map to the window
    tile_map.draw( window )

    pygame.display.flip()
    clock.tick_busy_loop(60)

pygame.quit()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...