peekmessage(用于接受信息)
exmessage(专门用于鼠标操作)
#include<graphics.h>
#include<string>
#include<vector>
using namespace std;
const int WINDOW_WIDTH = 1280;
const int WINDOW_HEIGHT = 720;
//封装了一个动画播放
class Animation
{
public:
Animation(LPCTSTR path, int num, int interval)//图片所来源的路径,图片的数量,图片播放之间的间隔 LP的含义使长指针, C的含义是const ,
{
interval_ms = interval;
TCHAR path_file[256];//TCHAR就是相当于根据我们系统在自己分配的字符串类型 这个自定义的含义是道路的文件
for (int i = 0; i < num; i++)//通过一个for循环将所有我们下载的图片都加载到一个图片数组中
{
_stprintf_s(path_file, path, i);//将文件名字打印在loadimage中
IMAGE* frame = new IMAGE();//定义一个图片指针 并且开辟这个图片指针
loadimage(frame, path_file);//加载这个图片
frame_list.push_back(frame);//有点类似于出队,或者出栈,就是数组向后移的意思
}
}
~Animation()//析构函数
{
for (int i = 0; i < frame_list.size(); i++)
delete frame_list[i];
}
void play(int x, int y, int delta)//动画播放
{
timer += delta;
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; //动画帧索引
int interval_ms = 0;
vector<IMAGE*> frame_list;//frame是图形的意思,图形列表
};
//输出图片函数
#pragma comment(lib, "MSIMG32.LIB")
inline void putimage_alpha(int x, int y, IMAGE* img)
{
int w = img->getheight();
int h = img->getwidth();
AlphaBlend(GetImageHDC(NULL), x, y, w, h,
GetImageHDC(img), 0, 0, w, h, { AC_SRC_OVER,0,225,AC_SRC_ALPHA });
}
//敌人类
class Enemy
{
public:
Enemy()
{
loadimage(&img_shadow, _T("img/shadow_enemy.png"));
anim_left = new Animation(_T("img/enemy_left_%d.png"), 6, 45);
anim_right = new Animation(_T("img/enemy_right_%d.png"), 6, 45);
//生成敌人边界
enum class SpawnEdge
{
Up = 0,
Down,
Left,
Right
};
//将敌人放置在地图外边界出的随机位置
SpawnEdge egde = (SpawnEdge)(rand() % 4);
switch (egde)
{
case SpawnEdge::Up:
position.x = rand() % WINDOW_WIDTH;
position.y = -FRAME_HEIGHT;
break;
case SpawnEdge::Down:
position.x = rand() % WINDOW_WIDTH;
position.y = WINDOW_HEIGHT;
break;
case SpawnEdge::Left:
position.x = -FRAME_WIDTH;
position.y = rand() % WINDOW_HEIGHT;
break;
case SpawnEdge::Right:
position.x = WINDOW_WIDTH;
position.y = rand() % WINDOW_HEIGHT;
break;
default:
break;
}
}
bool CheckBulletCollison(const Bullet& bullet)
{
return false;
}
bool CheckPlayerCollison(const Player& player)
{
return false;
}
void move(const Player& player)
{
const POINT& player_position = player.GetPosition();
int dir_x = player_position.x - position.x;
int dir_y = player_position.y - position.y;
double len_dir = sqrt(dir_x * dir_x + dir_y + dir_y);
if (len_dir != 0)
{
double normalize_x = dir_x / len_dir;
double normalize_y = dir_y / len_dir;
position.x += (int)(SPEED * normalize_x);
position.y += (int)(SPEED * normalize_y);
}
if (dir_x < 0)
facing_left = true;
else if (dir_x > 0)
facing_left = false;
}
void Draw(int delta)
{
int pos_shadow_x = position.x + (FRAME_WIDTH / 2 - SHADOW_WIDTH / 2);
int pos_shadow_y = position.y + FRAME_HEIGHT - 8;
putimage_alpha(pos_shadow_x, pos_shadow_y, &img_shadow);
if (facing_left)
anim_left->play(position.x, position.y, delta);
else
anim_right->play(position.x, position.y, delta);
}
~Enemy()
{
delete anim_left;
delete anim_right;
}
private:
const int SPEED = 2;
const int FRAME_WIDTH = 80;
const int FRAME_HEIGHT = 80;
const int SHADOW_WIDTH = 48;
bool is_move_right = false;
bool is_move_left = false;
private:
IMAGE img_shadow;
Animation* anim_left;
Animation* anim_right;
POINT position = { 0, 0 };
bool facing_left = false;
};
//子弹类
class Bullet
{
public:
POINT position = { 0, 0 };
public:
Bullet() = default;
~Bullet() = default;
void Draw() const
{
setlinecolor(RGB(255, 155, 50));
setfillcolor(RGB(200, 75, 10));
fillcircle(position.x, position.y, RADIUS);
}
private:
const int RADIUS = 10;//圆的半径
};
//玩家类
class Player
{
public:
Player()
{
loadimage(&img_shadow, _T("img/shadow_player.png"));
anim_left = new Animation(_T("img/player_left_%d.png"), 6, 45);
anim_right = new Animation(_T("img/player_right_%d.png"), 6, 45);
}
~Player()
{
delete anim_left;//释放空间
delete anim_right;
}
void ProcessEvent(const ExMessage& msg)//处理玩家的操作信息
{
switch (msg.message)
{
case WM_KEYDOWN:
switch (msg.vkcode)
{
case VK_UP:
is_move_up = true;
break;
case VK_DOWN:
is_move_down = true;
break;
case VK_LEFT:
is_move_left = true;
break;
case VK_RIGHT:
is_move_right = true;
break;
}
break;
case WM_KEYUP:
switch (msg.vkcode)
{
case VK_UP:
is_move_up = false;
break;
case VK_DOWN:
is_move_down = false;
break;
case VK_LEFT:
is_move_left = false;
break;
case VK_RIGHT:
is_move_right = false;
break;
}
break;
}
}
//处理玩家的移动
void Move()
{
int dir_x = is_move_right - is_move_left;
int dir_y = is_move_up - is_move_down;
double len_dir = sqrt(dir_x * dir_x + dir_y + dir_y);
if (len_dir != 0)
{
double normalize_x = dir_x / len_dir;
double normalize_y = dir_y / len_dir;
position.x += (int)(SPEED * normalize_x);
position.y += (int)(SPEED * normalize_y);
}
//防止玩家走出迷宫
if (position.x < 0)position.x = 0;
if (position.y < 0)position.y = 00;
if (position.x + FRAME_WIDTH > WINDOW_WIDTH) position.x = WINDOW_WIDTH - FRAME_WIDTH;
if (position.y + FRAME_HEIGHT > WINDOW_HEIGHT) position.y = WINDOW_HEIGHT - FRAME_HEIGHT;
}
//处理玩家的图形输出
void Draw(int delta)
{
int pos_shadow_x = position.x + (FRAME_WIDTH / 2 - SHADOW_WIDTH / 2);
int pos_shadow_y = position.y + FRAME_HEIGHT - 8;
putimage_alpha(pos_shadow_x, pos_shadow_y, &img_shadow);
static bool facing_left = false;
int dir_x = is_move_right - is_move_left;
if (dir_x < 0)
facing_left = true;
else if (dir_x > 0)
facing_left = false;
if (facing_left)
anim_left->play(position.x, position.y, delta);
else
anim_right->play(position.x, position.y, delta);
}
private:
const int SPEED = 3;
const int FRAME_HEIGHT = 80;//玩家图片高度
const int FRAME_WIDTH = 80;//玩家图片宽度
const int SHADOW_WIDTH = 32;//阴影宽度
private:
IMAGE img_shadow;
Animation* anim_left;
Animation* anim_right;
POINT position = { 500,500 };//初始化玩家的位置
bool is_move_up = false;
bool is_move_down = false;
bool is_move_left = false;
bool is_move_right = false;
};
int main()
{
initgraph(1280, 720);
bool runing = true;
Player player;
ExMessage msg;
IMAGE img_background;
vector<Enemy*> enemy_list;
loadimage(&img_background, _T("img/background.png"));
BeginBatchDraw();
while (runing)
{
DWORD start_time = GetTickCount();
while (peekmessage(&msg))
{
player.ProcessEvent(msg);
}
player.Move();
cleardevice();
putimage(0, 0, &img_background);
player.Draw(1000 / 144);
FlushBatchDraw();
DWORD end_time = GetTickCount();
DWORD delta_time = end_time - start_time;
if (delta_time < 1000 / 144)
{
Sleep(1000 / 144 - delta_time);
}
}
bool is_move_up = false;
bool is_move_down = false;
bool is_move_left = false;
bool is_move_right = false;
return 0;
}