问题描述
当大圆圈碰到小圆圈时,我希望它碰到的小圆圈从屏幕上消失。但是,我无法弄清楚如何在pygame中删除单个图形。如何解决此问题? pygame内置此功能吗?
from pygame import *
import random as rd
import math as m
init()
screen = display.set_mode((800,600))
p_1_x = 200
p_1_y = 200
p_1_change_x = 0
p_1_change_y = 0
def p_1(x,y):
player_1 = draw.circle(screen,(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
pass
dots = []
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,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()
解决方法
该代码应将其从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),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 ] )
,
您的代码是如此混乱且难以维护,首先,我为Balls&Dots编写了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,(self.x,self.y),Ball.SIZE)
def move(self,vx,vy):
self.x += vx
self.y += vy
class Dot():
SIZE = 5
def __init__(self,Dot.SIZE)
def pick_up(ball,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
Update1:
PyGame矩形碰撞 http://www.pygame.org/docs/ref/rect.html#pygame.Rect.colliderect