简体   繁体   English

在Python中碰撞没有类的矩形

[英]Colliding rectangles without classes in python

So I'm making this cool avoiding game and I've got everything done except for the collision. 因此,我正在制作一款很酷的避免游戏,除了碰撞之外,我已经完成了所有工作。 Since I'm a noob to the pygame module, I didn't do any classes, and I don't know how I would check if the player hitbox collides with the enemy hitbox. 由于我是pygame模块的菜鸟,因此我没有上任何课,也不知道如何检查玩家的Hitbox是否与敌人的Hitbox发生冲突。 Also, I know a few people have asked this before, but the answers they gave are either unclear to me or are for sprites, not rectangles. 另外,我知道以前有人问过这个问题,但是他们给出的答案对我来说还是不清楚,还是针对精灵而不是矩形。 Here's my code: https://hastebin.com/exaximafiy.py 这是我的代码: https : //hastebin.com/exaximafiy.py

#avoid game
#import
import pygame
from time import sleep
import os
import math
import random
import pygame.mixer
from pygame.locals import * 

#intiate pygame
pygame.mixer.init()
pygame.init()

os.system("cls")

#set screen size
screen = pygame.display.set_mode((1024,768))

#set title
pygame.display.set_caption("Avoid") 


def menu():
    pygame.time.delay(100)
    #set title
    pygame.display.set_caption("Avoid - Menu Screen") 
    running = True
    while running:
        #close program if user clicked big X
        if pygame.mixer.get_busy() != None:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running=False
                    pygame.quit()
                    break

        #set bg
        screen.fill((255,255,255))
        menubg=pygame.image.load("menuScreen.png")
        screen.blit(menubg,(0,0))
        pygame.display.flip()

        #detect button press (enter to play, h for instructions, q for options, esc to quit)
        keys = pygame.key.get_pressed()

        if keys[pygame.K_RETURN]:
            game()
        if keys[pygame.K_h]:
            instructions()
        if keys[pygame.K_ESCAPE]:
            pygame.quit()
        if keys[pygame.K_q]:
            options()

    pygame.quit()
def instructions():
    running=False
    #set title
    pygame.display.set_caption("Avoid - Instructions") 
    running=True
    while running:
        #close program if user clicked big X
        if pygame.mixer.get_busy() != None:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running=False
                    pygame.quit()
                    break

        #set bg
        screen.fill((255,255,255))
        helpbg=pygame.image.load("instructions.png")
        screen.blit(helpbg,(0,0))
        pygame.display.flip()

        #if esc pressed, go to menu
        keys = pygame.key.get_pressed()

        if keys[pygame.K_ESCAPE]:
            pygame.time.delay(100)
            menu()



def gameOver():
    running=False
    #set title
    pygame.display.set_caption("Avoid - Game Over") 
    running=True
    while running:
        #close program if user clicked big X
        if pygame.mixer.get_busy() != None:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running=False
                    pygame.quit()
                    break

        #set bg
        screen.fill((255,255,255))
        menubg=pygame.image.load("gameOver.png")
        screen.blit(menubg,(0,0)) 
        pygame.display.flip()

        #detect input
        keys = pygame.key.get_pressed()

        if keys[pygame.K_RETURN]:
            game()
        if keys[pygame.K_ESCAPE]:
            pygame.quit()  


