#include <iostream>
#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#include <string>
#include <vector>
using namespace std;
int idx_current_anim = 0;//人物动画的序数,从第一张开始
const int PLAYER_ANIM_NUM = 6;//人物动画一共有6张,这里要是const int,才能放入数组括号中
IMAGE img_player_left[PLAYER_ANIM_NUM];//把向左的人物动画放进图片数组中
IMAGE img_player_right[PLAYER_ANIM_NUM];//把向右的人物动画放进图片数组中
POINT player_pos = { 500,500 };//用POINT 类型存放人物的初始位置,player_pos.x=500,player_pos.y=500
int playerspeed = 10;//人物移动速度
#pragma comment(lib,"MSIMG32.LIB")//putimage不能处理透明度,要弄个能处理透明度的putimage函数
inline void putimage_alpha(int x, int y, IMAGE* img)
{
int w = img->getwidth();
int h = img->getheight();
AlphaBlend(GetImageHDC(NULL), x, y, w, h, GetImageHDC(img), 0, 0, w, h, { AC_SRC_OVER,0,255,AC_SRC_ALPHA });
}
void LoadAnimation()//图片的名称路径是有规律的,可以用循环来存放
{
for (size_t i = 0; i < PLAYER_ANIM_NUM; i++)
{
wstring path = L"img/player_left_" + to_wstring(i) + L".png";//wstring构建宽字符串path,用于表示动画帧文件的路径,使用L前缀来表示宽字符串,to_wstring函数将整数i转换为宽字符串
loadimage(&img_player_left[i], path.c_str());//c_str()函数将宽数组转换为c风格的字符串
}
for (size_t i = 0; i < PLAYER_ANIM_NUM; i++)
{
wstring path = L"img/player_right_" + to_wstring(i) + L".png";
loadimage(&img_player_right[i], path.c_str());
}
}
class Animation
{
public:
Animation(LPCTSTR path,int num,int interval)
{
interval_ms = interval;//切换帧的间隔
TCHAR path_file[256];
for (size_t i = 0; i < num; i++)
{
_stprintf_s(path_file, path, i);//把path和i结合起来拼成path_file
IMAGE* frame = new IMAGE();//用new开辟新内存
loadimage(frame, path_file);//加载这张图
frame_list.push_back(frame);//把这张图的指针放入vector容器中
}
}
~Animation()
{
for (size_t i = 0; i < frame_list.size(); i++)//清内存
delete frame_list[i];
}
void Play(int x, int y, int delta)
{
timer += delta;//每次调用play函数,计时器就增加对应时间,如果计时器到达帧间隔时间,那么就切换动画图片到下一帧,并重置计时器
if (timer >= interval_ms)
{
idx_frame = (idx_frame + 1) % frame_list.size();
timer = 0;
}
putimage_alpha(x, y, frame_list[idx_frame]);
}
private:
int timer = 0;//计时器
int idx_frame = 0;//动画帧索引
vector<IMAGE*> frame_list;
int interval_ms = 0;
};
int main()
{
initgraph(1280, 720);
bool running = true;
bool isup = false;
bool isdown = false;
bool isleft = false;
bool isright = false;
bool isturnleft = true;
bool isturnright = false;
IMAGE img_background;
loadimage(&img_background, _T("img/background.png"));
LoadAnimation();//记得调用存储人物图片的函数
ExMessage msg;
BeginBatchDraw();
while (running)
{
DWORD start_time = GetTickCount();//延时处理
while (peekmessage(&msg))
{
if (msg.message == WM_KEYDOWN)
{
switch (msg.vkcode)
{
case VK_UP:
isup = true;
break;//记得一定要有break,否则角色还是不会移动
case VK_DOWN:
isdown = true;
break;
case VK_LEFT:
isleft = true;
isturnleft = true;
isturnright = false;
break;
case VK_RIGHT:
isright = true;
isturnright = true;
isturnleft = false;
break;
}
}
else if (msg.message == WM_KEYUP)
{
switch (msg.vkcode)
{
case VK_UP:
isup = false;
break;
case VK_DOWN:
isdown = false;
break;
case VK_LEFT:
isleft = false;
break;
case VK_RIGHT:
isright = false;
break;
}
}
}
if (isup) player_pos.y -= playerspeed;//移动人物位置这段代码要放在while(peekmessage(&msg))循环之外,否则移动还是会卡顿
if (isdown) player_pos.y += playerspeed;
if (isleft) player_pos.x -= playerspeed;
if (isright) player_pos.x += playerspeed;
static int counter = 0;//计数器,游戏每运行5帧,切换一次人物图片
if (++counter % 5 == 0)
idx_current_anim++;
idx_current_anim = idx_current_anim % PLAYER_ANIM_NUM;//一组人物图片循环播放
DWORD end_time = GetTickCount();//延时处理
DWORD delta_time = end_time - start_time;
if (delta_time < 1000 / 144)
{
Sleep(1000 / 144 - delta_time);
}
cleardevice();
putimage_alpha(0, 0, &img_background);
if(isturnleft==true) putimage_alpha(player_pos.x, player_pos.y, &img_player_left[idx_current_anim]);//向左就put向左的人物图
if(isturnright==true) putimage_alpha(player_pos.x, player_pos.y, &img_player_right[idx_current_anim]);
FlushBatchDraw();
}
EndBatchDraw();
return 0;
}
/*
* 1.处理静态图片:创建IMAGE变量,用loadimage函数存储变量,用putimage函数呈现图片,注意如果要处理透明度,就要弄个putimage_alpha函数
* 2.处理动画:动画就是不断循环播放一组照片,比如每5帧游戏就切换一次人物图片,一组人物图片循环播放,这是数据处理部分,其它其实与处理静态图片一样,先是创建图片数组,
* 再借用for循环调用loadimage去存储图片,再用putimage呈现图片
* 3.角色移动:思路就是初始化角色位置,按键操控位置数据变化(定义角色移动速度),把角色位置数据传递给画出角色的函数。先用POINT初始化角色位置,再把这个变量的值传递给
* putimage函数
*/