Pygame 2第一个投资组合游戏中发生冲突的问题

发布于 2025-02-09 19:51:17 字数 6534 浏览 1 评论 0原文

我创建了这个帐户只是为了问这个问题:DI Am Learning Python,对于我的投资组合,我正在尝试在Python中创建一些游戏。

我对碰撞有问题,什至不知道如何检查错误在哪里。

当球员的子弹不在屏幕上时,它们会尽可能消失,并且最多有3个子弹的限制器。所以我想这部分肯定是好的。

但是,当子弹的矩形符合格林外星的矩形时,它不会消失也不会减少外星人的HP,因为外星人不会消失...

我已经很沮丧,因为这个虫子阻止了我2天...我有游戏 main

文件:

2 如果重要的话,我使用vsc,

我的主体。

import pygame as pg
from static import *

pg.init()


# ------------- BACKGROUND AND LVL SETTINGS ------------- #
bg1 = Background(bg_img1scaled)
lvl = 1
red_enemies_count = 5
green_enemies_count = 5


# ------------- ENEMIES SETTINGS ------------- #
redEnemyList = [RedEnemy() for _ in range(red_enemies_count)]
greenEnemyList = [GreenEnemy() for _ in range(green_enemies_count)]


# ------------- GAME LOOP ------------- #
clock = pg.time.Clock()
run = True
while run:
    # FPS HANDLER
    clock.tick(FPS)

    # EVENT HANDLER
    for event in pg.event.get():
        if event.type == pg.QUIT:
            run = False
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_SPACE and len(p_bulletList) < 3:
                p_bulletList.append(P_Bullet())

        # ENEMY BEHAVIOR
    for red_enemy in redEnemyList:
        if red_enemy.x > 0 and red_enemy.x + red_enemy.img_width < WIDTH:
            red_enemy.x += red_enemy.speed
        if red_enemy.x + red_enemy.img_width >= WIDTH or red_enemy.x <= 0:
            red_enemy.speed = -red_enemy.speed
            red_enemy.x += red_enemy.speed

    for green_enemy in greenEnemyList:
        if green_enemy.x > 0 and green_enemy.x + green_enemy.img_width < WIDTH:
            green_enemy.x += green_enemy.speed
        if green_enemy.x + green_enemy.img_width >= WIDTH or green_enemy.x <= 0:
            green_enemy.speed = -green_enemy.speed
            green_enemy.x += green_enemy.speed
        if green_enemy.hp == 0:
            greenEnemyList.remove(green_enemy)

        # PLAYER'S BULLETS BEHAVIOR
    for bullet in p_bulletList:
        bullet.y -= P_BULLET_SPEED
        if bullet.y <= 0:
            p_bulletList.remove(bullet)

        if bullet.rect.colliderect(green_enemy.rect):
            green_enemy.hp -= 1
            p_bulletList.remove(bullet)

        # PLAYER MOVEMENT
    key_pressed = pg.key.get_pressed()
    if key_pressed[pg.K_UP] and (player_rect.y > 0):
        dy = -P_SPEED
        player_rect.y += dy
    if key_pressed[pg.K_DOWN] and (player_rect.y < HEIGHT - player_rect.height):
        dy = P_SPEED
        player_rect.y += dy
    if key_pressed[pg.K_LEFT] and (player_rect.x > 0):
        dx = -P_SPEED
        player_rect.x += dx
    if key_pressed[pg.K_RIGHT] and (player_rect.x < WIDTH - player_rect.width):
        dx = P_SPEED
        player_rect.x += dx

    # DISPLAY HANDLER
    window.fill(BLACK)
    bg1.draw_bg(window)

    for red_enemy in redEnemyList:
        red_enemy.draw_enemy(window)

    for green_enemy in greenEnemyList:
        green_enemy.draw_enemy(window)

    draw(window, player_scaled, player_rect)
    for bullet in p_bulletList:
        bullet.draw_bullet(window)

    pg.display.update()

pg.quit()

这是

import pygame as pg
import random

# ------------- COLORS ------------- #
BLACK = 0, 0, 0
WHITE = 255, 255, 255
RED = 255, 0, 0
GREEN = 0, 255, 0
BLUE = 0, 0, 255

# ------------- SCREEN SETTINGS ------------- #
WIDTH = 1200
HEIGHT = 800
window = pg.display.set_mode((WIDTH, HEIGHT))
FPS = 60

# ------------- IMAGES ------------- #
bg_img1 = pg.image.load('images/backgrounds/background_0.png')
bg_img1scaled = pg.transform.scale(bg_img1, (WIDTH, HEIGHT)).convert_alpha()

player_img = pg.image.load('images/player/player_ship.png')
player_scaled = pg.transform.scale(player_img,
                                   (player_img.get_width() * 0.5, player_img.get_height() * 0.5)).convert_alpha()


# ------------- PLAYER SETTINGS ------------- #
player_rect = player_scaled.get_rect()
player_rect.center = (WIDTH // 2, HEIGHT - player_rect.height // 2)
p_width = player_rect.width
p_heigh = player_rect.height
P_SPEED = 6
dx = 0
dy = 0
P_BULLET_SPEED = 10
max_p_bullets = 3
p_bulletList = []


# ------------- CLASSES ------------- #
class Background():
    def __init__(self, image):
        self.img = image
        self.x = 0
        self.y = 0

    def draw_bg(self, screen_var_name):
        screen_var_name.blit(self.img, (self.x, self.y))


class P_Bullet():
    def __init__(self):
        self.img = pg.image.load(
            'images/player/player_bullet2.png').convert_alpha()
        self.img_width = self.img.get_width()
        self.img_height = self.img.get_height()

        self.rect = self.img.get_rect()
        self.rect.x = player_rect.x + player_rect.width // 2 - self.img_width // 2
        self.rect.y = player_rect.y - self.img_height

        self.x = self.rect.x
        self.y = self.rect.y

    def draw_bullet(self, screen_var_name):
        screen_var_name.blit(self.img, (self.x, self.y))


class RedEnemy():
    def __init__(self):
        self.img = pg.image.load('images/enemies/red_alien.png')
        self.img_scaled = pg.transform.scale(self.img,
                                             (player_rect.width, player_rect.height)).convert_alpha()
        self.img_width = self.img_scaled.get_width()
        self.img_height = self.img_scaled.get_height()

        self.rect = self.img_scaled.get_rect()
        self.rect.x = random.randint(1, WIDTH - self.img_width)
        self.rect.y = random.randint(0, 170)

        self.x = self.rect.x
        self.y = self.rect.y

        self.speed = random.randint(3, 6)
        self.hp = 3

    def draw_enemy(self, screen_var_name):
        screen_var_name.blit(self.img_scaled, (self.x, self.y))


class GreenEnemy(RedEnemy):
    def __init__(self):
        self.img = pg.image.load('images/enemies/green_alien.png')
        self.img_scaled = pg.transform.scale(self.img,
                                             (player_rect.width, player_rect.height)).convert_alpha()
        self.img_width = self.img_scaled.get_width()
        self.img_height = self.img_scaled.get_height()

        self.rect = self.img_scaled.get_rect()
        self.rect.x = random.randint(1, WIDTH - self.img_width)
        self.rect.y = random.randint(270, 370)

        self.x = self.rect.x
        self.y = self.rect.y

        self.speed = random.randint(2, 4)
        self.hp = 2


# ------------- DEFs ------------- #
def draw(screen_var_name, img, rect: pg.Rect):
    screen_var_name.blit(img, rect)

I have created this account only to ask this question :D I am learning python and for my portfolio I am trying to create some game in OOP approach in python.

I have a problem with collisions and I don't even know how to check where the mistake is.

When player's bullets go offscreen, they disappear as they should and there is a limiter for max of 3 bullets. So I guess this part is good for sure.

But when bullet's rect meets green alien's rect, it doesn't disappear nor reduce alien's hp, because alien doesn't disappear...

I am already so frustrated, because this bug stopped me for 2 days... I have my game in 2 files: main.py and static.py for images, classes etc.

I think there is a problem in section #PLAYER'S BULLET BEHAVIOR in Main.py

Please, help :)

Ps. I use VSC if it matters

THIS IS MY Main.py:

import pygame as pg
from static import *

pg.init()


# ------------- BACKGROUND AND LVL SETTINGS ------------- #
bg1 = Background(bg_img1scaled)
lvl = 1
red_enemies_count = 5
green_enemies_count = 5


# ------------- ENEMIES SETTINGS ------------- #
redEnemyList = [RedEnemy() for _ in range(red_enemies_count)]
greenEnemyList = [GreenEnemy() for _ in range(green_enemies_count)]


# ------------- GAME LOOP ------------- #
clock = pg.time.Clock()
run = True
while run:
    # FPS HANDLER
    clock.tick(FPS)

    # EVENT HANDLER
    for event in pg.event.get():
        if event.type == pg.QUIT:
            run = False
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_SPACE and len(p_bulletList) < 3:
                p_bulletList.append(P_Bullet())

        # ENEMY BEHAVIOR
    for red_enemy in redEnemyList:
        if red_enemy.x > 0 and red_enemy.x + red_enemy.img_width < WIDTH:
            red_enemy.x += red_enemy.speed
        if red_enemy.x + red_enemy.img_width >= WIDTH or red_enemy.x <= 0:
            red_enemy.speed = -red_enemy.speed
            red_enemy.x += red_enemy.speed

    for green_enemy in greenEnemyList:
        if green_enemy.x > 0 and green_enemy.x + green_enemy.img_width < WIDTH:
            green_enemy.x += green_enemy.speed
        if green_enemy.x + green_enemy.img_width >= WIDTH or green_enemy.x <= 0:
            green_enemy.speed = -green_enemy.speed
            green_enemy.x += green_enemy.speed
        if green_enemy.hp == 0:
            greenEnemyList.remove(green_enemy)

        # PLAYER'S BULLETS BEHAVIOR
    for bullet in p_bulletList:
        bullet.y -= P_BULLET_SPEED
        if bullet.y <= 0:
            p_bulletList.remove(bullet)

        if bullet.rect.colliderect(green_enemy.rect):
            green_enemy.hp -= 1
            p_bulletList.remove(bullet)

        # PLAYER MOVEMENT
    key_pressed = pg.key.get_pressed()
    if key_pressed[pg.K_UP] and (player_rect.y > 0):
        dy = -P_SPEED
        player_rect.y += dy
    if key_pressed[pg.K_DOWN] and (player_rect.y < HEIGHT - player_rect.height):
        dy = P_SPEED
        player_rect.y += dy
    if key_pressed[pg.K_LEFT] and (player_rect.x > 0):
        dx = -P_SPEED
        player_rect.x += dx
    if key_pressed[pg.K_RIGHT] and (player_rect.x < WIDTH - player_rect.width):
        dx = P_SPEED
        player_rect.x += dx

    # DISPLAY HANDLER
    window.fill(BLACK)
    bg1.draw_bg(window)

    for red_enemy in redEnemyList:
        red_enemy.draw_enemy(window)

    for green_enemy in greenEnemyList:
        green_enemy.draw_enemy(window)

    draw(window, player_scaled, player_rect)
    for bullet in p_bulletList:
        bullet.draw_bullet(window)

    pg.display.update()

pg.quit()

THIS IS MY Static.py:

import pygame as pg
import random

# ------------- COLORS ------------- #
BLACK = 0, 0, 0
WHITE = 255, 255, 255
RED = 255, 0, 0
GREEN = 0, 255, 0
BLUE = 0, 0, 255

# ------------- SCREEN SETTINGS ------------- #
WIDTH = 1200
HEIGHT = 800
window = pg.display.set_mode((WIDTH, HEIGHT))
FPS = 60

# ------------- IMAGES ------------- #
bg_img1 = pg.image.load('images/backgrounds/background_0.png')
bg_img1scaled = pg.transform.scale(bg_img1, (WIDTH, HEIGHT)).convert_alpha()

player_img = pg.image.load('images/player/player_ship.png')
player_scaled = pg.transform.scale(player_img,
                                   (player_img.get_width() * 0.5, player_img.get_height() * 0.5)).convert_alpha()