def game():
    running=False
    #play music
    song = pygame.mixer.Sound("song.wav")
    song.play(-1)

    #set title
    pygame.display.set_caption("Avoid - Game Screen") 

    #set vars
    #enemy x and y pos
    randx = random.randint(17,1007)
    randy = random.randint(17,751)
    #time vars (time2 = enemyspawn, time = stopwatch, time3 = playersize time, time4 = playersize)
    time2 = 0.5
    time=0
    time3 = 10
    time4 = 1
    #player x,y
    x = 1024*0.5
    y = 768*0.5
    #enemy width,height
    width = 50
    height = 50
    #colors
    red=(255,0,0)
    #speed
    vel=10  
    #set player size
    playerSize = 15

    running = True
    while running:
        #pygame.time.delay(10)
        #close program if user clicked big X
        if pygame.mixer.get_busy() != None:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running=False
                    pygame.quit()
                    break

        #set stopwatch
        time=time+0.040


        #movement
        keys = pygame.key.get_pressed()
        #arrow
        if keys[pygame.K_DOWN] and y < 751:
            y += vel
        if keys[pygame.K_UP] and y > 17:
            y -= vel
        if keys[pygame.K_RIGHT] and x < 1007:
            x += vel
        if keys[pygame.K_LEFT] and x > 17:
            x -= vel
        #wasd
        if keys[pygame.K_s] and y < 751:
            y += vel
        if keys[pygame.K_w] and y > 17:
            y -= vel
        if keys[pygame.K_d] and x < 1007:
            x += vel
        if keys[pygame.K_a] and x > 17:
            x -= vel
        #if esc quit, y - collide
        if keys[pygame.K_ESCAPE]:
            pygame.quit()
        if keys[pygame.K_y]:
            collision()



        #shows what coords you on
        print(x,y)


        #set bg
        screen.fill((255,255,255))
        gamebg=pygame.image.load("gamebg.png")
        screen.blit(gamebg,(0,0))
        pygame.display.flip()

        #time thing in middle
        time1 = float('%.2f' % round(time,1))
        myfont = pygame.font.SysFont('Arial', 35)
        textsurface = myfont.render(("time: " +str(time1)), 1, (0,0,0))
        screen.blit(textsurface,(455,384))

        #load enemys

        if time2 < time1:
            time2 = (time2+0.5)
            randx = random.randint(17,1007)
            randy = random.randint(17,751)

        #rainbow
        enemy=pygame.image.load("red.png")
        screen.blit(enemy,(randx,randy))
        pygame.display.flip()

        pygame.time.wait(1)
        enemy=pygame.image.load("orange.png")
        screen.blit(enemy,(randx,randy))
        pygame.display.flip()

        pygame.time.wait(1)
        enemy=pygame.image.load("yellow.png")
        screen.blit(enemy,(randx,randy))
        pygame.display.flip()

        pygame.time.wait(1)
        enemy=pygame.image.load("green.png")
        screen.blit(enemy,(randx,randy))
        pygame.display.flip()

        pygame.time.wait(1)
        enemy=pygame.image.load("blue.png")
        screen.blit(enemy,(randx,randy))
        pygame.display.flip()

        pygame.time.wait(1)
        enemy=pygame.image.load("indigo.png")
        screen.blit(enemy,(randx,randy))
        pygame.display.flip()

        pygame.time.wait(1)
        enemy=pygame.image.load("violet.png")
        screen.blit(enemy,(randx,randy))
        pygame.display.flip()

        #change size
        if time3 < time1:
            time3 = (time3+10.0)
            playerSize = (playerSize + 15)
            time4 = (time4 + 0.9)


        #draw hitboxes
        #player
        playerHitbox=((x-(17.5*time4)),(y-(18*time4)),(35*time4),(35*time4))
        #enemy
        enemyHitbox=(randx,randy,50,50)
        #draw
        pygame.draw.rect(screen,red,playerHitbox,2)
        pygame.draw.rect(screen,red,enemyHitbox,2)

        #draw player (red circle)
        player = pygame.draw.circle(screen, red, [int(x),int(y)], playerSize)
        #update screen
        pygame.display.update()

        def collision():
            song.stop()
            pygame.time.delay(1000)
            gameOver()



        # def checkCollision(playerHitbox, enemyHitbox):
        #     col = playerHitbox.colliderect(enemyHitbox)
        #     if col == True:
        #         collision()

        # checkCollision(playerHitbox,enemyHitbox)

        if Rect.colliderect(enemyHitbox):
            collision()

menu()

Any leads would be helpful and you can ask me to clarify in the comments below. 任何线索都会有所帮助,您可以要求我在下面的评论中进行澄清。

Every Rect object in Pygame has a method colliderect which can test if that Rect object collides (overlaps) with any other Rect object. Pygame中的每个Rect对象都有一个colliderect方法,该方法可以测试该Rect对象是否与任何其他Rect对象发生碰撞(重叠)。 More info 更多信息

To check if a rectangle at point ( x1 , y1 ) with a width w1 and height h1 collides with a rectangle at point ( x2 , y2 ) with a width w2 and height h2 , you can implement this like so: 要检查宽度为w1和高度h1点( x1y1 )处的矩形是否与宽度为w2和高度h2点( x2y2 )处的矩形发生碰撞,可以这样实现:

pygame.Rect(x1,y1,w1,h1).colliderect(pygame.Rect(x2,y2,w2,h2))

In your specific example for example, you could implement what you are trying to do with: 例如,在您的特定示例中,您可以实现您尝试执行的操作:

def checkCollision(playerHitbox, enemyHitbox):
    return pygame.Rect(*playerHitbox).colliderect(pygame.Rect(*enemyHitbox))

NB: the * I used here unpacks the tuple into arguments. 注意:我在这里使用的*将元组解压缩为参数。 Ie: the first element is sent as the first argument, the second is sent as the second argument, etc. More info . 即:第一个元素作为第一个参数发送,第二个元素作为第二个参数发送,等等。 更多信息

You were on the right track in your code, remember that this method operates on Rect objects and not on tuples of the information itself. 您在代码中的位置正确,请记住,此方法对Rect 对象 Rect ,而不对信息本身的元组起作用。 You therefore need to instantiate the necessary Rect objects as shown above ^ 因此,您需要如上所示实例化必要的Rect对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM