add Animation sample
This commit is contained in:
		
							parent
							
								
									4e3a32ec15
								
							
						
					
					
						commit
						5f31b12ee2
					
				|  | @ -1150,7 +1150,7 @@ static void ShowDemoWindowWidgets() | ||||||
|         ImGui::TreePop(); |         ImGui::TreePop(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (ImGui::TreeNode("Data Types")) |     if (ImGui::TreeNode("DataUtil Types")) | ||||||
|     { |     { | ||||||
|         // The DragScalar/InputScalar/SliderScalar functions allow various data types: signed/unsigned int/long long and float/double
 |         // The DragScalar/InputScalar/SliderScalar functions allow various data types: signed/unsigned int/long long and float/double
 | ||||||
|         // To avoid polluting the public API with all possible combinations, we use the ImGuiDataType enum to pass the type,
 |         // To avoid polluting the public API with all possible combinations, we use the ImGuiDataType enum to pass the type,
 | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ namespace easy2d | ||||||
| 
 | 
 | ||||||
| 		Animation( | 		Animation( | ||||||
| 			Duration duration,			/* 动画时长 */ | 			Duration duration,			/* 动画时长 */ | ||||||
| 			FramesPtr const& frames,	/* Ö¡¼¯ºÏ */ | 			FramesPtr const& frames,	/* ÐòÁÐÖ¡ */ | ||||||
| 			EaseFunc func = nullptr		/* 速度变化 */ | 			EaseFunc func = nullptr		/* 速度变化 */ | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ | ||||||
| 
 | 
 | ||||||
| namespace easy2d | namespace easy2d | ||||||
| { | { | ||||||
| 	// 帧集合
 | 	// ÐòÁÐÖ¡
 | ||||||
| 	class E2D_API Frames | 	class E2D_API Frames | ||||||
| 		: public virtual Object | 		: public virtual Object | ||||||
| 	{ | 	{ | ||||||
|  | @ -31,7 +31,7 @@ namespace easy2d | ||||||
| 		Frames(); | 		Frames(); | ||||||
| 
 | 
 | ||||||
| 		explicit Frames( | 		explicit Frames( | ||||||
| 			Array<ImagePtr> const& frames	/* 关键帧数组 */ | 			Array<ImagePtr> const& frames	/* ÐòÁÐÖ¡ */ | ||||||
| 		); | 		); | ||||||
| 
 | 
 | ||||||
| 		virtual ~Frames(); | 		virtual ~Frames(); | ||||||
|  |  | ||||||
|  | @ -1203,14 +1203,14 @@ namespace std | ||||||
| 	template<> | 	template<> | ||||||
| 	struct hash<::easy2d::String> | 	struct hash<::easy2d::String> | ||||||
| 	{ | 	{ | ||||||
| 		size_t operator()(const easy2d::String& key) const | 		inline size_t operator()(const easy2d::String& key) const | ||||||
| 		{ | 		{ | ||||||
| 			return key.hash(); | 			return key.hash(); | ||||||
| 		} | 		} | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 	template<> | 	template<> | ||||||
| 	void swap<::easy2d::String>(::easy2d::String& lhs, ::easy2d::String& rhs) | 	inline void swap<::easy2d::String>(::easy2d::String& lhs, ::easy2d::String& rhs) | ||||||
| 	{ | 	{ | ||||||
| 		lhs.swap(rhs); | 		lhs.swap(rhs); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -106,7 +106,7 @@ | ||||||
| //
 | //
 | ||||||
| 
 | 
 | ||||||
| #include "utils/Path.h" | #include "utils/Path.h" | ||||||
| #include "utils/Data.h" | #include "utils/DataUtil.h" | ||||||
| #include "utils/File.h" | #include "utils/File.h" | ||||||
| #include "utils/ResLoader.h" | #include "utils/ResLoader.h" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,20 +3,21 @@ | ||||||
| #pragma once | #pragma once | ||||||
| #include "common.h" | #include "common.h" | ||||||
| 
 | 
 | ||||||
| E2D_DECLARE_SMART_PTR(Man); | // 怪物
 | ||||||
| class Man | E2D_DECLARE_SMART_PTR(Monster); | ||||||
|  | class Monster | ||||||
| 	: public Sprite | 	: public Sprite | ||||||
| { | { | ||||||
| public: | public: | ||||||
| 	Man() | 	Monster() | ||||||
| 	{ | 	{ | ||||||
| 		// 加载图片
 | 		// 加载图片
 | ||||||
| 		Load(L"res/man.png"); | 		Load(L"res/akushu.png"); | ||||||
| 		// 缩小图片
 | 		// 缩小图片
 | ||||||
| 		SetScale(0.5f); | 		SetScale(0.7f); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// 每帧更新时
 | 	// 每帧渲染前执行 OnUpdate
 | ||||||
| 	void OnUpdate(Duration dt) override | 	void OnUpdate(Duration dt) override | ||||||
| 	{ | 	{ | ||||||
| 		// 获取输入设备
 | 		// 获取输入设备
 | ||||||
|  | @ -41,7 +42,7 @@ public: | ||||||
| 			this->Move(0, 2); | 			this->Move(0, 2); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// 按下鼠标左键,顺时针旋转小人
 | 		// 按下鼠标左键,顺时针旋转怪物
 | ||||||
| 		if (input.IsDown(MouseButton::Left)) | 		if (input.IsDown(MouseButton::Left)) | ||||||
| 		{ | 		{ | ||||||
| 			// 获取当前旋转角度
 | 			// 获取当前旋转角度
 | ||||||
|  | @ -50,7 +51,7 @@ public: | ||||||
| 			this->SetRotation(rotation + 2); | 			this->SetRotation(rotation + 2); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// 点击鼠标右键,隐藏或显示小人
 | 		// 点击鼠标右键,隐藏或显示怪物
 | ||||||
| 		if (input.WasPressed(MouseButton::Right)) | 		if (input.WasPressed(MouseButton::Right)) | ||||||
| 		{ | 		{ | ||||||
| 			// 获取当前显示状态
 | 			// 获取当前显示状态
 | ||||||
|  | @ -72,11 +73,11 @@ public: | ||||||
| 
 | 
 | ||||||
| 	Demo2() | 	Demo2() | ||||||
| 	{ | 	{ | ||||||
| 		// 创建人物
 | 		// 创建怪物
 | ||||||
| 		ManPtr man = new Man; | 		MonsterPtr monster = new Monster; | ||||||
| 		// 在屏幕上居中显示
 | 		// 在屏幕上居中显示
 | ||||||
| 		man->SetAnchor(0.5f, 0.5f); | 		monster->SetAnchor(0.5f, 0.5f); | ||||||
| 		man->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2); | 		monster->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2); | ||||||
| 
 | 
 | ||||||
| 		// 创建说明文字
 | 		// 创建说明文字
 | ||||||
| 		TextPtr text = new Text(L"按上下左右键移动\n按鼠标左键旋转\n点击鼠标右键隐藏"); | 		TextPtr text = new Text(L"按上下左右键移动\n按鼠标左键旋转\n点击鼠标右键隐藏"); | ||||||
|  | @ -88,7 +89,7 @@ public: | ||||||
| 		text->SetAlignment(TextAlign::Center); | 		text->SetAlignment(TextAlign::Center); | ||||||
| 
 | 
 | ||||||
| 		// 添加到场景
 | 		// 添加到场景
 | ||||||
| 		this->AddChild(man); | 		this->AddChild(monster); | ||||||
| 		this->AddChild(text); | 		this->AddChild(text); | ||||||
| 	} | 	} | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ public: | ||||||
| 	{ | 	{ | ||||||
| 		// 속潼稜있
 | 		// 속潼稜있
 | ||||||
| 		music = new Music; | 		music = new Music; | ||||||
| 		if (!music->Load(L"res/music.wav")) | 		if (!music->Load(L"res/splash.mp3")) | ||||||
| 		{ | 		{ | ||||||
| 			music = nullptr; | 			music = nullptr; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,192 @@ | ||||||
|  | // 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); | ||||||
|  | 	} | ||||||
|  | }; | ||||||
|  | @ -140,6 +140,7 @@ | ||||||
|     <ClInclude Include="Demo1.h" /> |     <ClInclude Include="Demo1.h" /> | ||||||
|     <ClInclude Include="Demo2.h" /> |     <ClInclude Include="Demo2.h" /> | ||||||
|     <ClInclude Include="Demo3.h" /> |     <ClInclude Include="Demo3.h" /> | ||||||
|  |     <ClInclude Include="Demo4.h" /> | ||||||
|     <ClInclude Include="include-forwards.h" /> |     <ClInclude Include="include-forwards.h" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|  |  | ||||||
|  | @ -9,5 +9,6 @@ | ||||||
|     <ClInclude Include="common.h" /> |     <ClInclude Include="common.h" /> | ||||||
|     <ClInclude Include="Demo2.h" /> |     <ClInclude Include="Demo2.h" /> | ||||||
|     <ClInclude Include="Demo3.h" /> |     <ClInclude Include="Demo3.h" /> | ||||||
|  |     <ClInclude Include="Demo4.h" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| </Project> | </Project> | ||||||
|  | @ -5,3 +5,4 @@ | ||||||
| #include "Demo1.h" | #include "Demo1.h" | ||||||
| #include "Demo2.h" | #include "Demo2.h" | ||||||
| #include "Demo3.h" | #include "Demo3.h" | ||||||
|  | #include "Demo4.h" | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ namespace | ||||||
| 		{ L"动画示例", Demo1::Create }, | 		{ L"动画示例", Demo1::Create }, | ||||||
| 		{ L"输入示例", Demo2::Create }, | 		{ L"输入示例", Demo2::Create }, | ||||||
| 		{ L"音频播放示例", Demo3::Create }, | 		{ L"音频播放示例", Demo3::Create }, | ||||||
|  | 		{ L"帧动画示例", Demo4::Create }, | ||||||
| 	}; | 	}; | ||||||
| 	int s_DemoIndex = 0; | 	int s_DemoIndex = 0; | ||||||
| 	int s_DemoNum = sizeof(s_Demos) / sizeof(Demo); | 	int s_DemoNum = sizeof(s_Demos) / sizeof(Demo); | ||||||
|  | @ -25,6 +26,7 @@ class DemoApp | ||||||
| public: | public: | ||||||
| 	DemoApp() | 	DemoApp() | ||||||
| 	{ | 	{ | ||||||
|  | 		ShowConsole(); | ||||||
| 		// 使用 Audio 组件
 | 		// 使用 Audio 组件
 | ||||||
| 		Use(&Audio::Instance()); | 		Use(&Audio::Instance()); | ||||||
| 
 | 
 | ||||||
|  | @ -39,7 +41,8 @@ public: | ||||||
| 
 | 
 | ||||||
| 	void ChangeDemoScene() | 	void ChangeDemoScene() | ||||||
| 	{ | 	{ | ||||||
| 		GetWindow()->SetTitle(s_Demos[s_DemoIndex].title); | 		String title = s_Demos[s_DemoIndex].title; | ||||||
|  | 		GetWindow()->SetTitle(title); | ||||||
| 
 | 
 | ||||||
| 		ScenePtr scene = s_Demos[s_DemoIndex].Create(); | 		ScenePtr scene = s_Demos[s_DemoIndex].Create(); | ||||||
| 		EnterScene(scene); | 		EnterScene(scene); | ||||||
|  | @ -48,8 +51,10 @@ public: | ||||||
| 		scene->AddListener(Event::KeyUp, Closure(this, &DemoApp::KeyPressed)); | 		scene->AddListener(Event::KeyUp, Closure(this, &DemoApp::KeyPressed)); | ||||||
| 
 | 
 | ||||||
| 		// 显示提示文字
 | 		// 显示提示文字
 | ||||||
| 		TextPtr intro = new Text(L"Key 1~3 to select demo"); | 		String intro_str = format_wstring(L"按键 1~%d 可切换示例\n", s_DemoNum); | ||||||
|  | 		TextPtr intro = new Text(intro_str + title); | ||||||
| 		intro->SetFontSize(16.f); | 		intro->SetFontSize(16.f); | ||||||
|  | 		intro->SetPosition(10, 10); | ||||||
| 		scene->AddChild(intro); | 		scene->AddChild(intro); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 81 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 702 KiB | 
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 28 KiB | 
		Loading…
	
		Reference in New Issue