终于忙完这段时间的项目、考证了,接下来将继续填之前的坑了。
书接上回【C++游戏程序】easyX图形库还原游戏《贪吃蛇大作战》(一)
本次将使得角色和AI动起来,实现键盘控制,同时使得AI可以动起来以及一些细节补充
一.角色控制
控制角色可以使用GetAsyncKeyState([in] int vKey)函数实时检测哪个按键被按下,具体的虚拟键码(部分)如下:
本次讲使用ASDW键来控制角色移动,具体代码如下:
int playerSpeedCol = 0;
int playerSpeedRow = 0;
int player_speed = 5; //角色移动速度
if (GetAsyncKeyState(0x57) && GetAsyncKeyState(0x41))
{
playerSpeedCol = -player_speed;
playerSpeedRow = -player_speed;
}
//上右
else if (GetAsyncKeyState(0x57) && GetAsyncKeyState(0x44))
{
playerSpeedCol = -player_speed;
playerSpeedRow = player_speed;
}
//下右
else if (GetAsyncKeyState(83) && GetAsyncKeyState(0x44))
{
playerSpeedCol = player_speed;
playerSpeedRow = player_speed;
}
//下左
else if (GetAsyncKeyState(83) && GetAsyncKeyState(0x41))
{
playerSpeedCol = player_speed;
playerSpeedRow = -player_speed;
}
//左
else if (GetAsyncKeyState(0x41))
{
playerSpeedRow = -player_speed;
playerSpeedCol = 0;
}
//下
else if (GetAsyncKeyState(83))
{
playerSpeedCol = player_speed;
playerSpeedRow = 0;
}
//右
else if (GetAsyncKeyState(0x44))
{
playerSpeedRow = player_speed;
playerSpeedCol = 0;
}
//上
else if (GetAsyncKeyState(0x57))
{
playerSpeedCol = -player_speed;
playerSpeedRow = 0;
}
else
{
if (playerSpeedRow > 0)
playerSpeedRow = player_speed;
if (playerSpeedCol > 0)
playerSpeedCol = player_speed;
if (playerSpeedRow < 0)
playerSpeedRow = -player_speed;
if (playerSpeedCol < 0)
playerSpeedCol = -player_speed;
}
根据按下的实际按键确定角色的移动方向,将值更新到角色的实例结构体中:
//赋值处理
int playerbody_x = player.x;
int playerbody_y = player.y;
player.x += playerSpeedRow;
player.y += playerSpeedCol;
最后就是尾部的处理,确保角色的头部在进行移动的时候,它的尾部也可以随时跟在身后:
//尾部处理
int x = player_body[0].x; //该变量在上一篇文章有定义,定义的是尾部的长度
int y = player_body[0].y; //该变量在上一篇文章有定义,定义的是尾部的长度
player_body[0].x = playerbody_x;
player_body[0].y = playerbody_y;
for (int i = 1; i < body_num; i++)
{
int a = 0, b = 0;
if (i % 2 == 1)
{
a = player_body[i].x;
b = player_body[i].y;
player_body[i].x = x;
player_body[i].y = y;
}
else
{
x = player_body[i].x;
y = player_body[i].y;
player_body[i].x = a;
player_body[i].y = b;
}
}
二.AI自主移动
AI移动的原理其实和角色的移动原理差不多,区别就在于需要使用一个随机函数来让AI自行随机移动,等到检测到角色靠近之后会自己主动逃避。首先是AI的随机移动:
int AiSpeedCol[Ai_num] = { 0 };
int AiSpeedRow[Ai_num] = { 0 };
srand((unsigned)time(NULL));
int count[Ai_num] = { 0 };
for (int i = 0; i < Ai_num; i++)
{
count[i] = rand() % 8;
if (count[i] == 0)
{
AiSpeedCol[i] = -player_speed;
AiSpeedRow[i] = -player_speed;
}
else if (count[i] == 1)
{
AiSpeedCol[i] = -player_speed;
AiSpeedRow[i] = player_speed;
}
else if (count[i] == 2)
{
AiSpeedCol[i] = player_speed;
AiSpeedRow[i] = player_speed;
}
else if (count[i] == 3)
{
AiSpeedCol[i] = player_speed;
AiSpeedRow[i] = -player_speed;
}
else if (count[i] == 4)
{
AiSpeedRow[i] = -player_speed;
AiSpeedCol[i] = 0;
}
else if (count[i] == 5)
{
AiSpeedCol[i] = player_speed;
AiSpeedRow[i] = 0;
}
else if (count[i] == 6)
{
AiSpeedRow[i] = player_speed;
AiSpeedCol[i] = 0;
}
else if (count[i] == 7)
{
AiSpeedCol[i] = -player_speed;
AiSpeedRow[i] = 0;
}
if (Ai[i].x >= map_wide - player_speed)
{
AiSpeedRow[i] = -player_speed;
}
else if (Ai[i].y >= map_hight - player_speed)
{
AiSpeedCol[i] = -player_speed;
}
else if (Ai[i].y <= player_speed)
{
AiSpeedCol[i] = player_speed;
}
else if (Ai[i].x <= player_speed)
{
AiSpeedRow[i] = player_speed;
}
for (int j = 0; j < body_num; j++)
{
if (Distance(player_body[j].x, player_body[j].y, Ai[i].x, Ai[i].y) < Ai[i].r + player_body[i].r + 20)
{
if (Ai[i].x < player_body[j].x)
{
AiSpeedRow[i] = -player_speed;
}
if (Ai[i].y < player_body[j].y)
{
AiSpeedCol[i] = -player_speed;
}
if (Ai[i].x > player_body[j].x)
{
AiSpeedCol[i] = player_speed;
}
if (Ai[i].y > player_body[j].y)
{
AiSpeedRow[i] = player_speed;
}
}
}
int m = Ai[i].x;
int n = Ai[i].y;
Ai[i].x += AiSpeedRow[i];
Ai[i].y += AiSpeedCol[i];
int x = Ai_body[i][0].x;
int y = Ai_body[i][0].y;
Ai_body[i][0].x = m;
Ai_body[i][0].y = n;
for (int j = 1; j < Ai_body_num[i]; j++)
{
int a = 0, b = 0;
if (j % 2 == 1)
{
a = Ai_body[i][j].x;
b = Ai_body[i][j].y;
Ai_body[i][j].x = x;
Ai_body[i][j].y = y;
}
else
{
x = Ai_body[i][j].x;
y = Ai_body[i][j].y;
Ai_body[i][j].x = a;
Ai_body[i][j].y = b;
}
}
}
这里需要注意的是AI会实时检测与角色的距离,角色靠的过近之后会自动原理:
int Distance(int x, int y, int x1, int y1)
{
return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
}
for (int j = 0; j < body_num; j++)
{
if (Distance(player_body[j].x, player_body[j].y, Ai[i].x, Ai[i].y) < Ai[i].r + player_body[i].r + 20)
{
if (Ai[i].x < player_body[j].x)
{
AiSpeedRow[i] = -player_speed;
}
if (Ai[i].y < player_body[j].y)
{
AiSpeedCol[i] = -player_speed;
}
if (Ai[i].x > player_body[j].x)
{
AiSpeedCol[i] = player_speed;
}
if (Ai[i].y > player_body[j].y)
{
AiSpeedRow[i] = player_speed;
}
}
}
以下是运行图:
在下一篇最后的文章中,将完成AI吃食物、角色吃AI等操作。