Pygame 移动一个对象

2 投票
4 回答
29744 浏览
提问于 2025-04-17 08:01

我正在尝试在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 个回答

1

其实这并不难。首先,我们来解决你关于移动对象的问题:

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这两个变量。当你按下方向键时,这些变量会发生变化,从而改变你形状的坐标和位置。

2

为了实现你想做的事情,你需要在“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行更新屏幕。

我真的希望这些解释对你有帮助,如果你觉得有用,请给我点赞或者接受我的回答,考虑到我写这些花了不少时间。如果你有任何问题,请随时问我。谢谢!

2

根据你的方法,是无法实现的。使用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 ...

撰写回答