193 lines
3.7 KiB
C++
193 lines
3.7 KiB
C++
// Copyright (C) 2019 Nomango
|
|
|
|
#pragma once
|
|
#include "common.h"
|
|
|
|
// 老虎
|
|
E2D_DECLARE_SMART_PTR(Tiger);
|
|
class Tiger
|
|
: public Sprite
|
|
{
|
|
FramesPtr run_frames; // 跑步序列帧
|
|
FramesPtr stand_frames; // 站立序列帧
|
|
bool facing_left; // 面朝左或面朝右
|
|
bool running; // 是否正在跑步
|
|
Direction running_direction; // 跑步方向
|
|
|
|
public:
|
|
Tiger()
|
|
{
|
|
// 获取图片原始大小
|
|
ImagePtr image = new Image(L"res/tiger.png");
|
|
Size source_size = image->GetSize();
|
|
// 计算每帧图片大小
|
|
Size frame_size = { source_size.x / 5, source_size.y / 3 };
|
|
|
|
// 加载帧动画
|
|
run_frames = new Frames;
|
|
for (int i = 0; i < 6; ++i)
|
|
{
|
|
Point pos = { (i % 5) * frame_size.x, (i / 5) * frame_size.y };
|
|
ImagePtr frame = new Image(L"res/tiger.png", Rect{ pos, frame_size });
|
|
run_frames->Add(frame);
|
|
}
|
|
|
|
stand_frames = new Frames;
|
|
for (int i = 0; i < 6; ++i)
|
|
{
|
|
Point pos = { ((i + 1) % 5) * frame_size.x, ((i + 1) / 5 + 1) * frame_size.y };
|
|
ImagePtr frame = new Image(L"res/tiger.png", Rect{ pos, frame_size });
|
|
stand_frames->Add(frame);
|
|
}
|
|
|
|
// 执行动画
|
|
AddAction(
|
|
Tween::Animation(stand_frames)
|
|
.SetDuration(1000)
|
|
.SetLoops(-1)
|
|
);
|
|
|
|
// 添加按键监听
|
|
AddListener(Event::KeyDown, Closure(this, &Tiger::OnKeyDown));
|
|
AddListener(Event::KeyUp, Closure(this, &Tiger::OnKeyUp));
|
|
|
|
// 默认方向为 Left
|
|
facing_left = true;
|
|
running = false;
|
|
|
|
// 设置锚点
|
|
SetAnchor(0.5f, 0.5f);
|
|
}
|
|
|
|
void OnKeyDown(Event const& e)
|
|
{
|
|
if (e.key.code == KeyCode::Left)
|
|
Run(Direction::Left);
|
|
else if (e.key.code == KeyCode::Right)
|
|
Run(Direction::Right);
|
|
else if (e.key.code == KeyCode::Up)
|
|
Run(Direction::Up);
|
|
else if (e.key.code == KeyCode::Down)
|
|
Run(Direction::Down);
|
|
}
|
|
|
|
void OnKeyUp(Event const& e)
|
|
{
|
|
switch (e.key.code)
|
|
{
|
|
case KeyCode::Left:
|
|
case KeyCode::Right:
|
|
case KeyCode::Up:
|
|
case KeyCode::Down:
|
|
StopRun();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Run(Direction d)
|
|
{
|
|
if (!running)
|
|
{
|
|
running = true;
|
|
StopAllActions();
|
|
|
|
// 执行跑步动画
|
|
AddAction(
|
|
Tween::Animation(run_frames)
|
|
.SetDuration(500)
|
|
.SetLoops(-1)
|
|
);
|
|
}
|
|
|
|
running_direction = d;
|
|
if (running_direction == Direction::Left)
|
|
{
|
|
facing_left = true;
|
|
}
|
|
else if (running_direction == Direction::Right)
|
|
{
|
|
facing_left = false;
|
|
}
|
|
|
|
// 缩放可以调整图片显示方向
|
|
// 缩放至 -1 图片会反转
|
|
SetScaleX(facing_left ? 1.0f : -1.0f);
|
|
}
|
|
|
|
void StopRun()
|
|
{
|
|
if (running)
|
|
{
|
|
running = false;
|
|
StopAllActions();
|
|
|
|
// 执行站立动画
|
|
AddAction(
|
|
Tween::Animation(stand_frames)
|
|
.SetDuration(1000)
|
|
.SetLoops(-1)
|
|
);
|
|
}
|
|
}
|
|
|
|
void OnUpdate(Duration dt)
|
|
{
|
|
if (running)
|
|
{
|
|
// 计算移动距离
|
|
// OnUpdate 并不是一个稳定间隔执行的函数, 如果想实现稳定
|
|
// 每秒移动 150 像素, 应根据 dt 参数计算移动距离
|
|
const float moving_per_sec = 150;
|
|
const float distance = moving_per_sec * dt.Seconds();
|
|
|
|
switch (running_direction)
|
|
{
|
|
case Direction::Up:
|
|
Move(0, -distance);
|
|
break;
|
|
case Direction::Down:
|
|
Move(0, distance);
|
|
break;
|
|
case Direction::Left:
|
|
Move(-distance, 0);
|
|
break;
|
|
case Direction::Right:
|
|
Move(distance, 0);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
class Demo4
|
|
: public Scene
|
|
{
|
|
public:
|
|
static ScenePtr Create()
|
|
{
|
|
return new Demo4;
|
|
}
|
|
|
|
Demo4()
|
|
{
|
|
// 创建老虎
|
|
TigerPtr tiger = new Tiger;
|
|
// 在屏幕上居中显示
|
|
tiger->SetAnchor(0.5f, 0.5f);
|
|
tiger->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);
|
|
|
|
// 创建说明文字
|
|
TextPtr text = new Text(L"按上下左右键移动");
|
|
// 设置节点大小为文字布局大小
|
|
text->SetSize(text->GetLayoutSize());
|
|
// 设置文字位置
|
|
text->SetAnchor(0.5f, 0.5f);
|
|
text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT - 80);
|
|
text->SetAlignment(TextAlign::Center);
|
|
|
|
// 添加到场景
|
|
this->AddChild(tiger);
|
|
this->AddChild(text);
|
|
}
|
|
};
|