您好,欢迎来到年旅网。
搜索
您的当前位置:首页空洞武士1

空洞武士1

来源:年旅网

能帮到你的话,就给个赞吧 😘


animation.h

#pragma once
#include "atlas.h"
#include "timer.h"
#include "vector2.h"
#include "util.h"

#include <vector>
#include <functional>

class Animation {
	//兼容任意大小的图片
	struct Frame{
		Frame() = default;
		Frame(IMAGE* img, const Rect& src) : img(img), src(src) {}

		IMAGE* img = nullptr;
		Rect src;
	};
public:
	enum AnchorMode {
		Centered,				//居中
		BottomCentered			//底部居中
	};

public:
	Animation();
public:
	void play(int deltaT);								//播放
	void render();										//渲染

public:
	void setAnchorMode(const AnchorMode& anchorMode);
	void setPosition(const Vector2& position);
	void reset();
	void setIsLoop(bool isLoop);
	void setInterval(int interval);
	void setPlaybackTask(const std::function<void()>& playbackTask);

	void addFrames(IMAGE* img, int num);				//加载一张长条动画
	void addFrames(Atlas* atlas);						//加载一个图集

private:
	std::vector<Frame> frames;							//图集
	int index = 0;										//帧索引
	Timer timer;										//定时器——推动帧索引
	Vector2 position;									//动画位置

	bool isLoop = true;									//动画是否循环
	std::function<void()> playbackTask;					//播放完后的任务
	AnchorMode anchorMode = Centered;					//position位于图片的脚底还是中心
};

Animation::Animation(){

	timer.setIsOneShot(false);
	
	//定时器负责向前播放
	timer.setTimedTask([&] {

		index++;

		if (index == frames.size()) {

			index = isLoop ? 0 : frames.size() - 1;

			if (!isLoop && playbackTask)
				playbackTask();
		}
	});
}

void Animation::play(int deltaT){

	timer.timing(deltaT);

}

void Animation::render(){

	const auto& frame = frames[index];

	Rect dst;

	//position 位于 图片中心 or 底部
	dst.x = position.x - frame.src.w / 2;													
	dst.y = anchorMode == Centered ? position.y - frame.src.h / 2 : position.y - frame.src.h;

	dst.w = frame.src.w;
	dst.h = frame.src.h;

	putImageEx(frame.img, &dst, &frame.src);
}

void Animation::setAnchorMode(const AnchorMode& anchorMode){
	this->anchorMode = anchorMode;
}

inline void Animation::setPosition(const Vector2& position){
	this->position = position;
}

void Animation::reset() {
	index = 0;
	timer.reSet();
}

void Animation::setIsLoop(bool isLoop) {
	this->isLoop = isLoop;
}

void Animation::setInterval(int interval) {
	timer.setTimer(interval);
}

void Animation::setPlaybackTask(const std::function<void()>& playbackTask){
	this->playbackTask = playbackTask;
}

//加载一张长条动画
void Animation::addFrames(IMAGE* img, int num){
	auto frameWidth = img->getwidth() / num;
	auto frameHeight = img->getheight();

	for (auto i = 0; i < num; i++) {
		Rect src;

		src.x = i * frameWidth;
		src.y = 0;

		src.w = frameWidth;
		src.h = frameHeight;

		frames.emplace_back(img, src);
	}

}
//加载一个图集
void Animation::addFrames(Atlas* atlas){

	Rect src;

	for (auto i = 0; i < atlas->getSize(); i++) {

		auto img = atlas->getImage(i);
		auto frameWidth = img->getwidth();
		auto frameHeight = img->getheight();

		src.x = 0;
		src.y = 0;

		src.w = frameWidth;
		src.h = frameHeight;

		frames.emplace_back(img, src);
	}
}

vector2.h

#pragma once
#include <cmath>

class Vector2 {
public:
	Vector2() = default;
	Vector2(float x, float y);

public:
	const Vector2& operator+(const Vector2& other) const;
	const Vector2& operator-(const Vector2& other) const;
	float operator*(const Vector2& other) const;
	const Vector2& operator*(const float val) const;
	
	void operator+=(const Vector2& other);
	void operator-=(const Vector2& other);
	void operator*=(const float val);

public:
	float lenth();
	const Vector2& normalize() const;

public:
	float x = 0, y = 0;
};

timer.h

#pragma once
#include <functional>

class Timer {
public:
	Timer() = default;
	Timer(int timerMs, bool isOneShot, const std::function<void()>& timedTask);
public:
	void setTimer(int timerMs);										//设置定时时间
	void setIsOneShot(bool isOneShot);								//设置任务单次/循环触发
	void setTimedTask(const std::function<void()>& timedTask);		//设置定时任务
public:
	void pause();													//暂停
	void resume();													//恢复
	void reSet();													//重置
	void timing(int deltaT);										//计时

private:
	int timer = 0;													//定时时间
	int time = 0;													//计时器已经经过的时间

	bool isPause = false;
	bool isOneShot = false;											//任务是否只触发一次
	bool isShotted = false;											//任务是否已触发

	std::function<void()> timedTask;								//定时任务
};

atlas.h

#pragma once
#include <graphics.h>
#include <vector>
class Atlas {
public:
	void load(LPCTSTR path, int num);		//加载图集
	void addImage(const IMAGE& img);		//加载单张
	void clear();							//清空图集
public:
	int getSize() const;					//图集大小
	IMAGE* getImage(int i);					//返回图片

private:
	std::vector<IMAGE> imgs;
};

util.h

#pragma once
#include <graphics.h>

#pragma comment(lib, "MSIMG32.LIB")		//AlphaBlend
#pragma comment(lib, "WINMM.LIB")		//mp3

struct Rect{

	int x, y;
	int w, h;
};

//裁剪img任意大小的图并显示在任意处
	//src	裁剪
	//dst	缩放	
void putImageEx(IMAGE* img, const Rect* dst, const Rect* src = nullptr) {

	Rect src_{ 0, 0, img->getwidth(), img->getheight() };
	
	if (src)
		src_ = *src;
	
	//将(src_x, src_y), w, h 的图像 复制到 (dst_x, dst_y)处
	AlphaBlend(GetImageHDC(GetWorkingImage()),
		dst->x, dst->y, dst->w, dst->h,
		GetImageHDC(img),
		src_.x, src_.y, src_.w, src_.h,
		{ AC_SRC_OVER, 0, 255, AC_SRC_ALPHA });
}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- oldu.cn 版权所有 浙ICP备2024123271号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务