我不能让我的班级在pygame中工作

时间:2016-06-07 14:15:24

标签: python class pygame

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和课程的新手,有人知道我是否错过了任何大的东西?精灵将使用箭头键移动,但不会更改图像。 谢谢!

2 个答案:

答案 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进行比较。

处理动画

我还会对每个帧的加载方式进行一些小改动,因为我猜测的是fwalk1fwalk2是什么,两个应该模拟动画的帧?

你可以做到这一点,然后将其转化为有用的东西"将它们放在一个列表中并循环遍历它,并根据几个图像资源创建一个手动动画序列。

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()自行跟踪时间。从来没有,你可能会在这段代码中加入正确的答案。

或者开箱即用?谁知道:)。

添加动画

有一种方法可以为同一个动画序列使用相同的位图 这可能被称为花哨的东西,我称之为"图像动画区域"。

enter image description here

请考虑以下图像 您只需为每个帧指定一个特定区域,然后在每次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

希望这有帮助