# ------------- PLAYER SETTINGS ------------- #
player_rect = player_scaled.get_rect()
player_rect.center = (WIDTH // 2, HEIGHT - player_rect.height // 2)
p_width = player_rect.width
p_heigh = player_rect.height
P_SPEED = 6
dx = 0
dy = 0
P_BULLET_SPEED = 10
max_p_bullets = 3
p_bulletList = []


# ------------- CLASSES ------------- #
class Background():
    def __init__(self, image):
        self.img = image
        self.x = 0
        self.y = 0

    def draw_bg(self, screen_var_name):
        screen_var_name.blit(self.img, (self.x, self.y))


class P_Bullet():
    def __init__(self):
        self.img = pg.image.load(
            'images/player/player_bullet2.png').convert_alpha()
        self.img_width = self.img.get_width()
        self.img_height = self.img.get_height()

        self.rect = self.img.get_rect()
        self.rect.x = player_rect.x + player_rect.width // 2 - self.img_width // 2
        self.rect.y = player_rect.y - self.img_height

        self.x = self.rect.x
        self.y = self.rect.y

    def draw_bullet(self, screen_var_name):
        screen_var_name.blit(self.img, (self.x, self.y))


class RedEnemy():
    def __init__(self):
        self.img = pg.image.load('images/enemies/red_alien.png')
        self.img_scaled = pg.transform.scale(self.img,
                                             (player_rect.width, player_rect.height)).convert_alpha()
        self.img_width = self.img_scaled.get_width()
        self.img_height = self.img_scaled.get_height()

        self.rect = self.img_scaled.get_rect()
        self.rect.x = random.randint(1, WIDTH - self.img_width)
        self.rect.y = random.randint(0, 170)

        self.x = self.rect.x
        self.y = self.rect.y

        self.speed = random.randint(3, 6)
        self.hp = 3

    def draw_enemy(self, screen_var_name):
        screen_var_name.blit(self.img_scaled, (self.x, self.y))


class GreenEnemy(RedEnemy):
    def __init__(self):
        self.img = pg.image.load('images/enemies/green_alien.png')
        self.img_scaled = pg.transform.scale(self.img,
                                             (player_rect.width, player_rect.height)).convert_alpha()
        self.img_width = self.img_scaled.get_width()
        self.img_height = self.img_scaled.get_height()

        self.rect = self.img_scaled.get_rect()
        self.rect.x = random.randint(1, WIDTH - self.img_width)
        self.rect.y = random.randint(270, 370)

        self.x = self.rect.x
        self.y = self.rect.y

        self.speed = random.randint(2, 4)
        self.hp = 2


# ------------- DEFs ------------- #
def draw(screen_var_name, img, rect: pg.Rect):
    screen_var_name.blit(img, rect)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

Bonjour°[大白 2025-02-16 19:51:17

为什么需要.x.y属性?您有rect.xrect.y。无论如何,当您更改xy时,您还需要更改rect.xrect.y 。注意,bullet.Rect.Colliderect(green_enemy.Rect):使用green_enemy.Rect,但是green_enemy.x and code> green_enemy.yemy.yy.y 。 rectXyrect.xrect.y 当您更改Xy时,请勿神奇地更新。

在碰撞测试之前更新rect属性:

while run:
   # [...]

   for bullet in p_bulletList:
        bullet.y -= P_BULLET_SPEED
        if bullet.y <= 0:
            p_bulletList.remove(bullet)

        else:

            # update bullet.rect and green_enemy.rect
            bullet.rect.topleft = bullet.x, bullet.y
            green_enemy.rect.topleft = green_enemy.x, green_enemy.y

            if bullet.rect.colliderect(green_enemy.rect):
                green_enemy.hp -= 1
                p_bulletList.remove(bullet)

另请参见如何在Pygame中检测碰撞?

Why do you need the .x and .y attributes? You have rect.x and rect.y. Anyway, when you change x, and y you also need to change rect.x, and rect.y. Note, bullet.rect.colliderect(green_enemy.rect): uses green_enemy.rect, but green_enemy.x and green_enemy.y. rect is not tied to x and y, rect.x and rect.y don't magically update when you change x and y.

Update the rect attribute before the collision test:

while run:
   # [...]

   for bullet in p_bulletList:
        bullet.y -= P_BULLET_SPEED
        if bullet.y <= 0:
            p_bulletList.remove(bullet)

        else:

            # update bullet.rect and green_enemy.rect
            bullet.rect.topleft = bullet.x, bullet.y
            green_enemy.rect.topleft = green_enemy.x, green_enemy.y

            if bullet.rect.colliderect(green_enemy.rect):
                green_enemy.hp -= 1
                p_bulletList.remove(bullet)

See also How do I detect collision in pygame?.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文