为了账号安全,请及时绑定邮箱和手机立即绑定

如何从屏幕上删除单个 pygame 绘图?

如何从屏幕上删除单个 pygame 绘图?

Smart猫小萌 2023-08-22 18:21:19
当大圆圈接触小圆圈时,我希望它接触的小圆圈从屏幕上消失。然而,我不知道你到底是如何删除 pygame 中的单个绘图的。我该如何解决这个问题?pygame有内置这个功能吗?from pygame import *import random as rdimport math as minit()screen = display.set_mode((800, 600))p_1_x = 200p_1_y = 200p_1_change_x = 0p_1_change_y = 0def p_1(x, y):    player_1 = draw.circle(screen, (0, 0, 0), (x, y), 15)def pick_up(x, y, xx, yy):    distance = m.sqrt(m.pow(xx - x, 2) + m.pow(yy - y, 2))    if distance < 19:        # I think the code to delete should go here        passdots = []locations = []for i in range(5):    x = rd.randint(100, 700)    y = rd.randint(100, 500)    locations.append((x, y))while True:    screen.fill((255, 255, 255))    for events in event.get():        if events.type == QUIT:            quit()        if events.type == KEYDOWN:            if events.key == K_RIGHT:                p_1_change_x = 1            if events.key == K_LEFT:                p_1_change_x = -1            if events.key == K_UP:                p_1_change_y += 1            if events.key == K_DOWN:                p_1_change_y -= 1        if events.type == KEYUP:            if events.key == K_RIGHT or K_LEFT or K_UP or K_DOWN:                p_1_change_x = 0                p_1_change_y = 0    p_1_x += p_1_change_x    p_1_y -= p_1_change_y    for i, locate in enumerate(locations):        dot = draw.circle(screen, (0, 0, 0), locate, 5)        dots.append(dot)        for l in enumerate(locate):            pick_up(p_1_x, p_1_y, locate[0], locate[1])    p_1(p_1_x, p_1_y)    display.update()
查看完整描述

2 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

你的代码是如此混乱且难以维护,首先我为球和点制作了 2 个类。我通过 检测碰撞pygame.Rect.colliderect,首先我制作 2 个矩形,然后检查碰撞,如下所示:


def pick_up(ball, dot):

    ball_rect = Rect( ball.x - ball.SIZE , ball.y - ball.SIZE , ball.SIZE*2, ball.SIZE*2)

    dot_rect = Rect( dot.x - dot.SIZE , dot.y - dot.SIZE , dot.SIZE*2, dot.SIZE*2)

    if ball_rect.colliderect(dot_rect): 

        return True

    return False

如果检测到碰撞,我将其从循环中的点数组中删除while:


for dot in dots:

    if pick_up(ball, dot): # if dot in range ball

            dots.remove(dot)

    dot.draw()

这是完整的来源:


from pygame import *

import random as rd


SCREEN_WIDTH = 800

SCREEN_HEIGHT = 600

NUMBER_OF_DOTS = 5


class Ball():

    SIZE = 15

    def __init__(self, x, y):

        self.x = x

        self.y = y

        

    def draw(self):

        draw.circle(screen, (0, 0, 0), (self.x, self.y), Ball.SIZE)

    def move(self, vx, vy):

        self.x += vx

        self.y += vy


class Dot():

    SIZE = 5    

    def __init__(self, x, y):

        self.x = x

        self.y = y

        

    def draw(self):

        draw.circle(screen, (0, 0, 0), (self.x, self.y), Dot.SIZE)



def pick_up(ball, dot):

    ball_rect = Rect( ball.x - ball.SIZE , ball.y - ball.SIZE , ball.SIZE*2, ball.SIZE*2)

    dot_rect = Rect( dot.x - dot.SIZE , dot.y - dot.SIZE , dot.SIZE*2, dot.SIZE*2)

    if ball_rect.colliderect(dot_rect): 

        return True

    return False




init()

screen = display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))


dots = []

ball = Ball(200,200)


# generate dots

for i in range(NUMBER_OF_DOTS):

    x = rd.randint(100, 700)

    y = rd.randint(100, 500)

    dots.append(Dot(x,y))


# the main game loop

while True:

    screen.fill((255, 255, 255))

    keys=key.get_pressed()


    for events in event.get():

        keys=key.get_pressed()

        if events.type == QUIT:

            quit()


    if keys[K_RIGHT]:

        ball.move(+1,0)

    if keys[K_LEFT]:

        ball.move(-1,0)

    if keys[K_UP]:

        ball.move(0,-1)

    if keys[K_DOWN]:

        ball.move(0,+1)


    for dot in dots:

        dot.draw()

        

        if pick_up(ball, dot):

                dots.remove(dot)


    ball.draw()

    display.update()

    time.delay(1) # Speed down

更新1:

PyGame 矩形碰撞 http://www.pygame.org/docs/ref/rect.html#pygame.Rect.colliderect


更新2:

我在 github 上做了一个 repo 并做了一些更改,

点是彩色的,新点的颜色是随机的,每当吃掉一个点时,球就会变大。

https://img1.sycdn.imooc.com//64e48c48000155c006080499.jpg

查看完整回答
反对 回复 2023-08-22
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

代码应该将其从locations列表中删除,以便将来不会重新绘制。你每一帧都清除屏幕,所以清除+不重画就是“删除”。


假设您修改pick_up()为仅返回 True 或 False:


def pick_up(x, y, xx, yy):

    result = False

    distance = m.sqrt(m.pow(xx - x, 2) + m.pow(yy - y, 2))

    if distance < 19:

        result = True              # It was picked

    return result

然后,当您迭代locations列表绘图并检查是否被拾取时,保存所拾取圆的索引,然后在locations第二步中将它们从列表中删除。使用两步形式意味着如果您在迭代列表时从列表中删除项目,则不必担心意外跳过项目。


p_1_x += p_1_change_x

p_1_y -= p_1_change_y

picked_up = []                           # empty list to hold "picked" items

for i, locate in enumerate(locations):

    dot = draw.circle(screen, (0, 0, 0), locate, 5)

    dots.append(dot)

    for l in enumerate(locate):

        if ( pick_up(p_1_x, p_1_y, locate[0], locate[1]) ):

            picked_up.append( i )        # save the index of anything "picked"


# remove any picked-up circles from the list

for index in sorted( picked_up, reverse=True ):   # start with the highest index first

    print( "Removing circle from location[%d]" % ( index ) )  # DEBUG

    del( locations[ index ] )


查看完整回答
反对 回复 2023-08-22
  • 2 回答
  • 0 关注
  • 140 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信