Pygame 移动一个对象
我正在尝试在pygame中简单地移动一个物体。我查了很多教程,但找到的全是怎么让它看起来像在下雪,哈哈。我试着把那个方法用在移动物体上,但一直没成功。我只想让一个物体在屏幕上移动,当它到达屏幕的边缘时,就重置位置再继续移动。所以我想把我在代码中放的两个多边形、线和圆形物体在屏幕上移动,无论是水平还是垂直移动都可以。
import pygame, sys, time, random
from pygame.locals import *
pygame.init()
windowSurface = pygame.display.set_mode((500, 400), 0, 32)
pygame.display.set_caption("Paint")
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
windowSurface.fill(WHITE)
pygame.draw.polygon(windowSurface,BLUE,((146, 0), (250, 100), (230, 265), (44, 250), (0,110)))
pygame.draw.polygon(windowSurface,RED,((70, 0), (150, 200), (0, 50)))
pygame.draw.line(windowSurface,BLACK,(60, 60), (120, 60), 8)
pygame.draw.circle(windowSurface, GREEN , (150,150), 15, 0)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
4 个回答
其实这并不难。首先,我们来解决你关于移动对象的问题:
import pygame, sys, time, random
from pygame.locals import *
pygame.init()
windowSurface = pygame.display.set_mode((500, 400), 0, 32)
pygame.display.set_caption("Paint")
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
windowSurface.fill(WHITE)
x, y = 250, 200
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
pressed = pygame.key.get_pressed()
if pressed[K_UP]: y - 5
if pressed[K_DOWN]: y + 5
if pressed[K_LEFT]: x - 5
if pressed[K_RIGHT]: x + 5
pygame.display.update()
pygame.draw.polygon(windowSurface,BLUE,((x - 104, y - 200), (x, y - 100), (x - 20, y + 65), (x - 206, y + 50), (x - 250, y - 90)))
pygame.draw.polygon(windowSurface,RED,((x - 180, y - 200), (x - 100, y), (x - 250, y - 150)))
pygame.draw.line(windowSurface,BLACK,(x - 190, y - 140), (x - 130, y - 140), 8)
pygame.draw.circle(windowSurface, GREEN , (x - 100, y - 50), 15, 0)
在上面的代码中,所有的坐标都被转换成了x和y这两个变量。当你按下方向键时,这些变量会发生变化,从而改变你形状的坐标和位置。
为了实现你想做的事情,你需要在“while True:”循环中有一些变化。下面是一个可以实现你目标的代码示例:
import pygame, sys, pygame.locals#1
pygame.init()#2
window=pygame.display.set_mode((500, 400), 0, 32)#3
pygame.display.set_caption("Paint")#4
BLACK = (0, 0, 0)#5
WHITE = (255, 255, 255)#6
RED = (255, 0, 0)#7
GREEN = (0, 255, 0)#8
BLUE = (0, 0, 255)#9
pentagon=pygame.Surface((250, 265))#10
pentagon.fill((0, 0, 0))#11
pygame.draw.polygon(pentagon, BLUE, ((146, 0), (250, 100), (230, 265), (44, 250), (0,110)))#12
pentagon.set_colorkey((0, 0, 0))#13
triangle=pygame.Surface((150, 200))#14
triangle.fill((0, 0, 0))#15
pygame.draw.polygon(triangle, RED, ((70, 0), (150, 200), (0, 50)))#16
triangle.set_colorkey((0, 0, 0))#17
line=pygame.Surface((60, 8))#18
line.fill(BLACK)#19
circle=pygame.Surface((30, 30))#20
circle.fill((0, 0, 0))#21
pygame.draw.circle(circle, GREEN , (15, 15), 15, 0)#22
circle.set_colorkey((0, 0, 0))#23
rects={'pentagon': pentagon.get_rect(), 'triangle': triangle.get_rect(), 'line': line.get_rect(), 'circle': circle.get_rect()}#24
rects['line'].centery=60#25
rects['line'].left=60#26
rects['circle'].centerx=150#27
rects['circle'].centery=150#28
while True:#29
for event in pygame.event.get():#30
if event.type==pygame.locals.QUIT:#31
pygame.quit()#32
sys.exit()#33
for rect in rects:#34
rects[rect].right+=1#35
if rects[rect].right>500:#36
if rect=='line':#37
rects['line'].centery=60#38
rects['line'].left=60#39
elif rect=='circle':#40
rects['circle'].centerx=150#41
rects['circle'].centery=150#42
else:#43
rects[rect].topleft=(0, 0)#44
window.fill(WHITE)#45
window.blit(pentagon, rects['pentagon'])#46
window.blit(triangle, rects['triangle'])#47
window.blit(line, rects['line'])#48
window.blit(circle, rects['circle'])#49
pygame.time.Clock().tick(40)#50
pygame.display.update()#51
我会尽量把这段代码解释得简单明了。
第1到第9行,你应该已经了解了。
第10行开始有一些你可能不太了解的内容。表面对象是一种矩形的图像,可以附加到其他任何表面上,或者用pygame.draw进行绘制。相信我,窗口其实也是一个表面。
第10行创建了一个表面,第11行把它填充为黑色,第12行在上面画了一个五边形。
第13行的作用是把所有黑色的像素变成透明。
第14到第17行,你应该现在能理解了。
第18行创建了一个新的表面对象用于线条,但没有在上面画线,而是把它填充为黑色并保持不变。这是因为,如果你看你旧程序中的线条,你会发现它其实就是一个矩形而已。
第20到第23行你应该能理解。
第24行创建了一个矩形的字典。矩形用来显示表面对象的位置,绘制它们到其他地方是必须的。
第25到第28行改变了线条和圆的位置。我这样做是因为我觉得你可能会喜欢,毕竟在你的程序中,线条和圆并不在左上角。
第29到第33行你应该能理解。
第34行开始一个循环,会遍历所有的矩形。
第35行把每个矩形的右边移动一个像素到右边。
第36行检查矩形的右边是否碰到了窗口的右边缘。
第37行检查碰到边的是不是线条,如果是的话,第38到39行就把它移动到你原来的位置。
第40行检查碰到边的是不是圆,如果是的话,第41到42行就把它移动到你原来的位置。
第43到44行把矩形放到左上角,也就是其他两个形状的起始位置。
第45行你应该知道。
第46到49行使用了surface.blit()函数。这个函数的第一个参数是一个表面,第二个参数是一个矩形。
第50行限制每秒最多只能有40帧通过。
第51行更新屏幕。
我真的希望这些解释对你有帮助,如果你觉得有用,请给我点赞或者接受我的回答,考虑到我写这些花了不少时间。如果你有任何问题,请随时问我。谢谢!
根据你的方法,是无法实现的。使用pygame的主要思路是每一帧都要把你想画的所有物体都画出来。你需要先把绘图的部分放到你的while True
循环里面。
因为你每一帧都在绘制所有内容,所以你可以:
- 创建一些变量,用来存储你物体的位置和方向
- 检查这个物体是否到达了屏幕的边缘
- 用新的位置来绘制你的多边形
所以最后,你可以得到类似这样的代码(你需要把它改成一个对象)
# ... pygame and app initialization
# get screen size
info = pygame.display.Info()
sw = info.current_w
sh = info.current_h
# initial position
x = y = 0
# initial direction
dx = 5
dy = 2
while True:
# update position with direction
x += dx
y += dy
# check bounds
if x - dx < 0 or x + dx > sw:
dx = -dx
if y - dy < 0 or y + dy > sh:
dy = -dy
# then draw and use x/y in your drawing instructions!
# ... pygame events ...