python - 我无法让我的类(class)在 pygame 中工作

标签 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 和类(class)的新手,有人知道我是否错过了什么大事吗? Sprite 将随着箭头键移动,但不会改变图像。 谢谢!

最佳答案

除了您与事件 Sprite 和图像对象的比较不符合 True 之外,我还没有确定您的问题。

但我想给你一些提示,这些提示会导致评论过长,并且需要结构和代码突出显示 - 所以这里有一些在处理图形和类时的一般提示。

图片是资源,不是 Sprite ,永远不应该改变。

例如,一张图片通常只加载一次。
加载后,它应该放在那里,通常您不会将其作为要针对 检查的参数传递(要么是因为要比较的数据很多,要么可能会给您带来倾斜的结果,具体取决于对象正在比较)。

考虑以下修改:

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您认为自己有解决方案的地方 - 它并不完全有效 - 所以现在您要根据该解决方案提出问题。

我猜你以为你会复制一个 Sprite 的精确副本,这样你就可以比较它们了?

如果是这样,请放弃那个想法,因为那不是你的问题所在。
相反,在您的 Sprite /角色中保留静态图像,将您现在需要显示的资源加载到 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 自己跟踪计时;时间.时间()。尽管如此,您还是可以将正确答案合并到此代码中。

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

添加动画

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

enter image description here

考虑下图。
您只需为每帧分配一个特定区域,并在每次调用 def update() 时裁剪图像。

您可以通过以下方式实现此目的:

x = pygame.image.load(filename)
x.get_rect(x, y, width, height)

本质上是重复使用同一张图片,只是向用户展示该图片的不同区域。它的性能通常比必须在图形上下文中更改某些内容(即更改事件图像)要高得多。

因此,为了将来,考虑在处理动画时实现这一点。

祝你的项目好运,我希望它成功! :)

关于python - 我无法让我的类(class)在 pygame 中工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37681848/

相关文章:

python - (pyspark 中的简单映射分区作业

python - Django 在使用 matplotlib 示例时出错

Python:CVXPY 解算器错误

perl - 如何在 Perl 中使类的成员成为哈希?

python - 如何在 Python 中创建只读类属性?

python - 我如何让敌人死后掉落金钱?

python - 在pygame中将玩家 move 到鼠标位置

python - 阻塞直到新的副本集配置到位

未找到 PHP 类

python - 使用 Pygame 处理 MVC 模式中的动画