Ai
1 Star 0 Fork 1

落樱游云/MagicTower-Python

Create your Gitee Account
Explore and code with more than 13.5 million developers,Free private repositories !:)
Sign up
文件
Clone or Download
sprite.py 8.21 KB
Copy Edit Raw Blame History
oscarcx123 authored 2020-01-11 15:17 +08:00 . 增加显伤颜色
# 精灵基类 用来做基本显示/逻辑物理转换的模块
import pygame
from sysconf import *
# 逻辑坐标到物理坐标的转换 默认为RM的方式
temp_scale = BLOCK_UNIT
temp_freq = 4 # 行动一格需要的帧数 scale的倍数最好 不是也行
def temp_trans(pos): # 仿RM 临时游戏坐标到绝对坐标转换 代表的是 centerx, bottom
return [int((pos[0] + 4.5) * temp_scale), (pos[1] + 1) * temp_scale]
def rect_trans(rect): # 获取rect的当前物理坐标
return [rect.centerx, rect.bottom]
import threading
# 事件原型精灵 有皮的事件都能用
# 因为是原型精灵 与地图位置无关 内部坐标仅仅是rect 初始均为0,0
class EventSprite(pygame.sprite.Sprite):
def __init__(self, id, image, shape, face=None, animate=True):
"""
:param args:
id image shape [face:(x,y)] [dynamic:bool]
shape : h * w 动作类型数 * 动作帧数
"""
super().__init__()
self.id = id
self.src = image
self.shape = shape
self.face = [0, 0]
if face is not None:
self.face = face
self.animate = animate
self.animate_speed = 250
self.moving = False
self._dx = int(image.get_width() / shape[1]) # 宽度
self._dy = int(image.get_height() / shape[0]) # 高度
self.image = self.src.subsurface(self.face[1] * self._dx, self.face[0] * self._dy, self._dx, self._dy)
self.rect = self.image.get_rect()
self.move_t = None
self.frame_ct = 0
self.speed_x = 0
self.speed_y = 0
self.moving_frames = 0
def update(self, *args):
if self.moving_frames > 0:
self.moving_frames -= 1
self.rect.centerx += self.speed_x
self.rect.bottom += self.speed_y
if self.moving_frames == 0:
self.moving = False
if self.animate or self.moving:
ticks = args[0]
if ticks - self.frame_ct >= self.animate_speed:
# 运动频率可以通过 animate_speed修改?
self.frame_ct = args[0]
# print(self.frame_ct)
self.face[1] = (self.face[1] + 1) % 2 # self.shape[1]
# print(self.id, self.face, self.frame_ct)
elif self.face[1] % 2 == 1:
self.face[1] = (self.face[1] + 1) % self.shape[1]
self.image = self.src.subsurface(self.face[1] * self._dx, self.face[0] * self._dy, self._dx, self._dy)
def change_face(self, spdx, spdy):
if spdy > 0.1:
self.face[0] = 0
elif spdx < -0.1 and self.shape[0] > 1:
self.face[0] = 1
elif spdx > 0.1 and self.shape[0] > 2:
self.face[0] = 2
elif spdy < -0.1 and self.shape[0] > 3:
self.face[0] = 3
# 移动精灵:一般要给出目标位置(默认centerx,bottom)和时间,根据FPS屡次更新完成
# 实现: 一般在update里反复写 尝试过使用多线程异步完成 但没必要而且时间不好控制
def move(self, dst, time=100.):
if self.moving:
return False
diff_x = dst[0] - self.rect.centerx
diff_y = dst[1] - self.rect.bottom
frames = FPS * time / 1000
wtime = time / 1000 / frames
self.speed_x = diff_x / frames
self.speed_y = diff_y / frames
self.moving = True
self.change_face(diff_x, diff_y)
self.moving_frames = frames
return True
def move_directly(self, dst):
self.rect.centerx = dst[0]
self.rect.bottom = dst[1]
# 角色精灵类 用于动态的角色或者事件
class ActorSprite(pygame.sprite.Sprite):
def __init__(self, id, image, pos, size, *groups):
# id : actor id image:surface pos(逻辑xy) size(图像个数,[行数,列数])
super().__init__(*groups)
self.id = id
self.src = image
self.pos = pos
self.size = size
self.face = [0, 0] # 当前的图像(行号,列号)
self._dx = int(image.get_width() / size[0]) # 宽度
self._dy = int(image.get_height() / size[1]) # 高度
self.image = self.src.subsurface(self.face[1] * self._dx, self.face[0] * self._dy, self._dx, self._dy)
self.rect = self.image.get_rect()
self.rect.centerx, self.rect.bottom = temp_trans(pos)
self.moving = False
self._walk = 0
def update(self,*args): # TODO:坐标系
self.image = self.src.subsurface(self.face[1] * self._dx, self.face[0] * self._dy, self._dx, self._dy)
# self.rect = self.image.get_rect()
dst_pos = temp_trans(self.pos) # 目标的物理坐标
cur_pos = rect_trans(self.rect)
step = int(temp_scale / temp_freq) + int(((temp_scale % temp_freq) * 2 - 1) / temp_freq)
# 步长算法: 如果有余数且余数大于步长的一半 分配到每一步上 否则之后对齐
def shiftleg(): # 对齐变腿
self.face[1] = (self.face[1] + 1) % self.size[1]
# print("换腿", self.face[1])
def attention():
if self.face[1] % 2 == 0:
return
else:
shiftleg()
# 在一条轴上的移动 callback是进入对齐线前后的回调函数
def move_axis(cur, dst, step, block, callback=None):
"""
:param cur: 当前坐标
:param dst: 目标坐标
:param step: 步长
:param block: 块长
:param callback: 每次对齐后的函数
:return: 当前步长
"""
res = abs(cur - dst) % block # 块内剩余距离
if cur < dst:
diff = step
elif cur > dst:
diff = -step
else:
return 0
if 0 < res < 2 * step:
# 即将走入的区间
if callback is not None:
callback()
ldff = abs(res - abs(diff))
if ldff < step: # 走入对齐区
if diff < 0:
diff = -res
else:
diff = res
return diff
sx = move_axis(cur_pos[0], dst_pos[0], step, temp_scale) # , shiftleg)
sy = move_axis(cur_pos[1], dst_pos[1], step, temp_scale) # , shiftleg)
if self.moving:
self._walk += 1
if not self._walk < int(temp_freq / 2):
self._walk = 0
shiftleg()
if sx != 0 or sy != 0:
if not self.moving:
self.moving = True
self.rect.move_ip(sx, sy)
elif self.moving: # 停止立正:
# print("立正")
attention()
self.moving = False
def move(self, dir): # TODO:渐变 | 边界判断
if self.moving: # 移动中不接受新指令
return
if dir < self.size[0]:
self.face[0] = dir
if dir == 0:
self.pos[1] += 1
if dir == 1:
self.pos[0] -= 1
if dir == 2:
self.pos[0] += 1
if dir == 3:
self.pos[1] -= 1
# print(self.pos)
# self.update()
def move_directly(self, pos): # 瞬移
self.pos = pos
self.rect.centerx, self.rect.bottom = temp_trans(pos)
class Player(EventSprite):
def __init__(self):
from os import path
player_img = pygame.image.load(path.join(img_dir, "hero48.png"))
self.image = pygame.transform.scale(player_img, (64 * 4, 64 * 4))
# self.image.set_colorkey(WHITE)
super().__init__(0, self.image, [4, 4])
self.speedx = 0
self.speedy = 0
def update(self, *args):
self.speedx = 0
self.speedy = 0
keystate = pygame.key.get_pressed()
if keystate[pygame.K_LEFT]:
self.move([self.rect.centerx - BLOCK_UNIT, self.rect.bottom])
elif keystate[pygame.K_RIGHT]:
self.move([self.rect.centerx + BLOCK_UNIT, self.rect.bottom])
elif keystate[pygame.K_UP]:
self.move([self.rect.centerx, self.rect.bottom - BLOCK_UNIT])
elif keystate[pygame.K_DOWN]:
self.move([self.rect.centerx, self.rect.bottom + BLOCK_UNIT])
# else:
super().update(*args)
# print(keystate)
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/hxq40/MagicTower-Python.git
git@gitee.com:hxq40/MagicTower-Python.git
hxq40
MagicTower-Python
MagicTower-Python
master

Search