Столкнувшиеся прямоугольники без классов в Python

1

Так что я делаю эту классную игру, избегая столкновений, и у меня есть все, кроме столкновения. Поскольку я новичок в модуле pygame, я не проводил никаких занятий и не знаю, как бы я мог проверить, не попадает ли хитбокс игрока с хитбоксом противника. Кроме того, я знаю, что некоторые люди спрашивали об этом раньше, но ответы, которые они дали, мне либо неясны, либо относятся к спрайтам, а не к прямоугольникам. Вот мой код: 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()

Любые выводы будут полезны, и вы можете попросить меня уточнить в комментариях ниже.

  • 0
    Всем привет! Пожалуйста, включите (соответствующие) части вашего кода непосредственно в ваш вопрос, а не в виде ссылки. Это ускоряет ответ на ваш вопрос и гарантирует, что он будет оставаться понятным ~ навсегда, поскольку, в отличие от ссылки на код, ваш вопрос не устареет :)
  • 0
    Возможно, вы захотите взглянуть на Как создать минимальный, полный и проверяемый пример
Показать ещё 1 комментарий
Теги:
pygame

1 ответ

4
Лучший ответ

Каждый объект Rect в Pygame имеет метод colliderect который может проверить, сталкивается ли этот объект Rect (перекрывается) с любым другим объектом Rect. Больше информации

Чтобы проверить, сталкивается ли прямоугольник в точке (x1, y1) с шириной w1 и высотой h1 с прямоугольником в точке (x2, y2) с шириной w2 и высотой h2, вы можете реализовать это следующим образом:

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

Например, в вашем конкретном примере вы можете реализовать то, что вы пытаетесь сделать:

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

NB: * я использовал здесь, распаковывает кортеж в аргументы. То есть: первый элемент отправляется в качестве первого аргумента, второй отправляется в качестве второго аргумента и т.д. Подробнее.

Вы были на правильном пути в своем коде, помните, что этот метод работает с объектами Rect а не с кортежами самой информации. Поэтому вам нужно создать экземпляр необходимых объектов Rect как показано выше ^

  • 1
    Спасибо вам большое! Я сделал несколько изменений в вашем коде, и это сработало !!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню