C/C++利用EasyX制作的简单乒乓球游戏
·
8月31写的,因为时间原因(在学YOLO),未写注释,有很多内容没写,有时间再补充,先贴vs2022项目文件和代码,自己配置环境依旧需要将“字符集”改成“多字节字符集”
9月5将球的y坐标及球y轴随机速度改为浮点型,范围为-2.5到2.5,解决bot跑出窗口的问题。
9月6添加大循环,可以重复游戏,不再修改没控制台的版本,需要自行修改,将球的y坐标及球y轴随机速度改为单精度浮点型
9月14添加注释并在显示获胜玩家时取消对鼠标消息的检测
1.vs2022文件
通过网盘分享的文件:C++游戏
链接: https://pan.baidu.com/s/1aJQb1ofMnmvrkd1sfXk8Sw?pwd=2n8w 提取码: 2n8w
2.代码,注释的printf语句是我测试用的
#include<graphics.h>//easyx的头文件
//#include<Windows.h>//Windows api的头文件,改成无cmd窗口运行需要
#include<time.h>//时间函数的头文件
#include<stdio.h>//输入输出函数的头文件
#define R 1//1表示向右,0表示向左
#define L 0//1表示向右,0表示向左
void keydown(struct Player& player);//键盘控制player1上下移动
int ballmove(struct Player& player1, struct Player& player2, struct Ball& ball);//球的移动
void bot(struct Player& player2, struct Ball& ball);//简单的机器人移动
struct Player {//玩家结构体,包含上下左右坐标
int lx;
int ly;
int rx;
int ry;
};
struct Ball {//球结构体,包含x坐标,y坐标,半径
int x;
float y;
int r;
};
bool RoL = R;//球的移动方向,R表示向右,L表示向左
float random_speed;//球的垂直移动速度
int main()
{
//游戏程序的主体部分
initgraph(400, 300);//创建一个400*300的窗口
Player player1;//player1为玩家,player2为机器人
Player player2;
Ball ball;//ball为球
clock_t starttime, endtime;//计时器
ExMessage m;//easyx的消息结构体
int temp;//用来接收ballmove函数的返回值
srand((unsigned)time(NULL));//用当前时间作为随机数种子
settextstyle(20, 10, "Consolas");//设置字体逻辑高度平均宽度和字体
BeginBatchDraw();//开始双缓冲
while (1)//开始游戏循环
{
player1 = { 0,100,5,149 };//初始化玩家和机器人的位置,球的位置
player2 = { 395,100,399,149 };
ball = { 5,122.0f,3 };
temp = 0;//初始化temp为0
while (1)//开始界面循环
{
cleardevice();//清屏
outtextxy(150, 100, "Start Game");//输出开始游戏
peekmessage(&m, EX_MOUSE | EX_KEY);//检测鼠标和键盘消息
if (m.x > 150 && m.x < 250 && m.y>100 && m.y < 120)//当鼠标在开始游戏的位置并且点击左键时,跳出循环,开始游戏
if (m.message == WM_LBUTTONDOWN)
{
break;
}
if (m.vkcode == 32 && m.message == WM_KEYDOWN)//空格的键码值为0x20即32,当按下空格键时,跳出循环,开始游戏
{
//printf("一%d\n", m.vkcode);
m.vkcode = 0x07;//将vkcode值设为一个不可能的值,防止误判
break;
}
FlushBatchDraw();//显示绘制的内容
}
starttime = clock();//开始计时
random_speed = (rand() % 51 - 25) / 10.0f;//初始化球的垂直移动速度,范围为-2.5到2.5
while (1)
{
cleardevice();//清屏
endtime = clock();//结束计时
if (endtime - starttime > 3)//每隔3毫秒操作一次
{
keydown(player1);//键盘控制player1上下移动
temp = ballmove(player1, player2, ball);//球的移动
bot(player2, ball);//简单的机器人移动
starttime = endtime;//重新开始计时
}
if (temp == 1)//当temp为1时,表示player2赢
{
outtextxy(150, 100, "Player2 Win");//输出player2赢
peekmessage(&m, EX_KEY);//检测键盘消息
if (m.vkcode == 32 && m.message == WM_KEYDOWN)//当按下空格键时,跳出循环,重新开始游戏
{
//printf("Player2 %d\n", m.vkcode);
m.vkcode = 0x07;//将vkcode值设为一个不可能的值,防止误判
break;
}
}
else if (temp == 2)//当temp为2时,表示player1赢
{
outtextxy(150, 100, "Player1 Win");//输出player1赢
peekmessage(&m, EX_KEY);//检测键盘消息
if (m.vkcode == 32 && m.message == WM_KEYDOWN)//当按下空格键时,跳出循环,重新开始游戏
{
//printf("Player1 %d\n", m.vkcode);
m.vkcode = 0x07;//将vkcode值设为一个不可能的值,防止误判
break;
}
}
else if (temp != 1 && temp != 2 && temp != 0)//当temp不为0,1,2时,表示程序出错
printf("%d\n", temp);
solidrectangle(player1.lx, player1.ly, player1.rx, player1.ry);//绘制玩家和机器人以及球
solidrectangle(player2.lx, player2.ly, player2.rx, player2.ry);
fillcircle(ball.x, ball.y, ball.r);
FlushBatchDraw();//显示绘制的内容
}
}
EndBatchDraw();//结束双缓冲
closegraph();//关闭图形窗口
return 0;
}
void keydown(struct Player& player)
{
if (GetAsyncKeyState('W'))//当按下W键时,player1向上移动
{
if (player.ly != 0)//防止player1移出屏幕
{
player.ly--;
player.ry--;
}
}
if (GetAsyncKeyState('S'))//当按下S键时,player1向下移动
{
if (player.ly != 250)//防止player1移出屏幕
{
player.ly++;
player.ry++;
}
}
}
int ballmove(struct Player& player1,struct Player& player2,struct Ball& ball)
{
if (ball.x + ball.r < 400 && RoL == R)//当球没有移出屏幕且向右移动时
{
if (ball.x + ball.r >= player2.lx)//当球的右边缘到达player2的左边缘y坐标时
{
if (ball.y > player2.ly && ball.y < player2.ry)//当球的y坐标在player2的上下边缘之间时,表示player2接到球
{
//printf("%d", RoL);
RoL = L;//改变球的移动方向
random_speed = (rand() % 51 - 25) / 10.0f;//改变球的垂直移动速度,范围为-2.5到2.5
}
}
ball.x++;//球向右移动
}
else if (RoL == R)//当球向右移出屏幕,表示player1赢(设定上不可能)
{
//printf("1继续%d\n", ball.y);
return 2;
}
else if (ball.x - ball.r >= 0 && RoL == L)//当球没有移出屏幕且向左移动时
{
if (ball.x - ball.r <= player1.rx)//当球的左边缘到达player1的右边缘y坐标时
{
if (ball.y > player1.ly && ball.y < player1.ry)//当球的y坐标在player1的上下边缘之间时,表示player1接到球
{
RoL = R;//改变球的移动方向
//printf("%d", RoL);
random_speed = (rand() % 51 - 25) / 10.0f;//改变球的垂直移动速度,范围为-2.5到2.5
}
}
ball.x--;//球向左移动
}
else if (RoL == L)//当球向左移出屏幕,表示player2赢
{
//printf("2继续%d\n", ball.y);
return 1;
}
if (ball.y - ball.r < 1 && random_speed < 0)//当球的上边缘到达屏幕上边缘时,改变球的垂直移动方向
{
random_speed = -random_speed;
}
else if (ball.y + ball.r > 298 && random_speed > 0)//当球的下边缘到达屏幕下边缘时,改变球的垂直移动方向
{
random_speed = -random_speed;
}
ball.y = ball.y + random_speed;//球的y坐标改变
//printf("%lf\n", ball.y);
return 0;
}
void bot(struct Player& player2, struct Ball& ball)
{
if (ball.y > 275)//防止player2移出屏幕
player2.ly = 250;
else if (ball.y < 25)
player2.ly = 0;
else
player2.ly = ball.y - 25;
player2.ry = player2.ly + 49;//player2的右下角y坐标
}
3.如果想去掉控制台,主函数改成如下,并包含Windows.h头文件,我的代码已经包含
int WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nShowCmd
)
{
return 0;
}
属性页链接器,系统,子系统里改成窗口,而非控制台

更多推荐

所有评论(0)