首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Pygame删除对象

Pygame删除对象
EN

Stack Overflow用户
提问于 2020-07-30 09:47:49
回答 4查看 415关注 0票数 3

我需要帮助删除一个对象,我的意思是删除,而不是绘制或其他事情。到目前为止我的代码如下:

代码语言:javascript
运行
复制
def detect_collision(player_pos, enemy_pos):
    p_x = player_pos[0]
    p_y = player_pos[1]

    e_x = enemy_pos[0]
    e_y = enemy_pos[1]

    if (e_x >= p_x and e_x < (p_x + player_size)) or (p_x >= e_x and p_x < (e_x+enemy_size)):
        if (e_y >= p_y and e_y < (p_y + player_size)) or (p_y >= e_y and p_y < (e_y+enemy_size)):
            return True
    return False

def bullets():
    b_x = player_pos[0]
    b_y = player_pos[1]
    keep_going = True
    pygame.draw.rect(screen, TEAL, (b_x, b_y, 15, 50))
    while keep_going:
        b_y += 75
        if detect_collision(player_pos, enemy_pos):
            # deleting part here

这就是我的玩家和敌人的原因:

代码语言:javascript
运行
复制
enemy_size = 50
enemy_pos = [random.randint(0,WIDTH-enemy_size), 0]
enemy_list = [enemy_pos]


def drop_enemies(enemy_list):
    delay = random.random()
    if len(enemy_list) < 10 and delay < 0.1:
        x_pos = random.randint(0,WIDTH-enemy_size)
        y_pos = 0
        enemy_list.append([x_pos, y_pos])

def draw_enemies(enemy_list):
    for enemy_pos in enemy_list:
        pygame.draw.rect(screen, RED, (enemy_pos[0], enemy_pos[1], 
        enemy_size, enemy_size))

def update_enemy_positions(enemy_list, score):
    for idx, enemy_pos in enumerate(enemy_list):
        if enemy_pos[1] >= 0 and enemy_pos[1] < HEIGHT:
            enemy_pos[1] += SPEED
        else:
            enemy_list.pop(idx)
            score += 1
     return score

播放器部分:

代码语言:javascript
运行
复制
player_size = 50
player_pos = [WIDTH/2, HEIGHT-2*player_size]

pygame.draw.rect(screen, TEAL, (player_pos[0], player_pos[1], player_size, 
player_size))

所以,这就是我制造子弹,玩家和敌人的方式。请忽略其余的,因为我的帖子中有很多代码,所以需要它。

嗨,嗨,嗨

EN

回答 4

Stack Overflow用户

发布于 2020-07-30 10:46:51

解决问题的最好方法是学习如何使用Sprite objects in pygame。与Group对象一起,它们已经可以开箱即用地做你想做的事情了。

简而言之,您的“敌人”应该是某个Sprite子类的实例,您可以将其添加到Group的实例中(而不是构建您自己的enemy_list)。当你想要敌人死的时候,你可以对它调用kill()方法,这将把它从Group中删除。这用于将其从游戏中删除,因为您应该使用Group对象上的方法来更新和绘制它包含的所有精灵(但不是那些已被杀死的精灵)。

票数 2
EN

Stack Overflow用户

发布于 2020-07-30 10:52:26

查看Sprites和SpriteGroups来跟踪游戏中的实体将是有益的。他们有一堆内置的功能,可以让事情变得更容易。

这是我的一个演示,它对精灵进行分组,移除那些与鼠标指针冲突的精灵:

代码语言:javascript
运行
复制
import random
import pygame

screen_width, screen_height = 640, 480

def get_random_position():
    """return a random (x,y) position in the screen"""
    return (
        random.randint(0, screen_width - 1),  # randint includes both endpoints.
        random.randint(0, screen_height - 1),
    )

color_list = ["red", "orange", "yellow", "green", "cyan", "blue", "blueviolet"]
colors = [pygame.color.Color(c) for c in color_list]

class PowerUp(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        width, height = 64, 32
        self.color = random.choice(colors)
        self.image = pygame.Surface([width, height])
        self.image.fill(self.color)
        # Fetch the rectangle object that has the dimensions of the image
        self.rect = self.image.get_rect()
        # then move to a random position
        self.update()

    def update(self):
        # move to a random position
        self.rect.center = get_random_position()

if __name__ == "__main__":
    pygame.init()
    screen = pygame.display.set_mode((screen_width, screen_height))
    pygame.display.set_caption("Sprite Group Collision Demo")
    clock = pygame.time.Clock()  # for limiting FPS
    FPS = 60
    exit_demo = False

    # create a sprite group to track the power ups.
    power_ups = pygame.sprite.Group()
    for _ in range(10):
        power_ups.add(PowerUp())  # create a new power up and add it to the group.

    # main loop
    while not exit_demo:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit_demo = True
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    exit_demo = True
                elif event.key == pygame.K_SPACE:
                    power_ups.update()
            elif event.type == pygame.MOUSEBUTTONUP:
                for _ in range(10):
                    power_ups.add(PowerUp())

        # Update State: check for collisions
        for p in power_ups:
            if p.rect.collidepoint(pygame.mouse.get_pos()):
                power_ups.remove(p)
        # draw background
        screen.fill(pygame.Color("black"))  # use black background
        # draw sprites
        power_ups.draw(screen)
        # update screen
        pygame.display.update()
        clock.tick(FPS)
    pygame.quit()
    quit()

单击鼠标按钮可以创建更多的精灵,按空格键可以随机化它们的位置。

子弹精灵的update()方法会根据它的速度来调整精灵的位置,例如self.rect.x += SPEED,你需要在每个游戏循环中调用子弹精灵组的.update()方法。

票数 0
EN

Stack Overflow用户

发布于 2020-07-30 10:59:14

好的,所以你在enemy_list里有一份敌人位置的清单。这是一个很好的开始。我没有看到bullet_list,所以我假设一次只有一颗子弹,定位在b_xb_y

因此,此程序的主循环可能如下所示:

代码语言:javascript
运行
复制
### Main Loop
while not game_over:
    
    # handle user input

    # move the player
    # move the bullet (if any)
    # move the enemies

    # if there's a bullet, did it hit an enemy?
       # remove enemy hit from enemy_list

    # Did an enemy in enemy_list, hit the player?
       # do game-over

    # clear the screen
    # paint the player 
    # paint the bullet (if any)
    # paint every enemy in enemy_list

敌人的碰撞和列表的删除可能看起来像下面这样。(我已经尝试尽可能地匹配您的代码的外观。)

代码语言:javascript
运行
复制
# if a bullet is on-screen (non 0,0), see if it hits an enemy
if ( b_x != 0 and b_y != 0 ):
    hit_enemy_idx = None
    for idx, enemy_pos in enumerate( enemy_list ):
        # check for collision
        if detect_collision( ( b_x, b_y ), enemy_pos ):
            hit_enemy = idx      # note the enemy index
            b_x, b_y  = 0, 0     # erase the bullet
            break                # exit the loop when hit found

    # If the bullet hit an enemy, remove from list
    if hit_enemy_idx != None:
        del( enemy_list[ hit_enemy_idx ] )      # delete hit enemy from list

我们对敌人列表进行迭代,检查是否存在冲突。一旦发现命中,它将保存被命中的敌人的索引,并停止循环。

下一步是从列表中删除敌人。我在一个单独的代码块中编写了这段代码,而不是将它放在循环中的break之前。这是因为当您在迭代时更改列表时,可能会出现意想不到的结果。在这种特殊的情况下,它应该是可以的,但作为一个初学者,这是需要警惕的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63164953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档