python - Pygame角色空闲动画
问题描述
我正在使用 Python 模块 Pygame 制作 2D 平台游戏。我已经为所述玩家制作了背景、角色和动作。您可以使用键盘上的 a & d 移动并使用 SPACE 跳跃。但是我无法弄清楚如何为玩家制作空闲动画。我有跑步动画,但我还没有制作精灵,所以我只是使用了空闲图片集。
这是我的代码:
import pygame, time, itertools
pygame.init()
# background image
walkRight = pygame.image.load('idle1.png')
walkLeft = pygame.image.load('idle1.png')
bg = pygame.image.load("background.png")
idle = [pygame.image.load('idle1.png'), pygame.image.load('idle2.png'), pygame.image.load('idle3.png')]
standcount = True
clock = pygame.time.Clock()
# jump
isJump = False
jumpcount = 10
# window
display_width = 1000
display_height = 600
win = pygame.display.set_mode((display_width, display_height))
# title & icon
pygame.display.set_caption("Grand Theft Ewok")
icon = pygame.image.load('bear.png')
pygame.display.set_icon(icon)
# player creds
x = 50
y = 430
vel = 10
# playerIMG
playerIMG = pygame.image.load('player.png')
def player(x, y):
global standcount
global walkcount
win.blit(bg, (0, 0))
# win.blit(playerIMG, (x,y))
if walkcount + 1 >= 9:
walkcount = 0
if standcount + 1 >= 9:
standcount = 0
if left:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
elif right:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
elif standcount:
p = 0
for frame in idle:
win.blit(idle[p], (x, y))
p += 1
if p >= 2:
p = 0
continue
pygame.display.update()
# game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# movement
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x > (vel - 25):
x -= vel
left = True
right = False
elif keys[pygame.K_d] and x < 835:
x += vel
right = True
left = False
else:
right = False
left = False
walkcount = 0
standcount = True
if not (isJump):
if keys[pygame.K_SPACE]:
isJump = True
left = False
right = False
else:
if jumpcount >= -10:
neg = 1
if jumpcount < 0:
neg = -1
y -= (jumpcount ** 2) * 0.5 * neg
jumpcount -= 1
else:
isJump = False
jumpcount = 10
player(x, y)
pygame.display.update()
pygame.quit()
在播放器功能下,您可以看到我尝试使用 for 循环的位置,但它不起作用。
我正在使用 Python 3.8。
向所有人致以最良好的祝愿。
待在室内,谢谢。
编辑 我发现了如何使用这个来制作空闲动画:
elif standcount:
p = 0
for frame in idle:
win.blit(idle[standcount], (x, y))
standcount += 1
#pygame.display.update()
if standcount >= 2:
standcount = 0
continue
pygame.display.update()
但是,它迭代列表的速度非常快。我想不出一种不使用 time.sleep 来减慢它的方法,因为每次我停止移动时它都会冻结游戏。
谢谢
解决方案
您不需要循环,只需执行与步行相同的操作即可:
if left:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
elif right:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
else:
win.blit(idle[standcount // 3], (x, y))
standcount += 1
使用循环意味着它将在同一帧中将所有图像相互叠加,这意味着您只会看到顶部/最后一个。您为步行动画所做的工作完美无缺。
另外,您应该只有一个pygame.display.update()
. 您应该只在每帧结束时更新屏幕,而不是在一帧中多次更新。由于您player()
在更新屏幕之前立即调用,因此您可以摆脱其中一个,因为一个不会做任何事情
所以我发现了问题,你有一个standcount = True
将它重置为 1,摆脱它解决了问题
这是编辑的完整代码:
import pygame, time, itertools
pygame.init()
# background image
walkRight = pygame.image.load('idle1.png')
walkLeft = pygame.image.load('idle1.png')
bg = pygame.image.load("background.png")
idle = [pygame.image.load('idle1.png'), pygame.image.load('idle2.png'), pygame.image.load('idle3.png')]
standcount = 0 # change it to an int, not a bool
clock = pygame.time.Clock()
# jump
isJump = False
jumpcount = 10
# window
display_width = 1000
display_height = 600
win = pygame.display.set_mode((display_width, display_height))
# title & icon
pygame.display.set_caption("Grand Theft Ewok")
icon = pygame.image.load('bear.png')
pygame.display.set_icon(icon)
# player creds
x = 50
y = 430
vel = 10
# playerIMG
playerIMG = pygame.image.load('player.png')
def player(x, y):
global standcount
global walkcount
win.blit(bg, (0, 0))
# win.blit(playerIMG, (x,y))
if walkcount + 1 >= 9:
walkcount = 0
if standcount + 1 >= 9:
standcount = 0
if left:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
elif right:
win.blit(idle[walkcount // 3], (x, y))
walkcount += 1
else:
win.blit(idle[standcount // 3], (x, y))
standcount += 1
pygame.display.update()
# game loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# movement
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and x > (vel - 25):
x -= vel
left = True
right = False
elif keys[pygame.K_d] and x < 835:
x += vel
right = True
left = False
#you could put standcount = 0 here to reset animation after walking
else:
right = False
left = False
walkcount = 0
#got rid of standcount = True
if not (isJump):
if keys[pygame.K_SPACE]:
isJump = True
left = False
right = False
else:
if jumpcount >= -10:
neg = 1
if jumpcount < 0:
neg = -1
y -= (jumpcount ** 2) * 0.5 * neg
jumpcount -= 1
else:
isJump = False
jumpcount = 10
player(x, y)
pygame.display.update()
pygame.quit()
至于速度:
有2个选项,
A)等待一段时间(我推荐)
B)等待一定数量的帧(不推荐)
最好做时间,因为性能不会影响速度
所以你已经有时间导入你可以这样做:
idle_frame_start = time.time() # get the current time - very accurate
walk_frame_start = time.time()
def player(x, y):
global standcount, idle_frame_start
global walkcount, walk_frame_start
# win.blit(playerIMG, (x,y))
if walkcount + 1 >= 4: #if the count is more than amount of images
walkcount = 0
if standcount + 1 >= 4:
standcount = 0
if left:
win.blit(idle[walkcount], (x, y))
if time.time() - walk_frame_start > 0.8:
walkcount += 1
walk_frame_start = time.time()
elif right:
win.blit(idle[walkcount], (x, y))
if time.time() - walk_frame_start > 0.8:
walkcount += 1
walk_frame_start = time.time()
else:
win.blit(idle[standcount], (x, y))
if time.time() - idle_frame_start > 0.8: # if the time difference is bigger than 0.8s
standcount += 1
idle_frame_start = time.time() # reset the start time
pygame.display.update()
推荐阅读
- wordpress - 如何在flutter中格式化api wordpress日期
- sql - 我如何防止一个用户具有相同的值
- schema.org - Schema.org 中组织提供的课程的讲师
- excel - 拆分列不适用于按钮
- python - 如何在转换函数中包含两个 lambda 操作?
- java - 在同一个线程中创建多个定时器会导致主线程滞后
- react-native - 在 React Native 中根据 Redux 状态显示或不显示标签栏项目
- php - Sentry:如何在 php 中配置 sentry?
- performance - EC2 中的响应极慢(宽度小于 100 个请求)
- java - 更改 RecyclerView 的所有项的 View 可见性