Пигмеи-спрайты "сталкиваются" прежде, чем они коснутся - PullRequest
0 голосов
/ 30 июня 2018

Новое в кодировании и создании игры с использованием Python и Pygame. Игра похожа на Flappy bird, но в космосе и трубы - метеоры.

Работа над созданием события, когда спрайты сталкиваются, но функция pygame.sprite.spritecollide не работает должным образом. Функция запускается на дюйм или около того (на экране) до того, как спрайты действительно соприкасаются. Если спрайты игрока проваливаются через метеоритный спрайт, событие не запускается.

import pygame
import random

# Initialize the game engine 
pygame.init()

# Define colors
WHITE = (255, 255, 255)

# Define done 
done = False

def create_meteor():
    meteor = Meteor(WHITE, width, height)
    meteor_sprites_list.add(meteor)

class Player(pygame.sprite.Sprite):
    # This class will be the sprite controlled by player

    # -- Methods
    def __init__(self, filename, color, HW, HH):
        # Constructor function 
        # Call parent'c constructor 
        super().__init__()

        # Set height, width
        self.image = pygame.image.load("player.png").convert_alpha()
        # Set background color to transparent
        self.image.set_colorkey(color)

        # Make top-left corner the passed in locatin 
        self.rect = pygame.rect.Rect((HW, HH), self.image.get_size())

        # How much to add to current player position
        self.dy = 0 

    def ignite(self):
        self.dy = -400

    def update(self, dt, screen):

        #apply gravity
        self.dy = min(400, self.dy + 40)
        self.rect.y += self.dy * dt

        self.rect.topleft = (self.rect.x, self.rect.y)  

        # Blit image to screen
        screen.blit(self.image, (320, self.rect.y))
        pygame.display.flip()


# Define new clas for meteor
class Meteor(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
        # Takes in parameters for color, width (x position) , and height (y postion)

        # Call the parent class 
        super().__init__()

        # Make list of image file location
        self.meteor_list = ["meteors/meteor1.png"]

        # Randomly select meteor from above list
        self.new_meteor = random.choice(self.meteor_list)

        # Load graphic that is in file folder  
        self.image = pygame.image.load(self.new_meteor).convert_alpha()

        # Set background to transparent
        self.image.set_colorkey(color)

        # Fetch the rectangle object that has the dimensions of the image
        self.rect = self.image.get_rect()

        # Random starting location
        self.rect.x = random.randrange(width, (width + 100))
        self.rect.y = random.randrange(0, height)

        # Random movement to the left
        self.change_x = random.randrange(-10,-5)
        self.change_y = random.randrange(-4,3)

    # ---- Attributes  
    # What meteor does each cycle through
    def update(self): 
        # Move bad block down 3 at a time 
        self.rect.x += self.change_x
        self.rect.y += self.change_y


# Used to manage how fast the screen updates
clock = pygame.time.Clock()

background_size = pygame.image.load("background.png")
# Get dimensions of background
width = background_size.get_width()
height = background_size.get_height() 
HW, HH = width/2, height/2
size = (width, height)
screen = pygame.display.set_mode(size)


# Load image for star background  
background = pygame.image.load("background.png").convert_alpha()
# Seperate becuase error when placed before screen

# Creates a list of sprites. Each object in program is added to list. Managed by a class called "group"
meteor_sprites_list = pygame.sprite.Group()


# Create spaceship 
player = Player("player.png", WHITE, HW, HH)

# Create meteor sprites on the screen     
create_meteor()

#-----Main Program Loop 
while not done:
    dt = clock.tick(30)
    # Main event Loop 
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        if event.type == pygame.MOUSEBUTTONDOWN:
            player.ignite()

#-----Game Logic 
    # Draw background
    screen.blit(background, (0,0))

    # Update Sprites 
    # Update meteor sprite
    meteor_sprites_list.update()
    # Update player sprite
    player.update(dt/1000. , screen)
    # Draw meteors
    meteor_sprites_list.draw(screen) 


    # Check to see if player has collided with meteor
    meteor_hit_list = pygame.sprite.spritecollide(player, meteor_sprites_list, True, pygame.sprite.collide_circle)

    # -- Go ahead and update the screen with what we've drawn.
    pygame.display.flip()

# Make sure to quit 
pygame.quit()

Любой совет будет принят и оценен. Спасибо, что посмотрели.

1 Ответ

0 голосов
/ 01 июля 2018

Если что-то не так с обнаружением столкновений, это обычно помогает нарисовать (или распечатать) фрагменты задействованных спрайтов. Вы не стираете изображение по x-координате прямоугольника, поэтому прямоугольник фактически будет дальше вправо.

screen.blit(self.image, (320, self.rect.y))  # self.rect.x is equal to `HW` not 320.

Просто перетащите изображение в прямоугольник:

screen.blit(self.image, self.rect)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...