微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

碰撞不会增加分数或移除射弹

如何解决碰撞不会增加分数或移除射弹

所以我目前有一个使用精灵组的敌人类和一个不使用精灵组的射弹类。

我检查了我的射弹与精灵组中的敌人的碰撞。如果敌人被击中,敌人的精灵会被移除,分数会增加,子弹也会从屏幕上移除。目前只有敌人的精灵被移除。

射弹类:

class Projectile():
    def __init__(self,x,y,width,height,speed,damage,image):
        # Variables for the player attacks (ranged)
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.speed = speed
        self.damage = damage
        self.image = image
        self.rect = self.image.get_rect()

    def draw(self,window):
        window.blit(self.image,(self.x,self.y))

    def checkCollision(self,bullet,enemy):
        col = pygame.sprite.spritecollide(bullet,enemy,True)
        if col == True:
            return True

敌人职业

class Enemy(pygame.sprite.Sprite):

    def __init__(self,mov_speed):
        # Variables for the varIoUs enemies
        pygame.sprite.Sprite.__init__(self)
        self.width = width
        self.height = height
        self.mov_speed = mov_speed
        self.image = speedboat_sprite
        self.rect = self.image.get_rect()
        self.rect.x = random.randint(64,734)
        self.rect.y = random.randrange(-1000,-100)
        self.hitBox = (
        self.rect.x + 22,self.rect.y + 15,19,45)  # Dimensions of the hitBox to make it close to the model
        self.end_reached = False
        self.alive = True

    def update(self):
        # This function lets the enemy go forward until the end of the screen
        max_distance = 800 - self.height
        if self.rect.y < max_distance:
            self.rect.y += self.mov_speed

        if self.rect.y >= max_distance:
            self.end_reached = True
            self.kill()

游戏循环中不起作用的代码

# Game logic here
game = True
whale = Player(334,650,128,128)  # Spawns the Player at the start of the game in the middle of the screen
speedboat_locations = (125,150,200,250,300,350,400,450,500,550,600,700,750,800)
speedboats = pygame.sprite.Group()
pirate_boss = Boss(1,1,256,50)
beams = []
cooldown = 0
wave_1 = 5
lives = 3
score = 0

while game:

    for event in pygame.event.get():  # this for-loop makes sure the game exits when clicking x
        if event.type == pygame.QUIT:
            game = False

    # Collision of attacks
    for beam in beams:
        hit = beam.checkCollision(beam,speedboats)
        if hit == True:
            score += 25
            beams.pop(beams.index(beam))

        if beam.y > 0:
            beam.y -= beam.speed  # This makes sure the bullet moves forward as long as it is not of the screen
            beam.rect.center = (beam.x,beam.y)
        else:
            beams.pop(beams.index(beam))  # If the bullet goes of the screen it gets removed from the list

完整代码

import pygame
import random

# Initialize game window here
pygame.init()

# Variables for the game window
window = pygame.display.set_mode((800,800))
pygame.display.set_caption('Sea Invaders')
clock = pygame.time.Clock()  # Adds the clock for spawn timers
message_font = pygame.font.SysFont('Calibri',36)

# Sprites,background and music
background = pygame.image.load('Background.jpg')
whale_sprite = pygame.image.load('Whale.png')
speedboat_sprite = pygame.image.load('Speedboat.png')
beam_sprite = pygame.image.load('Beam.png')
life_sprite = pygame.image.load('Life.png')
pirate_boss_sprite_right = pygame.image.load('Pirateboss_right.png')


# Classes
class Player():

    def __init__(self,height):
        # Variables for the Whale go here
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.mov_speed = 5
        self.hitBox = (self.x,self.y,self.width,self.height)

    def draw(self,window):
        # This function draws the whale using the sprite and the defined location in the class parameters
        window.blit(whale_sprite,self.y))
        self.hitBox = (self.x,self.height)
        # pygame.draw.rect(window,(255,0),self.hitBox,2) # HitBox check


class Enemy(pygame.sprite.Sprite):

    def __init__(self,45)  # Dimensions of the hitBox to make it close to the model
        self.end_reached = False
        self.alive = True

    def update(self):
        # This function lets the enemy go forward until the end of the screen
        max_distance = 800 - self.height
        if self.rect.y < max_distance:
            self.rect.y += self.mov_speed

        if self.rect.y >= max_distance:
            self.end_reached = True
            self.kill()

    def hit(self):
        self.kill()
        self.alive = False


class Boss():
    def __init__(self,mov_speed,hitpoints):
        # Variables for the boss objects
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.mov_speed = mov_speed
        self.hitpoints = hitpoints
        self.hitBox = (self.x + 30,self.y + 50,225,160)  # Dimensions of the hitBox to make it close to the model
        self.alive = True
        self.end_reached = False

    def draw(self,window):
        if self.alive:
            window.blit(pirate_boss_sprite_right,self.y))
            self.hitBox = (self.x + 30,160)
            pygame.draw.rect(window,(self.x + ((self.width / 2) - (self.hitpoints / 2)),self.y + 220,50,10))
            pygame.draw.rect(window,(0,255,self.hitpoints,10))

            # pygame.draw.rect(window,2)  # hitBox check

    def move(self):
        max_distance = 800 - self.height
        if self.x < (800 + self.width):
            self.x += self.mov_speed

        else:
            self.y += 100
            self.x = -51

        if self.y >= max_distance:
            self.alive = False
            self.end_reached = True

    def hit(self):
        print('hit')
        if self.hitpoints <= 0:
            self.alive = False


