Pygame我的游戏的碰撞工作,但只为最后放置的imag

2024-10-03 23:31:03 发布

您现在位置:Python中文网/ 问答频道 /正文

import pygame, random, time

class Game(object):
def main(self, screen):
    bg = pygame.image.load('data/bg.png')
    house1 = pygame.image.load('data/house1.png')

    playerIdle = pygame.image.load('data/playerIdle.png')
    playerRight = pygame.image.load('data/playerRight.png')
    playerLeft = pygame.image.load('data/playerLeft.png')
    playerUp = pygame.image.load('data/playerUp.png')
    playerX = 0
    playerY = 50

    clock = pygame.time.Clock()
    spriteList = []
    gameIsRunning = False

    house1Selected = False
    houseInWorld = False


    while 1:
        clock.tick(30)

        mouse = pygame.mouse.get_pos()
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
            if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                return
    #delete all sprites on the game(only able to do this in god mode)
    if event.type == pygame.KEYDOWN and event.key == pygame.K_d and gameIsRunning == False:
        spriteList = []
    #press 6 to select the house1 image to be placed
    if event.type == pygame.KEYDOWN and event.key == pygame.K_6 and gameIsRunning == False:
        house1Selected = True
    #spawning the image"house1" at the position of the mouse by pressing space
    if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE and gameIsRunning == False and house1Selected == True:
        spriteList.append((house1, mouse))
        house1XY = mouse
        houseInWorld = True

    #run mode where you cannot build and you move(where I want collision)
    if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
        gameIsRunning = True
    #god mode where you can build and place the house1 image
    if event.type == pygame.KEYDOWN and event.key == pygame.K_g:
        gameIsRunning = False

    #this is run mode where you can move around and where I want collision
    if(gameIsRunning == True):
        #player Movements
        if event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
            if playerY <= 0:
                playerY = 0
            if playerY >= 0:
                screen.blit(playerUp, (playerX, playerY))
                playerY = playerY - 2
        if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
            PLAYERDOWNLIMIT = 700 - playerIdle.get_height()
            if(playerY >= PLAYERDOWNLIMIT):
                playerY = PLAYERDOWNLIMIT
            if(playerY <= PLAYERDOWNLIMIT):
                screen.blit(playerIdle, (playerX, playerY))
                playerY = playerY + 2
        if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
            if playerX <= 0:
                playerX = 0
            if playerX >= 0:
                screen.blit(playerLeft, (playerX, playerY))
                playerX = playerX - 2
        if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
            PLAYERRIGHTLIMIT = 1200 - playerIdle.get_width()
            if(playerX >= PLAYERRIGHTLIMIT):
                playerX = PLAYERRIGHTLIMIT
            if(playerX <= PLAYERRIGHTLIMIT):
                screen.blit(playerRight, (playerX, playerY))
                playerX = playerX + 2

        #collision

        if(house1InWorld == True):
            house1Rect = pygame.Rect(house1XY[0], house1XY[1], 64, 64)

            if playerRect.colliderect(house1Rect) and playerX <= house1XY[0]:
                playerX = playerX - 2
            if playerRect.colliderect(house1Rect) and playerX >= house1XY[0]:
                playerX = playerX + 2
            if playerRect.colliderect(house1Rect) and playerY <= house1XY[1]:
                playerY = playerY - 2
            if playerRect.colliderect(house1Rect) and playerY >= house1XY[1]:
                playerY = playerY + 2

    #this is godmode where you can move around fast n preview where you place images but I don't want collision here
    if(gameIsRunning == False):
        if event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
            if playerY <= 0:
                playerY = 0
            if playerY >= 0:
                screen.blit(playerUp, (playerX, playerY))
                playerY = playerY - 8
        if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
            PLAYERDOWNLIMIT = 700 - playerIdle.get_height()
            if(playerY >= PLAYERDOWNLIMIT):
                playerY = PLAYERDOWNLIMIT
            if(playerY <= PLAYERDOWNLIMIT):
                screen.blit(playerIdle, (playerX, playerY))
                playerY = playerY + 8
        if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
            if playerX <= 0:
                playerX = 0
            if playerX >= 0:
                screen.blit(playerLeft, (playerX, playerY))
                playerX = playerX - 8
        if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
            PLAYERRIGHTLIMIT = 1200 - playerIdle.get_width()
            if(playerX >= PLAYERRIGHTLIMIT):
                playerX = PLAYERRIGHTLIMIT
            if(playerX <= PLAYERRIGHTLIMIT):
                screen.blit(playerRight, (playerX, playerY))
                playerX = playerX + 8

    screen.fill((200, 200, 200))
    screen.blit(bg, (0, 0))
    #what block are you placing(displays preview)
    if(gameIsRunning == False and house1Selected == True):
        screen.blit(house1, (mouse))

    if(gameIsRunning == True):
        playerXSTR = str(playerX)
        playerYSTR = str(playerY)
        playerXYSTR = ("(" + playerXSTR + ", " + playerYSTR + ")")
        font = pygame.font.SysFont("monospace", 15)
        playercord = font.render(playerXYSTR, 1, (255,255,255))
        screen.blit(playercord, (0, 0))
        runMode = font.render("Run Mode(Cannot build)", 1, (255,255,255))
        screen.blit(runMode, (0, 20))
    if(gameIsRunning == False):
        playerXSTR = str(playerX)
        playerYSTR = str(playerY)
        playerXYSTR = ("(" + playerXSTR + ", " + playerYSTR + ")")
        font = pygame.font.SysFont("monospace", 15)
        playercord = font.render(playerXYSTR, 1, (255,255,255))
        screen.blit(playercord, (0, 0))
        godMode = font.render("God Mode(Can build)", 1, (255,255,255))
        screen.blit(godMode, (0, 20))

    for (img, pos) in spriteList:
        screen.blit(img, pos)
    screen.blit(playerIdle, (playerX, playerY))

    pygame.display.flip()

if __name__ == '__main__':
pygame.init()
screen = pygame.display.set_mode((1200, 700))
pygame.display.set_caption('Sandbox')
Game().main(screen)

在我的游戏中,你从“上帝模式”开始,在那里你可以放置物体。当你完成放置物体并进入“运行模式”时,游戏是实时的,会有碰撞和其他物理效果。你知道吗

所以我现在在游戏中的碰撞只在一部分时间起作用。你知道吗

按空格键时,会在鼠标位置生成“house1”图像,它会设置house1的XY坐标,并设置house1InWorld = True(这会影响碰撞)。你知道吗

由于house1inWorld属性的缘故,冲突在生成house1图像时生效。因此,如果按r键(进入运行模式),则碰撞对一个house1实例有效。但是,当生成house1的2个实例(在不同的位置)时,碰撞只适用于最近放置的house1。你知道吗

我该如何更改代码,以便无论您生成多少house1,冲突都能正常工作?你知道吗


Tags: andkeyimageeventfalseiftypescreen
1条回答
网友
1楼 · 发布于 2024-10-03 23:31:03

您只存储最后放置的房屋的位置,并检查与该房屋的碰撞。你知道吗

您应该创建一个房屋位置列表,并循环查看它们以检查碰撞。 像这样:

houses1XY = []
houses1XY.append(mouse)
#and later
for house1XY in houses1XY:
    house1Rect = pygame.Rect(house1XY[0], house1XY[1], 64, 64)

由于您将房屋移动到列表中,因此不再需要houseInWorld。您已经在列表中找到了有关的信息。您可以通过评估列表来检查列表是否为空->;因此已经放置了房子。如果不为空,则返回true。你知道吗

if houses1XY:
   #enable realtime etc.

相关问题 更多 >