Creating collision in pygame [closed]

做~自己de王妃 提交于 2021-01-28 08:05:17

问题


i'm having a problem with my code. So, I want to create a game, in Pygame, where the bananas fall from the sky, and the monkey have to grab them. I'm having quite a hard time creating a collision between those two (spent hours trying already).

So, this is my code:

import pygame, sys, random, time, os
from pygame.locals import * 

#Variáveis necessárias
banana_speed = 5
monkey_speed = 20
WIDTH = 800
HEIGHT = 800
pontos = 0
vidas = 3

#Nome do jogo
pygame.display.set_caption("Catch the fruit")

#Tamanho do ecrã do jogo
screen = pygame.display.set_mode((WIDTH, HEIGHT))

class Macaco(pygame.sprite.Sprite):
    def __init__(self):
        self.image = pygame.image.load('monkey.png')
        self.rect = self.image
        self.x = 300
        self.y = 640 
    def keyboard(self):
        key = pygame.key.get_pressed()
        if key[pygame.K_RIGHT]:
            self.x += monkey_speed
        elif key[pygame.K_LEFT]:
            self.x -= monkey_speed
    def draw (self, screen):
        screen.blit(self.rect, (self.x, self.y))

class Background(pygame.sprite.Sprite):
    def __init__(self, image_file, location):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(image_file)
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = location

class Banana(pygame.sprite.Sprite):
    def __init__(self):
        self.image = pygame.image.load('banana.png')
        self.rect = self.image
        self.x = random.randrange(0,WIDTH)
        self.y = -50
    def draw(self, screen):
        self.y = self.y + banana_speed
        screen.blit(self.rect,(self.x, self.y))

#Funções necessárias para o Loop
macaco = Macaco()
banana = Banana()
Background = Background('background.png', [0,0])

os.environ["SDL_VIDEO_CENTERED"] = "1"
pygame.init()

while vidas > 0:
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                running = False
        elif event.type == QUIT:
            running = False

    screen.blit(Background.image, Background.rect)
    pressed_keys = pygame.key.get_pressed()
    macaco.keyboard()
    macaco.draw(screen)
    banana.draw(screen)
    pygame.display.update()

edit: So i'm trying another solution and did this:

import pygame, sys, random, time, os
from pygame.locals import * 

#Variáveis necessárias
banana_speed = 5
monkey_speed = 20
WIDTH = 800
HEIGHT = 800
pontos = 0
vidas = 3
green = (0, 0 , 255)

#Nome do jogo
pygame.display.set_caption("Catch the fruit")

#Tamanho do ecrã do jogo
screen = pygame.display.set_mode((WIDTH, HEIGHT))

class Macaco(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.rect = pygame.image.load('monkey.png')
        self.image = pygame.Surface([WIDTH, HEIGHT])
        self.x = 300
        self.y = 640
        self.image.fill(green)
    def keyboard(self):
        key = pygame.key.get_pressed()
        if key[pygame.K_RIGHT]:
            self.x += monkey_speed
        elif key[pygame.K_LEFT]:
            self.x -= monkey_speed
    def draw (self, screen):
        screen.blit(self.rect, (self.x, self.y))

class Background(pygame.sprite.Sprite):
    def __init__(self, image_file, location):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(image_file)
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = location

class Banana(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.rect = pygame.image.load('banana.png')
        self.image = pygame.Surface([WIDTH, HEIGHT])
        self.x = random.randrange(0, WIDTH)
        self.y = -50
    def draw(self, screen):
        self.y = self.y + banana_speed
        screen.blit(self.rect,(self.x, self.y))


#Funções necessárias para o Loop
macaco = Macaco()
banana = Banana()
Background = Background('background.png', [0,0])

os.environ["SDL_VIDEO_CENTERED"] = "1"
pygame.init()

while vidas > 0:
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE:
                running = False
        elif event.type == QUIT:
            running = False
    screen.blit(Background.image, Background.rect)
    pressed_keys = pygame.key.get_pressed()
    macaco.keyboard()
    macaco.draw(screen)
    banana.draw(screen)
    blocks_hit_list = pygame.sprite.spritecollide(macaco, banana, True)
    for blocks in blocks_hit_list:
        pontos +=1
    pygame.display.update()

Could you give me some help please?


回答1:


I've created two sprite groups: all_sprites which contains all sprites and is used to update and draw them with just two lines of code, and the bananas group which is used to check for collisions between the macaco and the bananas. Then we need the pygame.sprite.spritecollide function to get the collided sprites. You have to pass a sprite instance and a sprite group and it'll check for you if the sprite has collided with the sprites in the group. It returns the collided bananas as a list over which you can iterate to do something with them or for example to increment a points counter.

You have to call the __init__ method of the parent class in your sprites to be able to use them correctly with sprite groups (do that with the super function super().__init__() (in Python 2 super(Macaco, self).__init__()).

To update the positions of your sprites, set their topleft (or center) attribute to the new x, y coordinates.

To get a rect from an image call self.rect = self.image.get_rect().

import sys
import random
import pygame


pygame.init()
screen = pygame.display.set_mode((800, 800))


class Macaco(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((30, 30))
        self.image.fill((190, 140, 20))
        self.rect = self.image.get_rect()
        self.x = 300
        self.y = 640
        self.speed = 20

    def keyboard(self, keys):
        if keys[pygame.K_RIGHT]:
            self.x += self.speed
        elif keys[pygame.K_LEFT]:
            self.x -= self.speed

    def update(self):
        self.rect.topleft = self.x, self.y


class Banana(pygame.sprite.Sprite):

    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((30, 30))
        self.image.fill((230, 230, 40))
        self.rect = self.image.get_rect()
        self.x = random.randrange(0, 770)
        self.y = -50
        self.speed = 5

    def update(self):
        self.y += self.speed
        self.rect.topleft = self.x, self.y


macaco = Macaco()
banana = Banana()

all_sprites = pygame.sprite.Group(macaco, banana)
bananas = pygame.sprite.Group(banana)

clock = pygame.time.Clock()
running = True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False

    keys = pygame.key.get_pressed()
    macaco.keyboard(keys)
    all_sprites.update()
    # Collision detection. Check if macaco collided with bananas group,
    # return collided bananas as a list. dokill argument is True, so
    # that collided bananas will be deleted.
    collided_bananas = pygame.sprite.spritecollide(macaco, bananas, True)
    for collided_banana in collided_bananas:
        print('Collision.')

    screen.fill((70, 40, 70))
    all_sprites.draw(screen)

    pygame.display.update()
    clock.tick(30)

pygame.quit()
sys.exit()


来源:https://stackoverflow.com/questions/44099654/creating-collision-in-pygame

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!