class Projectile():
    def __init__(self,enemy):

        bullet.rect.x = int(self.x)
        bullet.rect.y = int(self.y)

        return pygame.sprite.spritecollide(bullet,True)




class Hud():
    def __init__(self,sprite):
        self.x = x
        self.y = y
        self.sprite = sprite

    def draw(self,window):
        window.blit(self.sprite,self.y))


# Methods
def redrawGameWindow():
    window.blit(background,0))  # Loads in the background
    whale.draw(window)  # Draws the Whale in the game
    scoreboard = message_font.render(str(score),True,255))
    window.blit(scoreboard,(700,760))

    x_life = 0

    for life in range(lives):
        life = Hud(x_life,760,life_sprite)
        x_life += 25
        life.draw(window)

    if lives == 0:
        text = f'Game over! Your score: {score}.'
        game_over = message_font.render(text,0))
        window.blit(game_over,(200,200))

    if score >= 75:
        pirate_boss.draw(window)
        pirate_boss.move()

    speedboats.draw(window)
    speedboats.update()

    for fired_beam in beams:
        fired_beam.draw(window)
    pygame.display.update()  # This updates the above changes to the game window


# Game logic here
game = True
whale = Player(334,50)
beams = []
cooldown = 0
wave_1 = 5
lives = 3
score = 0

while game:

    for event in pygame.event.get():  # this for-loop makes sure the game exits when clicking x
        if event.type == pygame.QUIT:
            game = False

    # Life check
    for speedboat in speedboats:
        if speedboat.end_reached:  # if this is true we subtract a life
            lives -= 1  # We subtract lives with the enemies that reached the end

        if not speedboat.alive:
            speedboats.remove(speedboat)

    if pirate_boss.end_reached:
        lives = 0

    # Basic cooldown for the projectiles of the player
    if cooldown > 0:
        cooldown += 1
    if cooldown > 50:
        cooldown = 0

    # Collision of attacks
    for beam in beams:
        hit = beam.checkCollision(beam,speedboats)
        if hit == True:
            score += 25
            beams.pop(beams.index(beam))
        if pirate_boss.alive:
            if beam.y - beam.width < pirate_boss.hitBox[1] + pirate_boss.hitBox[3] and beam.y + beam.width > \
                    pirate_boss.hitBox[1]:
                if beam.x + beam.height > pirate_boss.hitBox[0] and beam.x - beam.height < pirate_boss.hitBox[0] + \
                        pirate_boss.hitBox[2]:
                    pirate_boss.hitpoints -= beam.damage
                    beams.pop(beams.index(beam))
                    pirate_boss.hit()

        if beam.y > 0:
            beam.y -= beam.speed  # This makes sure the bullet moves forward as long as it is not of the screen
            beam.rect.center = (beam.x,beam.y)
        else:
            beams.pop(beams.index(beam))  # If the bullet goes of the screen it gets removed from the list

    # --- PLAYER CONTROLS ---
    keys = pygame.key.get_pressed()

    if keys[pygame.K_LEFT] and whale.x > whale.mov_speed:
        # Makes sure the whale can move left
        # and prevents the whale from exiting the screen
        whale.x = whale.x - whale.mov_speed

    if keys[pygame.K_RIGHT] and whale.x < 800 - whale.mov_speed - whale.width:
        # Makes sure the whale can move right
        # and prevents the whale from exiting the screen
        whale.x = whale.x + whale.mov_speed

    if keys[pygame.K_SPACE] and cooldown == 0:
        # This block of code takes care of the beam-projectile the player can shoot
        if len(beams) < 3:
            beams.append(
                Projectile(round(whale.x + (whale.width // 2) - (32 // 2)),round(whale.y - (32 // 2)),32,2,10,beam_sprite))
            # The beam gets spawned at the whale X/Y Coordinate. To make the beam appear in the middle and at the
            # nose we add half the sprites width - half the width of the projectile to the for the x coordinate
            # and we use the y coordinate - half the length of the projectile to make the attack spawn at the top
        cooldown = 1

    # --- ENEMY SPAWNING ---
    # This block of code spawns the first wave of enemies
    for n in range(wave_1):
        speedboats.add(Enemy(64,64,1))
        wave_1 -= 1

    redrawGameWindow()

pygame.quit()

解决方法

我看不到绘图代码,所以我猜你还在画梁。使梁成为精灵组并在循环中执行此操作(不在梁类中)

pygame.sprite.groupcollide(beams,speedboats,True,True)

这将从各自的组中删除。

,

pygame.sprite.spritecollide 使用对象的 rect 属性来检测碰撞。然而,Projectile 对象的脚趾位置并未存储​​在 rect 中,而是存储在 xy 属性中。

在运行碰撞测试之前,用rectx属性更新y属性的位置:

class Projectile():
    # [...]

    def checkCollision(self,enemy):

        self.rect.x = int(self.x)
        self.rect.y = int(self.y)

        return any(pygame.sprite.spritecollide(self,enemy,True))
for beam in beams[:]:
    if beam.checkCollision(speedboats):
        score += 25
        beams.pop(beams.index(beam))

另外我推荐阅读How to remove items from a list while iterating?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。