C语言飞机大战小游戏
说明
此设计可以作为C语言课程设计,主要用的是easyx图形库;
在VS2019成功运行,注释比较全面,对没有C语言基础的小白也很友好;
若有些地方还可以完善,请指正。
设计游戏的思路主要从以下几个当面:
1.游戏图片的保存及绘制;其中主要包括玩家、子弹、敌机图片;
2.封装的函数包括玩家的移动、子弹的创建、子弹的移动、敌机的创建、敌机的移动;
3.使用的逻辑主要有边界的处理,子弹击中敌机;
4.在主函数运行所有的功能函数
下面开始介绍主要功能函数吧
枚举出设计中所需要的常量
enum TYPE
{WIDTH = 480, //窗口的宽度HEIGHT = 600, //窗口的高度PLAYERHEIGHT = 60, //玩家飞机的高度PLAYYERWIDTH = 90, //玩家飞机的宽度BULLET_NUM = 15, //玩家子弹的数量ENEMY_NUM=6, //敌机的数量BIG,SMALL, ENEMY_1_WIDTH=70, //Boss的宽度ENEMY_1_HEIGHT=78, //Boss的高度ENEMY_2_WIDTH=60,ENEMY_2_HEIGHT=60
};
创建结构体,其中包括的成员有玩家、敌机、玩家
struct Plane
{int x;int y;bool live;int width;int hegiht;int hp; //敌机的血量int type; //敌机的类别
}player,bullet[BULLET_NUM],enemy[ENEMY_NUM];
主要的功能函数
图片加载
void LoadIm()
游戏绘制
void gameDraw();//游戏初始化void initGanme();
数据的创建
void creatEnemy();/*这里创建的敌机判断敌机的类型及生命状态*/void creatBullet();/*子弹是通过获取键盘信息创建的*/
逻辑处理
1.void playerMove();/*主要的对玩家的坐标处理:*左边界坐标要大于玩家宽度的1/2,*右边界的坐标要小于主界面的宽度减去玩家宽度的1/2;*上边界的坐标要大于玩家的高度;*下边界的坐标应该小于主界面的高度减去玩家高度1/2;*/2.void playPlane();/*这里的逻辑是子弹的坐标应该在敌机区域内*主要实现的代码如下*/if (bullet[k].x > enemy[i].x && bullet[k].x<enemy[i].x + enemy[i].width&& bullet[k].y>enemy[i].y&& bullet[k].y < enemy[i].y + enemy[i].hegiht){bullet[k].live = false; //事件发生,消除子弹enemy[i].hp--; //敌机的血量-1}
程序所用代码(已测试)
#include<stdio.h>
#include<graphics.h>
#include<conio.h>
#include<time.h>enum My
{WIDTH = 480, //窗口的宽度HEIGHT = 600, //窗口的高度PLAYERHEIGHT = 60, //玩家飞机的高度PLAYYERWIDTH = 90, //玩家飞机的宽度BULLET_NUM = 15, //玩家子弹的数量ENEMY_NUM=6, //敌机的数量BIG,SMALL, ENEMY_1_WIDTH=70, //Boss的宽度ENEMY_1_HEIGHT=78, //Boss的高度ENEMY_2_WIDTH=60,ENEMY_2_HEIGHT=60
};
struct Plane
{int x;int y;bool live;int width;int hegiht;int hp;int type; //敌机的类别
}player,bullet[BULLET_NUM],enemy[ENEMY_NUM];//保存背景图片
IMAGE bk;//保存玩家图片
IMAGE img_role[2];//保存子弹图片
IMAGE img_bullet[2];//保存敌机图片
IMAGE img_enemy[2][2];//保存继续
IMAGE img_continue;//保存退出
IMAGE img_exit;//把图片加载到程序中
void LoadIm()
{//加载背景图片loadimage(&bk, "./images/background.jpg");//加载玩家图片loadimage(&img_role[0], "./images/planeNormal_1.jpg");loadimage(&img_role[1], "./images/planeNormal_2.jpg");//加载子弹图片loadimage(&img_bullet[0], "./images/bullet_1.jpg");loadimage(&img_bullet[1], "./images/bullet_2.jpg");//加载敌机图片loadimage(&img_enemy[0][0], "./images/enemy_1.jpg");loadimage(&img_enemy[0][1], "./images/enemy_2.jpg");loadimage(&img_enemy[1][0], "./images/enemy_3.jpg");loadimage(&img_enemy[1][1], "./images/enemy_4.jpg");//加载游戏结束图片loadimage(&img_continue, "./images/continue.jpg");//加载退出图片loadimage(&img_exit, "./images/exit.jpg");}
//敌机的类型
void enemyHp(int i)
{int flag = rand() % 10;if (flag>=0&&flag<=2) //0~9{enemy[i].type = BIG;enemy[i].hp = 3;enemy[i].width = ENEMY_1_WIDTH;enemy[i].hegiht = ENEMY_1_HEIGHT;}else{enemy[i].type = SMALL;enemy[i].hp = 1;enemy[i].width = ENEMY_2_WIDTH;enemy[i].hegiht = ENEMY_2_HEIGHT;}
}
//初始化游戏数据
void gameInit()
{//初始化玩家数据player.x = WIDTH / 2 - PLAYYERWIDTH/2;player.y = HEIGHT - PLAYERHEIGHT;player.hp = 4;player.live = true;//初始化子弹for (int i = 0; i < BULLET_NUM; i++){bullet[i].x = 0;bullet[i].y = 0;bullet[i].live = false;}//初始化敌机for (int i = 0; i < ENEMY_NUM; i++){enemy[i].live = false;enemyHp(i);}}
//游戏的绘制函数
void gameDraw()
{LoadIm();//贴窗口文件putimage(0, 0, &bk);//绘制玩家图片if (player.live){putimage(player.x, player.y, &img_role[0], NOTSRCERASE);putimage(player.x, player.y, &img_role[1], SRCINVERT);}for (int i = 0; i < BULLET_NUM; i++){if (bullet[i].live){//绘制子弹图片putimage(bullet[i].x, bullet[i].y, &img_bullet[0], NOTSRCERASE);putimage(bullet[i].x, bullet[i].y, &img_bullet[1], SRCINVERT);}}//绘制敌机for (int i = 0; i < ENEMY_NUM; i++){if (enemy[i].live){if (enemy[i].type == SMALL){putimage(enemy[i].x, enemy[i].y, &img_enemy[1][0], NOTSRCERASE);putimage(enemy[i].x, enemy[i].y, &img_enemy[1][1], SRCINVERT);}else{putimage(enemy[i].x, enemy[i].y, &img_enemy[0][0], NOTSRCERASE);putimage(enemy[i].x, enemy[i].y, &img_enemy[0][1], SRCINVERT);}}}//游戏结束界面if (player.live == false){putimage(40, 220, &img_continue);putimage(290, 220, &img_exit);}//播放音乐//mciSendString(TEXT("open music.mp3 alias music"), 0, 0, 0);//mciSendString(TEXT(" play music"), 0, 0, 0);
}
//定时器
bool Timer(int ms, int id)
{static DWORD t[10];if (clock()-t[id]>ms){t[id] = clock();return true;}return false;
}//创建子弹
void creatBullet()
{for (int i = 0; i < BULLET_NUM; i++){if (!bullet[i].live){bullet[i].x = player.x + 35;bullet[i].y = player.y;bullet[i].live = true;break;}}
}
//敌机的移动
void enemyMove(int speed)
{for (int i = 0; i < ENEMY_NUM; i++){if (enemy[i].live){enemy[i].y += speed;if (enemy[i].y > HEIGHT){enemy[i].live = false;}}}
}
//产生敌机
void creatEnemy()
{for (int i = 0; i < ENEMY_NUM; i++){if (!enemy[i].live){enemy[i].live = true;enemy[i].x = rand() % (WIDTH - ENEMY_1_WIDTH/2);enemy[i].y = 0;enemyHp(i);break;}}enemyMove(3);
}//玩家移动,判断键盘消息
void playerMove(int speed)
{#if 0//如果有键盘按下,则返回真if (_kbhit){//1.方式一 _getch() 阻塞函数,和scanf一样,如果没有输入,就会卡在主程序,一直等待输入,且不是标准C的函数char key = _getch();switch (key){case 'w':case 'W':player.y -= speed;break;case 's':case 'S':player.y += speed;break;case 'a':case 'A':player.x -= speed;break;case 'd':case 'D':player.x += speed;break;default:break;}}
#elif 1//2.使用Windows函数获取键盘的输入 GetAsyncKeyState 非阻塞函数//如果用字母,可以用大写;则键盘的大小写都可以被检测到if (GetAsyncKeyState(VK_UP)||GetAsyncKeyState('W')){if (player.y > 0-PLAYERHEIGHT/2){player.y -= speed;}printf("(%d,%d),Live:%d,Hp:%d\n", player.x, player.y, player.live, player.hp);}if (GetAsyncKeyState(VK_DOWN)||GetAsyncKeyState('S')){if (player.y < HEIGHT - PLAYERHEIGHT/2){player.y += speed;}printf("(%d,%d),Live:%d,Hp:%d\n", player.x, player.y, player.live, player.hp);} if (GetAsyncKeyState(VK_LEFT)||GetAsyncKeyState('A')){if (player.x > 0-PLAYYERWIDTH/2){player.x -= speed;}printf("(%d,%d),Live:%d,Hp:%d\n", player.x, player.y, player.live, player.hp);} if (GetAsyncKeyState(VK_RIGHT)||GetAsyncKeyState('D')){if (player.x < WIDTH - PLAYYERWIDTH/2){player.x += speed;}printf("(%d,%d),Live:%d,Hp:%d\n", player.x, player.y, player.live, player.hp);}
#endif // 0if (GetAsyncKeyState(VK_SPACE)&& Timer(200, 1) ||GetAsyncKeyState('J')&&Timer(200,1)) //延时时间,毫秒{if (player.live){creatBullet();}}
}
//子弹的移动
void bulletMove()
{for (int i = 0; i < BULLET_NUM; i++){if (bullet[i].live){bullet[i].y -= 2;//bullet[i].x -= 1;if (bullet[i].y < 0){bullet[i].live = false;}}}
}//击中飞机,碰撞算法
void playPlane()
{for (int i = 0; i < ENEMY_NUM; i++){if (!enemy[i].live){continue;}for (int k = 0; k < BULLET_NUM; k++){if (!bullet[i].live){continue;}if (bullet[k].x > enemy[i].x && bullet[k].x<enemy[i].x + enemy[i].width&& bullet[k].y>enemy[i].y && bullet[k].y < enemy[i].y + enemy[i].hegiht){bullet[k].live = false;enemy[i].hp--;}}if (enemy[i].hp<=0){enemy[i].live = false;}}
}int main()
{//创建一个窗口initgraph(WIDTH, HEIGHT,SHOWCONSOLE);gameInit();//双缓冲绘图BeginBatchDraw();while (1){gameDraw();FlushBatchDraw();playerMove(5);bulletMove();if (Timer(100,0)){creatEnemy();}if (Timer(200, 2)){enemyMove(2);}playPlane();}EndBatchDraw();return 0;
}
程序运行截图
问题处理
图片
1.在项目里面创建images文件夹;
2.加入原图和掩码图,黑白的为掩码图;
字符集
打开-“项目”-“属性”,按照上图将“字符集”改成上图模式然后可以运行了;
C语言飞机大战小游戏相关推荐
- C语言—飞机大战小游戏
哈工大经典C语言大作业-飞机大战小游戏,源码如下,已经通过编译获得评分19+ (满分20)当时还是太菜了呜呜呜. 可以给大家参考一下,好像本来是加了音乐的,但是你们可能没有对应的音乐MP3文件,所以如 ...
- 基于Java语言在窗体上实现飞机大战小游戏
全套资料下载地址:https://download.csdn.net/download/sheziqiong/85594271 项目介绍 飞机大战:用 Java 语言在窗体上实现飞机大战小游戏,运行程 ...
- 用C语言实现飞机大战小游戏
我的个人博客:谋仁·Blog 该项目已上传至GitHub:点击跳转 文章目录 摘要 运行环境 整体功能思维导图 效果预览 具体功能的实现 图形界面:EasyX EasyX图形库简介 EasyX图形库的 ...
- 华为官方解析开源鸿蒙 OpenHarmony 3.1关键特性画布,教你如何完成飞机大战小游戏
华为技术有限公司的江英杰为大家揭晓了关于开源鸿蒙 OpenHarmony 3.1 Beta 版中的一个关键特性,也就是 ArkUI 开发框架中的 canvas 画布. 据介绍,canvas 是 Ark ...
- canvas绘制“飞机大战”小游戏,真香
canvas是ArkUI开发框架里的画布组件,常用于自定义绘制图形.因为其轻量.灵活.高效等优点,被广泛应用于UI界面开发中. 本期,我们将为大家介绍canvas组件的使用. 目录 一.canvas介 ...
- 【python】飞机大战小游戏练习
飞机大战小游戏练习 一.前提准备 二.制作步骤 1.库的导入与初始化 2.窗口操作 3.键盘按键监听相关操作 4.添加游戏背景 5.加载玩家飞机 6.获取玩家飞机矩阵 三.完整代码编写 游戏背景类编写 ...
- python 飞机大战小游戏
飞机大战小游戏,这里需要下载pygame模块 这是需要的素材,需要的自取: 上代码: import time import pygame from pygame.locals import *#检测事 ...
- 点击list view中一行内容可以在combox中显示_java版飞机大战小游戏详细教程(零基础小白也可以分分钟学会!)...
一:游戏展示 飞机大战小游戏我们都玩过,通过移动飞机来打敌机,这里给大家展示一下游戏成果:呜呜呜由于gif只能上传5M大小,所以就不能给大家展示操作了,如果大家有兴趣可以自己自己做出来再玩哟. 这里面 ...
- 飞机大战小游戏(超详细)
偷学Python之最后的项目二:飞机大战小游戏(超详细) 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志.--苏轼 甜甜先说 这次用Python中的pygame模块来完成一个飞机大战的小游戏:基本思 ...
最新文章
- 计量经济学建模_不了解计量经济学的前世今生,怎么能学会他
- Winhex添加文件头的方法
- 21-5-22校赛G 自行车调度
- react全局状态管理_rxv: 在React中用Vue3的reactivity包实现状态管理。
- 交公粮了,我经常逛的技术网站,你最爱哪个?
- 一步一步手绘Spring IOC运行时序图一(Spring 核心容器 IOC初始化过程)
- “云计算之旅”筹备完成,意见征询!
- 量化投资中的「模型」与「人」
- Ubuntu Android开发环境配置
- 基础算法练习200题07、编框
- 笔记本电脑如何用c语言开无线网卡,教你如何用无线网卡做wifi热点(适用笔记本)...
- 如何给自己的照片制作水印
- 数据结构c语言版李冬梅PDF,数据结构(C语言版) 习题答案 严蔚敏 李冬梅 吴伟民 23490数据结构习题答案.pdf...
- 【学习记录——unity 3D】Stealth秘密行动游戏制作(一)
- 任天堂Switch最优DNS测试
- java delphi socket_Delphi跨平台Socket通讯库
- matlab求解数独流程图,简单的数独游戏求解程序(matlab)
- 中国煤层气开发市场发展态势及投资规划深度研究报告2022-2028年
- 世界上以一台计算机体积多大,世界上体积最大的计算机器有多大
- 最全Airtest接口功能介绍和示例总结,新手同学千万不能错过呀!(一)
热门文章
- 使用 springboot + mybatis-plus 连接firebird(火鸟数据库)
- opencv系列之基于NVIDIA显卡的opencv-python硬解方案
- 任我行/管家婆 导入EXCEL ACCESS数据
- 五行、八卦、风水与算命
- python学习之字符串—佛曰实现简易版
- 通信协议/通讯协议 有哪些?包含哪些分类?
- SQL 查找表名,字段名(转)
- hd2+android+4.4,传说仍在继续 HTC HD2成功刷入Android 4.4
- 东芝复印机2505AC错误CD40请求维修
- 裸机是指只装操作系统的计算机吗,所谓裸机是指.A单板机B只装备操作系统的计......