我如何知道立方体何时与另一个移动立方体碰撞?

时间:2015-12-28 22:55:51

标签: python python-3.x pygame

我正在尝试创建一个小游戏作为训练,但我被阻止因为我不知道如何碰撞2个移动的立方体。

游戏很简单,有一个红色的盒子可以移动,如果这个盒子碰到一个绿色的立方体,那么你输了。 (绿色立方体总是在移动)

我尝试阅读一些文档但作为初学者并不是很容易理解。

以下是代码:

import pygame
import random
from threading import Timer

pygame.init()

screenWidth = 1100
screenHeight = 600

white = (255,255,255)
red = (255, 0, 0)
yellow = (50, 250, 20)

FPS = 60

gameDisplay = pygame.display.set_mode((screenWidth, screenHeight))
pygame.display.set_caption('Tekken')
pygame.display.update()

clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 28)
class Players:
    def __init__(self, playerName, playerAttribute, cubeheight, cubewidth, missilesHeight, missilesWidth):
        self.playerName = playerName
        self.playerAttribute = playerAttribute
        self.playerLife = 100
        self.droite_x = 300
        self.droite_y = 600
        self.cubeheight = cubeheight
        self.cubewidth = cubewidth
        self.missiles = True
        self.missilesHeight = missilesHeight
        self.missilesWidth = missilesWidth
        self.missiles_droite_x = 0
        self.missiles_droite_y = round(random.randrange(50, screenHeight-50))
        self.missiles_droite_x_inverse = screenWidth-50
        self.missiles_droite_y_inverse = round(random.randrange(50, screenHeight-50))
        self.vitesse_missiles = 10

        print(self.playerName, self.playerAttribute, self.playerLife)

    def environment_un(self):
        gameExit = False
        gameOver = False

        droite_x_change = 0
        droite_y_change = 0
        missiles_droite_x_change = 0
        missiles_droite_x_change_inverse = 0

        while not gameExit:

            while gameOver:
                gameDisplay.fill(red)
                screen_text = font.render("Game Over, do you want to play again? [Q] to quit", True, white)
                gameDisplay.blit(screen_text, [100, 300])
                pygame.display.update()

                for event in pygame.event.get():
                    if event.type == pygame.KEYDOWN:

                        if event.key == pygame.K_q:
                            gameOver = False
                            gameExit = True
                            break

                    if event.type == pygame.QUIT:
                        gameOver = False
                        gameExit = True
                        break

            for event in pygame.event.get(): #va chercher les events
                if event.type == pygame.QUIT: #Si j'appuie sur X
                    gameExit = True

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_LEFT:
                        droite_x_change = -3

                    if event.key == pygame.K_RIGHT:
                        droite_x_change = +3

                    if event.key == pygame.K_UP:
                        droite_y_change = -3

                    if event.key == pygame.K_DOWN:
                        droite_y_change = +3

                    if event.key == pygame.K_SPACE:
                         missiles_droite_x_change = self.vitesse_missiles
                         missiles_droite_x_change_inverse = -self.vitesse_missiles

                if event.type == pygame.KEYUP:
                    if event.key == pygame.K_LEFT:
                        droite_x_change = 0

                    if event.key == pygame.K_RIGHT:
                        droite_x_change = 0

                    if event.key == pygame.K_UP:
                        droite_y_change = 0

                    if event.key == pygame.K_DOWN:
                        droite_y_change = 0


            self.missiles_droite_x_inverse += missiles_droite_x_change_inverse
            self.missiles_droite_x += missiles_droite_x_change
            self.droite_x += droite_x_change
            self.droite_y += droite_y_change

            if self.droite_y + self.cubeheight <= 0:
                self.droite_y = 0
            elif self.droite_y + self.cubeheight >= screenHeight:
                self.droite_y = screenHeight-self.cubeheight
            elif self.droite_x + self.cubewidth <= 0:
                self.droite_x = 0
            elif self.droite_x + self.cubewidth >= screenWidth:
                self.droite_x = screenWidth-self.cubewidth



            gameDisplay.fill(white)
            gameDisplay.fill(red, rect=[self.droite_x, self.droite_y, self.cubewidth, self.cubeheight])
            gameDisplay.fill(yellow, rect=[self.missiles_droite_x, self.missiles_droite_y, self.missilesWidth, self.missilesHeight])
            gameDisplay.fill(yellow, rect=[self.missiles_droite_x_inverse, self.missiles_droite_y_inverse, self.missilesWidth, self.missilesHeight])
            pygame.display.update()

            if self.missiles_droite_x + self.missilesWidth >= screenWidth:
                missiles_droite_x_change = 0
                if missiles_droite_x_change == 0:
                    self.missiles_droite_x = 0
                    self.missiles_droite_y = round(random.randrange(50, screenHeight-50))
                    missiles_droite_x_change = self.vitesse_missiles

            if self.missiles_droite_x_inverse <= 0:
                missiles_droite_x_change_inverse = 0
                if missiles_droite_x_change >= 0:
                    self.missiles_droite_x_inverse = screenWidth-50
                    self.missiles_droite_y_inverse = round(random.randrange(50, screenHeight-50))
                    missiles_droite_x_change_inverse = -12

            clock.tick(FPS)
        pygame.quit()

Player_1 = Players('John', 'sometext', 50, 50, 100, 100)
Player_1.environment_un()

我应该怎样做才能发现碰撞?

3 个答案:

答案 0 :(得分:3)

我暂时无法运行您的代码,因为我没有安装pygame。但是,如果您声明对象在其类中具有pygame.sprite.Sprite-object或从该类继承(如下所示),则可以使用pygame.sprite.collide_rect()。下面的代码可能会记录工作,因为我无法测试它,但它应该接近功能正常的代码片段。如果您想测试精灵与多个其他精灵的碰撞,请考虑查看pygame.sprite.Group()。我相信这样的事情应该有效:

class SpriteObject(pygame.sprite.Sprite):
    def __init__(self,pos_x, pos_y):   
        pygame.sprite.Sprite.__init__(self)
        self.rect = self.original.get_rect()
        self.rect.center = (pos_x, pos_y)

class Players:
    def __init__(self, playerName, playerAttribute, cubeheight, cubewidth, missilesHeight, missilesWidth):
        sprite1 = SpriteObject(1,2)
        sprite2 = SpriteObject(1,2)
        sprite1.rect.collide_rect(sprite2)

答案 1 :(得分:2)

如果您正在寻找概念性答案:

由于您只考虑立方体,如果它们具有相同的大小,则当且仅当'一个立方体的一个角落在另一个立方体的两个平行平面之间时,两个立方体将占据相同的空间“。在实践中有很多方法可以做到这一点。

我会检查是否通过从任意角落(立方体1)评估点缀有向量的立方体1的向内法线向量到角落(立方体2)。对两个平行边都这样做。如果两者都是正面的,那么它的内部

对于不同形状和不同尺寸,它稍微复杂一些。

答案 2 :(得分:-2)

使用pygame.Rect()保持多维数据集的位置和大小 - 然后您可以使用pygame.Rect.colliderect()检查两个多维数据集之间的冲突。

cube1 = pygame.Rect((x1, y1), (width, height)) 
cube2 = pygame.Rect((x2, y2), (width, height)) 

if cube1.colliderect(cube2):
     print("Collision !")

PyGame还有其他有用的类 - pygame.sprite.Spritepygame.sprite.Group - 使用Rectcollision detection函数。