如何在pygam中循环图像精灵

2024-09-24 22:28:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望在游戏中使用pygame和python2.7.6版创建角色。我有一个简单的python脚本,它允许我创建一个窗口并将图像打印到屏幕上。这是成功的,但它只是一个静态图像。在

import pygame


class Game(object):
    def main(self, screen):

        #load first sprite to image for blit"
        image = pygame.image.load('sprites/sprite1.png')
        image2 = pygame.image.load('sprites/sprite2.png')
        image3 = pygame.image.load('sprites/sprite3.png')
        while 1:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
            if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                return

        screen.fill((200, 200, 200))
        screen.blit(image, (320, 240))
        pygame.display.flip()

if __name__ == '__main__':
    pygame.init()
    screen = pygame.display.set_mode((640, 480))
    Game().main(screen)

我希望创建一个更动态的图像,通过改变第一个精灵与第二个精灵,依此类推,至少三个精灵可能更多(如sprite1.pngsprite2.pngsprite3.png)。如何在给定的时间间隔过期后循环图像,例如:1秒1/2秒。。。在


Tags: 图像imageeventgameforifpngmain
3条回答

让我们从头开始,在编写游戏时,让渲染循环远离程序的主循环(处理窗口事件的主循环)是非常重要的。这样,即使在渲染过程中有东西卡住,窗口也不太可能变得无响应。在其他好处中,例如,人们可以调整大小,并以其他方式操作它,而不会中断图形线程。 web上有一些很好的教程,虽然我手头没有关于python的教程,SFML tutorials can teach you the right concepts可以在python中使用。在

随着公共服务的退出,当你已经将应用程序分割成不同的线程时,我们就剩下动画的问题了。非常简单的实现(当然不是最好的)是为每个图像生成一个单独的线程,该线程只会对类似的内容进行排序:

def shake_it():
  while True:
    time.sleep(3)
    #do rotation here

虽然这会很好地工作,但显然不是最好的解决方案,因为它非常不灵活。想象一下,现在你还想定期做些别的事情,比如让你的npc巡逻堡垒。这将需要另一个线程,这将很快升级到相当多的线程(这本身并不坏,但不是理想的效果)。在

因此,一个更通用的线程事件处理程序将起到拯救作用。一个类,它将控制所有需要以特定间隔执行的函数。然后,在这个额外的线程中,你将在循环中运行event_handler的一个实例,它将作为动画等动作的抽象。在

在评论中对@Puciek的建议稍微详细一点,可以使用一个循环,比如

import time

for img in [image, image1, image2]:
    screen.fill((200, 200, 200))
    screen.blit(img, (320, 240))
    time.sleep(1)    # sleep 1 second before continuing

要循环使用精灵图像,您应该只在循环中blit对应的图像。一个好的方法是将序列的所有图像放在一个图像中,并在程序启动时加载它。然后使用substream()函数获取要blitting的图像,这样您就可以将次表面的“窗口”绑定到整个图像中,并使用一些在循环中不断变化的变量。另一个问题是,如何控制频率,有几种方法,这里有一个简单的精灵动画例子。这是同一个有8个状态的sprite序列,以三种不同的FPS循环:初始-12 FPS(1/12秒暂停),然后1/3初始FPS=4 FPS(3/12秒暂停),1/12初始FPS=1 FPS(12/12=1秒暂停)。我发布了整个脚本,这样你就可以运行并查看它是如何工作的,只需将它与图像放在一个地方,然后运行脚本。 将此图像与脚本一起使用:

enter image description here

源代码:

import pygame, os
from pygame.locals import *

def Cycle(n, N) :           # n - current state, N - max number of states
    value = n+1 
    case1 = (value >= N) 
    case2 = (value < N)
    result = case1 * 0 + case2 * value
    return result

w = 600         # window size
h = 400
cdir = os.path.curdir       # current directory in terminal
states = 8      # number of sprite states

pygame.init()
DISP = pygame.display.set_mode((w, h))
BG = (36, 0, 36)        # background color
DISP.fill(BG)
band_1 = pygame.image.load(os.path.join(cdir, "band1.png")).convert()
K = 4           # global scale factor
band_1 = pygame.transform.scale(band_1, (K * band_1.get_width(), K * band_1.get_height()))
band_1.set_colorkey((0,0,0))
sw = K*8            # sprite width
sh = K*8            # sprite height
r0 = (100, 100, sw, sh)     # sprite 0 rectangle
r1 = (150, 100, sw, sh)     # sprite 1 rectangle
r2 = (200, 100, sw, sh)     # sprite 2 rectangle
s0 = 0          # initial state of sprite 0
s1 = 0          # initial state of sprite 1
s2 = 0          # initial state of sprite 2
t0 = 1          # main ticker
t1 = 1          # ticker 1
t2 = 1          # ticker 2
Loop_1 = True
FPS = 12
clock = pygame.time.Clock( ) 
while Loop_1 :
    clock.tick(FPS)
    DISP.fill(BG, r0)
    sprite_0 = band_1.subsurface((s0*sw, 0, sw, sh))
    DISP.blit(sprite_0, r0)
    s0 = Cycle(s0, states)
    if t1 == 3 :
        DISP.fill(BG, r1)
        sprite_1 = band_1.subsurface((s1*sw, 0, sw, sh))
        DISP.blit(sprite_1, r1)
        s1 = Cycle(s1, states)
        t1 = 0
    if t2 == 12 :
        DISP.fill(BG, r2)
        sprite_2 = band_1.subsurface((s2*sw, 0, sw, sh))
        DISP.blit(sprite_2, r2)
        s2 = Cycle(s2, states)
        t2 = 0
    for event in pygame.event.get( ):
        if event.type == QUIT : Loop_1 = False
        if event.type == KEYDOWN:
            if event.key == K_ESCAPE : Loop_1 = False
#   t0 = t0 + 1 
    t1 = t1 + 1 
    t2 = t2 + 1 
    pygame.display.update()

pygame.quit( )

相关问题 更多 >