如何在 Pygame 中使用 Sprite Sheets 创建动画精灵? [英] How do I create animated sprites using Sprite Sheets in Pygame?

查看:132
本文介绍了如何在 Pygame 中使用 Sprite Sheets 创建动画精灵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我一直在测试这段代码,我找到了一个关于如何在 pygame 中添加 spritesheets 的教程,并决定尝试这个:

import os导入pygame类 SpriteSheet:def __init__(self, filename, px, py, tw, th, m, tile, color_key = None):self.sheet = pygame.image.load(文件名)如果颜色键:self.sheet = self.sheet.convert()self.sheet.set_colorkey(color_key)别的:self.sheet = self.sheet.convert_alpha()self.cells = [(px + tw * i, py, tw-m, th) for i in range(tiles)]self.index = 0定义更新(自我):self.tile_rect = self.cells[self.index % len(self.cells)]self.index += 1def draw(self, surface, x, y):rect = pygame.Rect(self.tile_rect)rect.center = (x, y)surface.blit(self.sheet, rect, self.tile_rect)pygame.init()窗口 = pygame.display.set_mode((400, 300))时钟 = pygame.time.Clock()sprite_sheet = SpriteSheet('awesomepossum sheet.bmp', 18, 580, 64, 66, 0, 6, (0, 128, 0))运行 = 真运行时:时钟滴答(10)对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:运行 = 错误sprite_sheet.update()window.fill(0)sprite_sheet.draw(window, *window.get_rect().center)pygame.display.update()pygame.quit()出口()

Sprite 表单

So I've been testing out this code, I found a tutorial on how I can add spritesheets in pygame and decided to try this one: https://www.spriters-resource.com/3ds/dragonballzextremebutoden/sheet/67257/

I did as the video said and counted the columns and rows, this is my code:

pygame.init()
CLOCK = pygame.time.Clock()
DS = pygame.display.set_mode((W, H))
FPS = 60

class spritesheet:
    def __init__(self, filename, cols, rows):
        self.sheet = pygame.image.load(filename).convert_alpha()

        self.cols = cols
        self.rows = rows
        self.totalCellCount = cols * rows

        self.rect = self.sheet.get_rect()
        w = self.cellWidth = self.rect.width / cols
        h = self.cellHeight = self.rect.height / rows
        hw, hh = self.cellCenter = (w / 2, h / 2)

        self.cells = list([(index % cols * w, index / cols * h, w, h) for index in range(self.totalCellCount)])
        self.handle = list([
            (0,0), (-hw, 0), (-w, 0),
            (0, -hh), (-hw, -hh), (-w, -hh),
            (0, -h), (-hw, -h), (-w, -h),])

    def draw(self, surface, cellIndex, x, y, handle = 0):
        surface.blit(self.sheet, 
        (x + self.handle[handle][0], y + self.handle[handle][1],
         self.cells[cellIndex][2], self.cells[cellIndex][3]))


s = spritesheet('Number18.png', 58, 6)

CENTER_HANDLE = 6

Index = 0

#mainloop
run = True
while run:

    s.draw(DS, Index % s.totalCellCount, HW, HH, CENTER_HANDLE)
    Index +=1

    #pygame.draw.circle(DS, WHITE, (HW, HW), 20, 10)
    DS.blit(bg,(0,0))

    pygame.display.update()
    CLOCK.tick(FPS)
    DS.fill(BLACK)

The line s = spritesheet("Number18.png", 58, 6) has the numbers 58, 6 which are basically the number of rows and columns I counted on this spritesheet block, but I'm getting problems such as the pygame window on "not responding", the image does not load up and I can't move the pygame screen.

解决方案

I'm getting problems such as the pygame window on "not responding", [...]

The fist thing what you've to do is to add en event loop to the main loop of the application.
pygame.event removes a pending event message from the queue and returns it. At least you should handle the QUIT event. Set the value of control variable for the main loop False:

run = True
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

The tiles in the sprite sheet don't have equal size. Limit the cells list to some parts of the sheet which have equal size.
Try the following:

class spritesheet:
    def __init__(self, filename, py, tw, th, tiles):
        self.sheet = pygame.image.load(filename).convert_alpha()

        self.py = py
        self.tw = tw
        self.th = th
        self.totalCellCount = tiles

        self.rect = self.sheet.get_rect()
        w, h = tw, th
        hw, hh = self.cellCenter = (w / 2, h / 2)

        self.cells = [(1+i*tw, self.py, tw-1, th-1) for i in range(tiles)]
        self.handle = list([
            (0,0), (-hw, 0), (-w, 0),
            (0, -hh), (-hw, -hh), (-w, -hh),
            (0, -h), (-hw, -h), (-w, -h),])

s = spritesheet('Number18.png', 1085, 80, 134, 8)


[...] the image does not load up [...]

Make sure that the image is located int the working directory of the application.
If you want to draw a sub-image of a spritsheet then you've to set the area parameter (3rd parameter) of pygame.Surface.blit to the rectangle area of the sub-image:

def draw(self, surface, cellIndex, x, y, handle = 0):
    hdl = self.handle[handle]
    surface.blit(self.sheet, (x + hdl[0], y + hdl[1]), area=self.cells[cellIndex])


[...] I can't move [...]

You have to change the position of the sprite. Handle the KEYDOWN event. Store the position of the sprite (px, py). Change the position when the K_UP, K_DOWN, K_LEFT or K_RIGHT key is pressed:

run = True
px, py, speed = HW, HH, 10
while run:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                py -= speed
            elif event.key == pygame.K_DOWN:
                py += speed
            elif event.key == pygame.K_LEFT:
                px -= speed
            elif event.key == pygame.K_RIGHT:
                px += speed


Minimal Sprite Sheet example:

import os
import pygame

class SpriteSheet:
    def __init__(self, filename, px, py, tw, th, m, tiles, color_key = None):
        self.sheet = pygame.image.load(filename)
        if color_key:
            self.sheet = self.sheet.convert()
            self.sheet.set_colorkey(color_key)
        else:
            self.sheet = self.sheet.convert_alpha()
        self.cells = [(px + tw * i, py, tw-m, th) for i in range(tiles)]
        self.index = 0

    def update(self):
        self.tile_rect = self.cells[self.index % len(self.cells)]
        self.index += 1

    def draw(self, surface, x, y):
        rect = pygame.Rect(self.tile_rect)
        rect.center = (x, y) 
        surface.blit(self.sheet, rect, self.tile_rect)

pygame.init()
window = pygame.display.set_mode((400, 300))
clock = pygame.time.Clock()

sprite_sheet = SpriteSheet('awesomepossum sheet.bmp', 18, 580, 64, 66, 0, 6, (0, 128, 0))

run = True
while run:
    clock.tick(10)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    sprite_sheet.update()

    window.fill(0)
    sprite_sheet.draw(window, *window.get_rect().center)
    pygame.display.update()
    
pygame.quit()
exit()

Sprite sheet form OpenGameArt.org:

这篇关于如何在 Pygame 中使用 Sprite Sheets 创建动画精灵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