import pygame, sys, time, os, copy
from pygame.locals import *
forest = pygame.image.load('C:/Python32/PygameImages/forest.png')
rstill = pygame.image.load('C:/Python32/PygameImages/rstill.bmp')
lstill = pygame.image.load('C:/Python32/PygameImages/lstill.bmp')
bstill = pygame.image.load('C:/Python32/PygameImages/bstill.bmp')
fstill = pygame.image.load('C:/Python32/PygameImages/fstill.bmp')
lwalk1 = pygame.image.load('C:/Python32/PygameImages/lwalk1.bmp')
lwalk2 = pygame.image.load('C:/Python32/PygameImages/lwalk2.bmp')
rwalk1 = pygame.image.load('C:/Python32/PygameImages/rwalk1.bmp')
rwalk2 = pygame.image.load('C:/Python32/PygameImages/rwalk2.bmp')
fwalk1 = pygame.image.load('C:/Python32/PygameImages/fwalk1.bmp')
fwalk2 = pygame.image.load('C:/Python32/PygameImages/fwalk2.bmp')
bwalk1 = pygame.image.load('C:/Python32/PygameImages/bwalk1.bmp')
bwalk2 = pygame.image.load('C:/Python32/PygameImages/bwalk2.bmp')
class character():
def __init__(self, walk1, still, walk2):
self.sprite = sprite
self.walk1 = walk1
self.still = still
self.walk2 = walk2
def move(self, walk1, still, walk2, sprite):
timer = clock.tick()
if timer > 9:
if sprite == walk1:
self.sprite = still
elif sprite == still:
self.sprite = walk2
elif sprite == walk2:
self.sprite = walk1
pygame.init()
screen = pygame.display.set_mode((492,360))
background = forest
sprite = bstill
spritex = 240
spritey = 300
clock = pygame.time.Clock()
walk1 = fwalk1
walk2 = fwalk2
still = fstill
Character = character(walk1,still,walk2)
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if (event.key == K_LEFT):
spritex-=1
walk1 = copy.deepcopy(lwalk1)
walk2 = copy.deepcopy(lwalk2)
still = copy.deepcopy(lstill)
elif (event.key == K_RIGHT):
spritex+=1
walk1 = copy.deepcopy(rwalk1)
walk2 = copy.deepcopy(rwalk2)
still = copy.deepcopy(rstill)
elif (event.key == K_UP):
spritey-=1
walk1 = copy.deepcopy(fwalk1)
walk2 = copy.deepcopy(fwalk2)
still = copy.deepcopy(fstill)
elif (event.key == K_DOWN):
spritey+=1
walk1 = copy.deepcopy(bwalk1)
walk2 = copy.deepcopy(bwalk2)
still = copy.deepcopy(bstill)
Character.move(walk1, still, walk2, sprite)
screen.blit(background, (0,0))
screen.blit(Character.sprite, (spritex, spritey))
pygame.display.update()
我的程序从不运行character.move中的三个if语句中的任何一个(它确实运行了一个计时器)。我是pygame和课程的新手,有人知道我是否错过了任何大的东西?精灵将使用箭头键移动,但不会更改图像。 谢谢!
答案 0 :(得分:1)
我还没有找出你的问题,除了你的比较与活跃的精灵和图像对象没有加起来True
。
但是我想给你一些指示,这些指针可以用来评论,需要结构和代码突出显示 - 所以这里有一些关于做图形和类的一般提示。
例如,图像通常只能加载一次 一旦加载,它应该坐在那里,通常你不会将它作为一个参数传递给进行检查(或者因为要比较很多数据,或者它可能会给你偏差结果取决于被比较的对象)。
考虑以下修改:
class character():
def __init__(self, direction):
self.rstill = pygame.image.load('C:/Python32/PygameImages/rstill.bmp')
self.lstill = pygame.image.load('C:/Python32/PygameImages/lstill.bmp')
self.bstill = pygame.image.load('C:/Python32/PygameImages/bstill.bmp')
self.fstill = pygame.image.load('C:/Python32/PygameImages/fstill.bmp')
self.direction = direction
if self.direction == 'up':
self.sprite = self.fstill
elif ...
else ...
def move(self, direction):
if clock.tick() > 9: # No point in variable this unless you need to use it again.
if direction == self.direction:
self.sprite = self.fstill2
elif direction == 'down':
self.sprite = self.dstill
else ...
将图像资源加载到需要它们的类中,并保留较小的指针,例如它们移动的方向。
调试和更容易进行比较会更容易,有时甚至是Python。
不确定你想要做什么:
walk1 = copy.deepcopy(lwalk1)
walk2 = copy.deepcopy(lwalk2)
...
我认为这是一个XY Problem,您认为自己有一个解决方案 - 它没有完成任务 - 所以现在您根据该解决方案提出问题。
我猜你是否认为你复制了精灵的精确副本,这样可以让你比较它们?
如果是这种情况,请删除该想法,因为那不是您所处的位置。
相反,请在精灵/角色中保留静态图片,将您需要立即显示的资源加载到self.sprite
中,但与self.direction
进行比较。
我还会对每个帧的加载方式进行一些小改动,因为我猜测的是fwalk1
和fwalk2
是什么,两个应该模拟动画的帧?
你可以做到这一点,然后将其转化为有用的东西"将它们放在一个列表中并循环遍历它,并根据几个图像资源创建一个手动动画序列。
self.lwalk = [ret_bitmap('lwalk1.bmp'), ret_bitmap('lwalk2.bmp')]
self.rwalk = [ret_bitmap('rwalk1.bmp'), ret_bitmap('rwalk2.bmp')]
self.animation_frame = 0
理想情况下,您希望将运动分开,更新用户看到的内容并更改图像。这些是三个不同的任务,即使它们通常同时组合在一起。
def move(x, y):
# Should be in charge of moving the character and changing sprite
def update(direction):
# Should be in charge of animation updates etc.
def get_image():
# should return the current active frame/image (since you're working with animations)
如果你将它们全部结合起来,并调整我们修改过的内容并通过这里进行调整 您的类和代码应如下所示:
import pygame, sys, time, os, copy
from pygame.locals import *
def ret_bitmap(fname):
return pygame.image.load('C:/Python32/PygameImages/' + rstill.bmp)
class character():
def __init__(self, x=0, y=0, direction='up'):
self.rstill = [ret_bitmap('rstill.bmp')]
self.lstill = [ret_bitmap('lstill.bmp')]
self.bstill = [ret_bitmap('bstill.bmp')]
self.fstill = [ret_bitmap('fstill.bmp')]
self.lwalk = [ret_bitmap('lwalk1.bmp'), ret_bitmap('lwalk2.bmp')]
self.rwalk = [ret_bitmap('rwalk1.bmp'), ret_bitmap('rwalk2.bmp')]
self.fwalk = [ret_bitmap('fwalk1.bmp'), ret_bitmap('fwalk2.bmp')]
self.bwalk = [ret_bitmap('bwalk1.bmp'), ret_bitmap('bwalk2.bmp')]
self.direction = direction
self.animation_frame = 0
self.x, self.y = x, y
## == Load the first frame to show the user
## Note: We don't load the image, we load the list.
if self.direction == 'up':
self.sprite = self.fwalk
elif self.direction == 'down':
self.sprite = self.bwalk
elif self.direction == 'left':
self.sprite = self.lwalk
else:
self.sprite = self.rwalk
def move(self, direction):
self.direction = direction
if direction == 'left':
self.x -= 1
self.sprite = self.lwalk
elif direction == 'right':
self.x += 1
self.sprite = self.rwalk
elif direction == 'up':
self.y += 1
self.sprite = self.fwalk
else: # Down
self.y -= 1
self.sprite = self.bwalk
def update(self, direction):
if clock.tick() > 9:
self.animation_frame += 1
if self.animation_frame > len(self.sprite):
self.animation_frame = 0
def get_image(self):
return self.sprite[self.animation_frame]
pygame.init()
screen = pygame.display.set_mode((492,360))
clock = pygame.time.Clock()
Character = character(x=240, y=300, direction='down')
background = ret_bitmap('forest.png')
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if (event.key == K_LEFT):
Character.move('left')
elif (event.key == K_RIGHT):
Character.move('right')
elif (event.key == K_UP):
Character.move('up')
elif (event.key == K_DOWN):
Character.move('down')
Character.update() # Just updates the animation frame, if the time is right
screen.blit(background, (0,0))
screen.blit(Character.get_image(), (Character.x, Character.y))
pygame.display.update()
现在请记住,我没有安装Pygame
我可能已经包含了我认为DCA-
指出的原始问题与计时器有关。
我不完全确定计时器在Pygame中是如何工作的,因为我自己使用Pyglet,我通常会通过import time; time.time()
自行跟踪时间。从来没有,你可能会在这段代码中加入正确的答案。
或者开箱即用?谁知道:)。
有一种方法可以为同一个动画序列使用相同的位图 这可能被称为花哨的东西,我称之为"图像动画区域"。
请考虑以下图像
您只需为每个帧指定一个特定区域,然后在每次def update()
调用时裁剪图像。
您可以使用以下方法实现此目的:
x = pygame.image.load(filename)
x.get_rect(x, y, width, height)
并且基本上重复使用相同的图像,只是向用户显示该图像的不同区域。它的性能通常远高于必须在图形上下文中更改某些内容(即更改活动图像)。
因此,对于未来,请考虑在处理动画时实施。
祝你的项目好运,我希望它能成功! :)
答案 1 :(得分:0)
您的计时器在达到9之前被调用并重置
解决这个问题:
def move(self, walk1, still, walk2, sprite):
timer += clock.tick()
if timer > 9:
timer = 0
if sprite == walk1:
self.sprite = still
elif sprite == still:
self.sprite = walk2
elif sprite == walk2:
self.sprite = walk1
这将增加每帧的时间量,当总时间大于9时,它将传递if语句
您还必须在程序开头或类timer
中将__init__
初始化为0,例如
class character():
def __init__(self, walk1, still, walk2):
self.sprite = sprite
self.walk1 = walk1
self.still = still
self.walk2 = walk2
self.timer = 0
def move(self, walk1, still, walk2, sprite):
self.timer = clock.tick()
if self.timer > 9:
self.timer = 0
if sprite == walk1:
self.sprite = still
elif sprite == still:
self.sprite = walk2
elif sprite == walk2:
self.sprite = walk1
希望这有帮助