简体   繁体   English

如何检测两个移动精灵之间的碰撞?

[英]How can I detect collision between two moving sprites?

I am trying to make it so when my player sprite collides with an enemy, the player is killed.我试图做到这一点,当我的玩家精灵与敌人发生碰撞时,玩家会被杀死。 However, my player only dies if the enemy happens to spawn at the same point as the player and not when the player moves about and touches another sprite on purpose.但是,我的玩家只有在敌人碰巧与玩家在同一点生成时才会死亡,而不是当玩家四处移动并故意触摸另一个精灵时。

Here is my code:这是我的代码:


import math
from random import randint
import pygame
from pygame.math import Vector2

pygame.init()

screen = pygame.display.set_mode((600, 600))
screen_width = 600
screen_height = 600
black = (0, 0, 0)
pygame.display.set_caption("gang")
clock = pygame.time.Clock()


class Player(pygame.sprite.Sprite):

    def __init__(self, pos):
        super().__init__()
        self.image = pygame.Surface((50, 30), pygame.SRCALPHA)
        pygame.draw.polygon(self.image, pygame.Color('steelblue2'), [(0, 0), (50, 15), (0, 30)])
        self.original_image = self.image
        self.rect = self.image.get_rect(center=pos)
        self.pos = Vector2(pos)
        self.velocityx = Vector2(6, 0)
        self.velocityy = Vector2(0, 6)

    def update(self):
        self.rect.center = (int(self.pos.x), int(self.pos.y))
        clamp_rect = self.rect.clamp(screen.get_rect())
        if clamp_rect != self.rect:
            self.rect = clamp_rect
            self.pos.x, self.pos.y = self.rect.center
        self.rotate()

    def rotate(self):
        direction = pygame.mouse.get_pos() - self.pos
        radius, angle = direction.as_polar()
        self.image = pygame.transform.rotate(self.original_image, -angle)
        self.rect = self.image.get_rect(center=self.rect.center)


class Enemy(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pygame.Surface((50, 50))
        self.image.fill((randint(0, 255), randint(0, 255), randint(0, 255)))
        self.rect = self.image.get_rect(center=pos)
        self.pos = Vector2(pos)
        self.velocity = Vector2(1, 0)

    def update(self):
        self.pos += self.velocity
        self.rect.center = self.pos


class Projectile(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pygame.Surface((9, 15), pygame.SRCALPHA)
        pygame.draw.circle(self.image, (0, 0, 0), (30, 50), 14)
        self.rect = self.image.get_rect(center=pos)
        self.pos = Vector2(pos)
        self.velocityx = Vector2(9, 0)
        self.velocityy = Vector2(0, 9)

    def update(self):
        self.pos += self.velocityx
        self.rect.center = self.pos


def draw_window():
    screen.fill((30, 30, 30))
    all_sprites.update()
    all_sprites.draw(screen)
    bullets.update()
    bullets.draw(screen)
    pygame.display.update()


def xor(a, b):
    if bool(a) != bool(b):
        return True
    else:
        return False


def game_end():
    pygame.font.init()
    text = pygame.font.Font('freesansbold.ttf', 32)
    text_surface = text.render('Game Over', False, (255, 255, 255))
    text_rect = text_surface.get_rect()
    text_rect.center = (86, 86)
    screen.blit(text_surface, (172, 172))
    pygame.display.update()


player = Player((300, 300))
projectile = Projectile((150, 150))
bullets = pygame.sprite.Group(projectile)
enemies_list = pygame.sprite.Group()
all_sprites = pygame.sprite.Group(player, projectile)


def collision():
    score = 0

    for i in range(5):
        enemy = Enemy((randint(0, 600), randint(0, 600)))
        enemies_list.add(enemy)
        all_sprites.add(enemy)

        collide_list = pygame.sprite.spritecollide(player, enemies_list, True)
        for enemy in collide_list:
            all_sprites.remove(player)


collision()


def main():
    screen_rect = screen.get_rect()

    run = True
    while run:
        clock.tick(60)

        keys = pygame.key.get_pressed()

        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                run = False

        if keys[pygame.K_SPACE]:
            if len(bullets) < 5:
                projectile.pos += projectile.velocityx
        if xor(keys[pygame.K_a], keys[pygame.K_LEFT]):
            player.pos -= player.velocityx
        elif xor(keys[pygame.K_d], keys[pygame.K_RIGHT]):
            player.pos += player.velocityx
        elif xor(keys[pygame.K_w], keys[pygame.K_UP]):
            player.pos -= player.velocityy
        elif xor(keys[pygame.K_s], keys[pygame.K_DOWN]):
            player.pos += player.velocityy

        player.rect.clamp_ip(screen_rect)

        draw_window()


main()

How can I make it so that a collision is detected and hence my player is removed from the game whilst the two sprites are moving?我如何才能检测到碰撞,从而在两个精灵移动时将我的玩家从游戏中移除?

You have to check if the player collides with an enemy in the main loop:您必须在主循环中检查玩家是否与敌人发生碰撞:

eg例如

run = True
hit_count = 0
while run:

    # [...]

    player.rect.clamp_ip(screen_rect)

    collidelist = pygame.sprite.spritecollide(player, enemies_list, False)
    if collidelist:
        hit_count += 1
        print("hit", hit_count)

    draw_window()

If you want to fins initial enemy positions, which are not "on" the player, you've to check for collision of a new enemy and the player before you add it to enemies_list respectively all_sprites :如果您想确定不在玩家“上”的初始敌人位置,则必须在将新敌人和玩家的enemies_list分别添加到enemies_list all_sprites之前检查新敌人和玩家的all_sprites

eg例如

def collision():
    score = 0

    while len(enemies_list) < 5:#
        enemy = Enemy((randint(0, 600), randint(0, 600)))
        if not pygame.sprite.collide_rect(enemy, player):
            enemies_list.add(enemy)
            all_sprites.add(enemy)

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

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