"""
俯视视角下的伪3D实现测试(切片堆叠法
"""
import pygame
import sys, pickle
from typing import List
from pygame.locals import *
class Sprites3D:
X, Y, Z = 0, 1, 2
def __init__(
self,
images: [], # 图像列表[image1, image2, ...] 从上到下
angle: [], # 角度列表 图片中心为中心,俯仰角度
position: [], # 位置 x, y
):
self.images = images
self.angle = angle
self.rect = self.images[-1].get_rect()
self.rect.center = position
self.height = len(self.images)
def set_face(self, image, width=15):
"""设置表情,接受一张高度、宽度与自身相同的图片"""
rect = image.get_rect()
images = self.images
range_x = range(rect[2])
range_w = range(87,95)
for index in range(len(images)): # 被替换的图片的索引
for x in range_x: # 表情的x轴位置
for width in range_w:
images[index].set_at((x, width), image.get_at((x, index)))
def update(self):
pass
def draw(self, screen):
h = self.height
angle = self.angle
shift = 0 # 每张图片向上的偏移量
for index in range(h-1, -1, -1):
image = self.images[index]
image = pygame.transform.rotate(image, angle[0])
# 俯仰
if -45 <= angle[1] <= 45:
shift += (angle[1] / 45) * 0.75
elif -90 <= angle[1] < -45:
shift += ((angle[1] + 45) / 45) * 0.25 - 0.75
elif 45 < angle[1] <= 90:
shift += ((angle[1] - 45) / 45) * 0.25 + 0.75
rect = image.get_rect()
image = pygame.transform.smoothscale(image,[rect[2], rect[3] * (1 - abs(angle[1] / 90))])
rect = image.get_rect()
rect.center = self.rect.centerx, self.rect.centery
rect.y += shift
screen.blit(image, rect)
# 颜色常量
WHITE = (255,255,255)
BLACK = (0,0,0)
size = width, height = 800,600
screen = pygame.display.set_mode(size)
pygame.display.set_caption("title")
clock = pygame.time.Clock()
delay = 60 # 延时计时器(1秒)
# 是否全屏
fullscreen = False
screen_change = False
# 背景颜色设定
bg_color = WHITE
running = True
# 伪3d对象
image_list = []
for i in range(12):
image_list.append(pygame.image.load("images/top.png"))
for i in range(75):
image_list.append(pygame.image.load("images/center.png"))
for i in range(13):
image_list.append(pygame.image.load("images/top.png"))
s3d = Sprites3D(image_list,[30,-50],[200,200])
s3d.set_face(pygame.image.load("images/face1.png"))
while running:
# 设定帧数
clock.tick(60)
# 延时计时器刷新
if delay == 0:
delay = 60
delay -= 1
# 检测是否全屏
if fullscreen and screen_change:
screen = pygame.display.set_mode(size,FULLSCREEN,HWSURFACE)
screen_change = False
elif screen_change:
screen = pygame.display.set_mode(size)
screen_change = False
# 事件检测
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
# 鼠标
if event.type == MOUSEBUTTONDOWN:
print(1)
# 按键按下事件
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
#F11切换全屏
if event.key == K_F11:
fullscreen = not fullscreen
screen_change = True
if event.key == K_UP:
print("up1")
if s3d.angle[1] > -85:
s3d.angle[1] -= 5
print("up2")
elif event.key == K_DOWN:
if s3d.angle[1] < 85:
s3d.angle[1] += 5
elif event.key == K_LEFT:
s3d.angle[0] -= 5
elif event.key == K_RIGHT:
s3d.angle[0] += 5
elif event.key == K_1:
s3d.set_face(pygame.image.load("images/face1.png"))
elif event.key == K_2:
s3d.set_face(pygame.image.load("images/face2.png"))
elif event.key == K_3:
s3d.set_face(pygame.image.load("images/face3.png"))
# 按键抬起事件
if event.type == KEYUP:
pass
#画背景
screen.fill(bg_color)
# 刷新xxx
s3d.update()
#画 xxxx
s3d.draw(screen)
# 刷新界面
pygame.display.update()