Pygame我的游戏碰撞有效,但仅适用于最后放置的图像

时间:2014-02-09 08:50:27

标签: python pygame

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实例。但是当你产生2个house1实例(在不同的位置)时,碰撞只适用于最近放置的house1。

我应该如何更改我的代码,以便无论你生成多少个house1,碰撞都会起作用?

1 个答案:

答案 0 :(得分:1)

您只存储最后放置的房屋的位置并检查碰撞。

您应该创建一个房屋位置列表,然后循环检查房屋位置以检查是否存在碰撞。 像这样:

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

由于您将房屋移至列表,因此您不再需要houseInWorld。您已经在列表中获得了相关信息。您可以检查列表是否为空 - &gt;所以通过评估列表已经放置了一所房子。如果它不为空,则返回true。

if houses1XY:
   #enable realtime etc.