【发布时间】:2021-06-18 01:33:04
【问题描述】:
我尝试使用 for 循环,因此根据 Animations 类中的状态执行的每个动画都存储在属于 Player 类的实例变量中,即 self.images 与实例变量 self.original_image 匹配并且然后根据指定的角度旋转,但这不起作用,图片中的像素变得凌乱并漫无目的地旋转,很快pygame引发错误:pygame.error: Out of memory。其他的方法我也试过了,比如把原来的动画列表换成一个旋转的图片列表,但是结果是一样的。
import os
import sys
import math
import pygame
clock = pygame.time.Clock()
screen = pygame.display.set_mode((500, 500))
FPS = 60
class Animations:
def __init__(self):
self.frame = 0
self.animations_loop = []
self.animations_db = {}
@staticmethod
def search_png(path):
return [img for img in os.listdir(path) if img.endswith(".png")]
@staticmethod
def load_image(path):
img = pygame.image.load(path)
trans = pygame.transform.scale(img, (80, 80))
return trans
def load_images(self, path):
images = []
images_dir = self.search_png(path)
for image in images_dir:
load = self.load_image(f"{path}/{image}")
images.append(load)
return images
def load_animations(self, name, images, frame_durations, loop=True):
images = self.load_images(images)
if loop:
self.animations_loop.append(name)
data = []
for image in range(len(images)):
for _ in range(frame_durations):
data.append(images[image])
self.animations_db[name] = data
def get_animations(self):
return self.animations_db[self.state]
def set_state(self, new_state):
self.state = new_state
def frame_control(self):
if self.frame >= len(self.animations_db[self.state]):
self.frame = 0 if self.state in self.animations_loop else len(self.animations_db[self.state])
def frame_increase(self):
self.frame += 1
def play(self, screen, position):
self.frame_increase()
self.frame_control()
screen.blit(self.animations_db[self.state][self.frame-1], position)
class Player:
def __init__(self):
path = "..\..\sprites\sprite Rotoscoped zombie and soldier"
self.anim = Animations()
self.anim.load_animations("idle", f"{path}\soldier-idle", 4)
self.anim.load_animations("walk", f"{path}\soldier-walk", 4)
self.anim.set_state("idle")
self.images = self.anim.get_animations()
self.original_image = self.images
self.position = pygame.math.Vector2((200, 200))
self.rect = self.images[0].get_rect(center=self.position)
def move(self, up=False, down=False, right=False, left=False):
move = [0, 0]
if up:
move[1] = -2
elif down:
move[1] = 2
elif right:
move[0] = 2
elif left:
move[0] = -2
self.rect.x += move[0]
self.rect.y += move[1]
if move[0] != 0 or move[1] != 0:
self.anim.set_state("walk")
def rotate(self, mx, my):
for image in range(len(self.images)):
rel_x, rel_y = self.position[0] - mx, self.position[1] - my
angle = (180 / math.pi) * -math.atan2(rel_x, rel_y)
self.images[image] = pygame.transform.rotate(self.original_image[image], angle)
self.rect = self.images[0].get_rect(center=self.position)
def draw(self, screen):
self.anim.play(screen, (self.rect.x, self.rect.y))
# init
soldier = Player()
while True:
clock.tick(FPS)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYUP:
soldier.anim.set_state("idle")
mx, my = pygame.mouse.get_pos()
soldier.rotate(mx, my)
key_pressed = pygame.key.get_pressed()
if key_pressed[pygame.K_w]:
soldier.move(up=True)
elif key_pressed[pygame.K_s]:
soldier.move(down=True)
elif key_pressed[pygame.K_d]:
soldier.move(right=True)
elif key_pressed[pygame.K_a]:
soldier.move(left=True)
screen.fill((0, 0, 0))
soldier.draw(screen)
pygame.display.update()
【问题讨论】:
标签: python python-3.x pygame