问题
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