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
331 views
in Technique[技术] by (71.8m points)

python - Collision for Pygame Game Map

I am trying to make a maze game in Pygame but am unable to achieve collision for the 1 (maze wall) in the array. I tried to put the collision detection in the loop creating the map but it is not working. I also put the collision detection in the main loop but only the top left rect detected the collision, not all the 1 rects. How would I go about fixing this? Thank you!

import pygame
pygame.init()

screen = pygame.display.set_mode((700,700))
pygame.display.set_caption("Game")

speed = 20
x = 200
y = 600


def game_map():

    global rect_one
    surface = pygame.Surface((100, 100), pygame.SRCALPHA)
    rect_one = pygame.draw.rect(surface, (0, 0, 255), (0, 0, 50, 50)) 

    global rect_two
    surface_one = pygame.Surface((80, 80), pygame.SRCALPHA)
    rect_two = pygame.draw.rect(surface_one, (255, 255, 255), (0, 0, 50, 50)) 

    tileX = 0
    tileY = 0

    global tile_list
    tile_list = []
    map = [
            [1,1,1,1,1,1,1,1,1,1,1,1,1],
            [1,0,0,0,1,0,1,0,0,0,0,0,1],
            [1,0,1,0,0,0,1,0,1,1,1,0,1],
            [1,0,0,0,1,1,1,0,0,0,0,0,1],
            [1,0,1,0,0,0,0,0,1,1,1,0,1],
            [1,0,1,0,1,1,1,0,1,0,0,0,1],
            [1,0,1,0,1,0,0,0,1,1,1,0,1],
            [1,0,1,0,1,1,1,0,1,0,1,0,1],
            [1,0,0,0,0,0,0,0,0,0,1,0,1],
            [1,1,1,1,1,1,1,1,1,1,1,1,1]
            ]

    for y, row in enumerate(map):
        tileX = 0
        for x, cell in enumerate(row):
            image = surface if cell == 1 else surface_one
            screen.blit(image, [x*50, y*50]) 
            tile_list.append(rect_one)
    pygame.display.update() 


def player():
    player = pygame.draw.rect(screen, (255,0,0), (x, y, 20, 20))   

    for i in tile_list:
        if player.colliderect(i):
            print("hello")

loop = True

while loop:
    pygame.time.delay(100)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            loop = False

    #player controls
    keys = pygame.key.get_pressed()
    
    if keys[pygame.K_LEFT]:
        x -= speed
    if keys[pygame.K_RIGHT]:
        x += speed
    if keys[pygame.K_UP]:
        y -= speed
    if keys[pygame.K_DOWN]:
        y += speed

    screen.fill((255,255,255))
    game_map()
    player()
    pygame.display.update()


pygame.quit()
question from:https://stackoverflow.com/questions/65887274/collision-for-pygame-game-map

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

1 Reply

0 votes
by (71.8m points)

Save the position of the player before moving it:

pos = x, y

Compute the row and column after the player has moved:

row = y // 50
column = x // 50

Reset the player's position if the new position is on a wall:

if map[row][column] == 1:
    x, y = pos

Additionally you have to move the map variable to global namespace. The speed should a integral divider of the tile size. Change the starting position to a position in the grid:

speed = 25
x = 50
y = 50

Complete code:

import pygame
pygame.init()

screen = pygame.display.set_mode((700,700))
pygame.display.set_caption("Game")

speed = 25
x = 50
y = 50

map = [
    [1,1,1,1,1,1,1,1,1,1,1,1,1],
    [1,0,0,0,1,0,1,0,0,0,0,0,1],
    [1,0,1,0,0,0,1,0,1,1,1,0,1],
    [1,0,0,0,1,1,1,0,0,0,0,0,1],
    [1,0,1,0,0,0,0,0,1,1,1,0,1],
    [1,0,1,0,1,1,1,0,1,0,0,0,1],
    [1,0,1,0,1,0,0,0,1,1,1,0,1],
    [1,0,1,0,1,1,1,0,1,0,1,0,1],
    [1,0,0,0,0,0,0,0,0,0,1,0,1],
    [1,1,1,1,1,1,1,1,1,1,1,1,1]
]

def game_map():

    global rect_one
    surface = pygame.Surface((100, 100), pygame.SRCALPHA)
    rect_one = pygame.draw.rect(surface, (0, 0, 255), (0, 0, 50, 50)) 

    global rect_two
    surface_one = pygame.Surface((80, 80), pygame.SRCALPHA)
    rect_two = pygame.draw.rect(surface_one, (255, 255, 255), (0, 0, 50, 50)) 

    tileX = 0
    tileY = 0
    
    for y, row in enumerate(map):
        tileX = 0
        for x, cell in enumerate(row):
            image = surface if cell == 1 else surface_one
            screen.blit(image, [x*50, y*50]) 
    pygame.display.update() 


def player():
    player = pygame.draw.rect(screen, (255,0,0), (x, y, 25, 25))   

loop = True

while loop:
    pygame.time.delay(100)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            loop = False

    #player controls
    keys = pygame.key.get_pressed()
    
    pos = x, y
    if keys[pygame.K_LEFT]:
        x -= speed
    if keys[pygame.K_RIGHT]:
        x += speed
    if keys[pygame.K_UP]:
        y -= speed
    if keys[pygame.K_DOWN]:
        y += speed

    row = y // 50
    column = x // 50
    if map[row][column] == 1:
        x, y = pos

    screen.fill((255,255,255))
    game_map()
    player()
    pygame.display.update()

pygame.quit()

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

1.4m articles

1.4m replys

5 comments

57.0k users

...