我不知道如何在 pygame 中让一个矩形站在另一个矩形上

I dont know how to make a rect stand on another rect in pygame

我正在尝试制作一个简单的 2d 跳跃游戏,我制作了一个跳跃的立方体和一个简单的平台(地图),如果我像 print("collided") 一样测试它,碰撞会起作用,但我不知道'知道如何使矩形站在另一个矩形上,

tile[1] 实际上是从名为 tile_list 的列表中循环的所有图块(块)。在 tile_list 中,它们是保存的图块。 self.rect_img = img.get_rect() <- 是我希望玩家站立的矩形对象,但我怎么说,它在列表中循环所以我需要使用 tile[1]

我尝试使用:

for tile in self.tile_list:
    collide =  tile[1].colliderect(self.player_rect.x,self.player_rect.y,PLAYER_WIDTH,PLAYER_HEIGHT)
    if collide:
        tile[1].top =  self.player_rect.bottom
            

但是没有用,玩家(self.player_rect)以某种方式将第二个矩形推到它下面。 完整代码 main.py:

import pygame as pg
import sys
import os

from pygame import key
from mapdata import game_map_data

#ASSETS
GRASS_IMAGE = pg.image.load(r'C:\Users\user\Desktop\pygame-tilemap.11.2022\assets\platform.jpg')
sky = pg.image.load(r'C:\Users\user\Desktop\pygame-tilemap.11.2022\assets\sky.png')
CONTINUE = True

#CONSTANT VARIABLES
#WIDTH;HEIGHT
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 598
PLAYER_WIDTH = 20
PLAYER_HEIGHT = 20
#COLORS
COLOR_DARKBLUE = 'darkblue'
COLOR_RED = 'red'
#WINDOW
WINDOW = pg.display.set_mode((WINDOW_WIDTH,WINDOW_HEIGHT))

sky = pg.transform.scale(sky,(800,599))

class Player(object):
    def __init__(self,x,y,width,height,jumpRange):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.isJump = False
        self.jumpRange = jumpRange

    def Draw(self):
        self.player = pg.image.load(r'C:\Users\user\Desktop\pygame-tilemap.11.2022\assets\player.png')
        self.player = pg.transform.scale(self.player,(PLAYER_WIDTH,PLAYER_HEIGHT))
        self.player_rect = self.player.get_rect()
        WINDOW.blit(self.player,dest=(self.x,self.y))
        self.player_rect.x = self.x
        self.player_rect.y = self.y

        #COLLISION WITH BLOCKS
        for tile in self.tile_list:
            collide =  tile[1].colliderect(self.player_rect.x,self.player_rect.y,PLAYER_WIDTH,PLAYER_HEIGHT)
            if collide:
                tile[1].top =  self.player_rect.bottom
                
    def handle_keys(self,speed,vel_y):
        keys = pg.key.get_pressed()
        self.speed = speed
        self.vel_y = vel_y
        if keys[pg.K_RIGHT]:
            if CONTINUE == True:
                self.x += speed
        if keys[pg.K_LEFT]:
            if CONTINUE == True:
                self.x -= speed


    def jump(self,jumpRange):
        if self.isJump == True:
            if self.jumpRange >= -11:
                neg = 1
                if self.jumpRange < 0:
                    neg = -1
                self.y -= self.jumpRange**2 * 0.1 * neg
                self.jumpRange -= 1
            else:
                self.isJump = False
                self.jumpRange = jumpRange

    ###########
    ##TILEMAP##
    ###########

    def tile(self,data,tile_size,img_size):
        self.tile_list = []

        #SAVING TILES IN A LIST

        row_count = 0
        self.tile_size = tile_size
        self.img_size = img_size

        for row in data:
            col_count = 0
            for tile in row:
                if tile == 1:
                    self.rect_img = img.get_rect()
                    self.rect_img.x = col_count * tile_size
                    self.rect_img.y = row_count * tile_size
                    tile = (img,self.rect_img)
                    self.tile_list.append(tile)
                col_count += 1
            row_count += 1

    #DRAWING TILES FROM THE LIST
    def draw_tile(self):
        for tile in self.tile_list:
            WINDOW.blit(tile[0], tile[1])



#FPS
clock = pg.time.Clock()


game_map_data = game_map_data


#PLAYER
player = Player(x=30,y=500,width=PLAYER_WIDTH,height=PLAYER_HEIGHT,jumpRange=11)


img_size = 17
img = pg.transform.scale(GRASS_IMAGE,(img_size,img_size))
gamemap = player.tile(game_map_data,tile_size=17,img_size=20)



while True:
    FPS = 60
    pg.display.update()
    clock.tick(FPS)

    
    for event in pg.event.get():
        if event.type == pg.QUIT:
            sys.exit()
        elif event.type == pg.KEYDOWN:
            if event.key == pg.K_SPACE:
                # Start to jump by setting isJump to True.
                player.isJump = True

    SKY_POSITION = (0,0)

    WINDOW.blit(sky,SKY_POSITION)
    player.draw_tile()
    player.jump(jumpRange=11)
    player.Draw()
    player.handle_keys(speed=3,vel_y=3)
    pg.display.update()
    pg.display.flip()

mapdata.py:

game_map_data = [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
]

此外,如果你想测试代码,游戏会创建 2 个文件,main.py 和 mapdata.py(即 tilemap),并更改照片

你需要改变玩家的位置而不是方块的位置,你还需要设置玩家的y属性:

self.player_rect.x = round(self.x)
self.player_rect.y = round(self.y)

for tile in self.tile_list:
    if self.player_rect.colliderect(tile[1]):
        self.player_rect.bottom = tile[1].top
        self.y = self.player_rect.y