大家好,我是作者:隐匿269今天我带来的是用链表制作游戏,飞机大战(俗称:打飞机小游戏)。我会运用到图形库,没有图形库的伙伴不用着急,把打印图片的步骤省略,代码也能运行。

一、准备(大纲)

编程时,首先要做的就是整理好思路。我们要思考飞机大战的游戏规则,以及飞机的移动,敌机、子弹的创建和销毁等。总的可以分为一下几个环节。

*    1、初始化地图窗口,加载图片,飞机链表结构体的实现,变量的定义
    *    2、生成我放飞机,并移动
    *    3、发射子弹、移动、销毁
        4、敌方飞机生成、移动、销毁
        5、子弹消灭敌机
        6、敌机和我放飞机碰撞
        7、表示游戏结束
        8、计分
        9、背景音乐

二、代码

​
//头文件名称"Airplane.h"
#pragma once
#include <stdio.h>
#include <stdlib.h>//头文件重复函数//链表结构的声明和定义//链表节点结构体的声明
typedef struct Node
{int x;//坐标int y;//坐标int speed;//移动速度struct Node*next;//指针域,用于连接下一个节点
}Node;//链表结构体的声明
typedef struct Linklist
{Node*head;//头部节点指针Node*end;//尾部节点指针
}LL;//链表节点的创建函数
Node *linklist_init(int x, int y, int speed)
{Node*temp = (Node*)malloc(sizeof(Node));if (temp == NULL){return 0;}temp->speed = speed;temp->x = x;temp->y = y;temp->next = NULL;return temp;
}//链表节点的插入
void linklist_insert(LL*list, int x, int y, int speed){if (NULL == list){return;}if (list->head == NULL){list->head = list->end = linklist_init(x, y, speed);}else{list->end->next = linklist_init(x, y, speed);list->end = list->end->next;}
}//链表节点的删除函数
void Node_delete(LL*list, Node*p){if (list == NULL || list->head == NULL){return;}if (p == list->head){list->head = p->next;free(p);return;}Node*temp = list->head;for (; temp; temp = temp->next){if (temp->next = p){if (p == list->end){list->end = temp;}temp->next = p->next;free(p);p = NULL;return;}}
}//链表的释放,销毁
void linklist_dekete(LL*list){if (list->head == NULL || list == NULL){return;}for (Node*temp1 = list->head; temp1 != NULL;){Node*temp2 = temp1;temp1 = temp1->next;free(temp2);}list->head = list->end = NULL;
}​
​
//头文件名称"AirWar.h"
#pragma once
#include"Airplane.h"
//图形库头文件
#include"graphics.h"
#include "stdlib.h"
#include<stdio.h>
#include<conio.h>//_getch()、getch()、_kbhit()头文件
#include<time.h>//时间函数头文件
#include<math.h>//数学函数头文件
#include<tchar.h>//宽字节字符头文件
#define BGWIDETH                400                                         //窗口、背景宽度
#define BGHIGHT                 600                                         //窗口、背景的高度
#define myPlaneBGWIDETH         50                                          //我方飞机宽度
#define myPlaneBGHIGHT          75                                          //我方飞机高度
#define enemyPlaneBGWIDETH      50                                          //敌方飞机宽度
#define enemyPlaneBGHIGHT       40                                          //敌方飞机高度
#define BulletBGWIDETH          10                                          //子弹宽度
#define BulletBGHIGHT           16                                          //子弹高度
#pragma comment(lib,"winmm.lib")//包含音乐静态库winmm.libIMAGE img[4];                                                                //图片数组
Node myPlane;                                                                //我方飞机
LL myBullet;                                                                 //我方子弹链表
LL enemyPlane;                                                               //敌方飞机链表int isWin;                                                                  //游戏开始、结束初始化为0
int score;                                                                   //游戏开始得分初始化为0//加载图片
void init()
{//定义随机种子srand((unsigned)time(NULL));loadimage(&img[0], "res\\背景.jpg", BGWIDETH, BGHIGHT);loadimage(&img[1], "res\\敌机.jpg", enemyPlaneBGWIDETH, enemyPlaneBGHIGHT);loadimage(&img[2], "res\\飞机.jpg", myPlaneBGWIDETH, myPlaneBGHIGHT);loadimage(&img[3], "res\\子弹.jpg", BulletBGWIDETH, BulletBGHIGHT);
}//初始化我放飞机的坐标和速度
void myPlane_init()
{isWin = 0;score = 0;mciSendString("open res\\JustBlue.mp3", 0, 0, 0);//mciSendString函数用于设置音乐相关选项//open加载音乐(打开音乐)//打开音乐时需要注意:音乐文件的名称不能含有空客' ',否则无法识别音乐//play播报音乐mciSendString("play res\\JustBlue.mp3", 0, 0, 0);myPlane.x = BGWIDETH/2- enemyPlaneBGWIDETH/2;myPlane.y = BGHIGHT- myPlaneBGHIGHT -25;myPlane.speed = 5;myPlane.next = NULL;//初始化子弹的坐标和速度
}//我方子弹生成函数
void creatmyBullet()
{linklist_insert(&myBullet, myPlane.x + (myPlaneBGWIDETH / 2) - (BulletBGWIDETH / 2), myPlane.y + (myPlaneBGHIGHT/2)-BulletBGHIGHT, 10);
}//敌机的生成函数(随机)
void createEnemyPlane()
{if ((rand() % 200) == 199)linklist_insert(&enemyPlane, rand() % (BGWIDETH- enemyPlaneBGWIDETH), 0 - enemyPlaneBGHIGHT, (rand() % 2)+1);
}//子弹和敌机的移动
void move()
{//子弹移动for (Node*temp = myBullet.head; temp; temp = temp->next){//循环遍历整个子弹链表temp->y -= temp->speed;}//敌机移动for (Node*temp = enemyPlane.head; temp; temp = temp->next){//循环遍历整个敌机链表temp->y += temp->speed;}
}//玩游戏函数,我方飞机的移动
void play()
{if (_kbhit()){switch (getch()){//向上移动case 'w':case 'W':if(myPlane.y>=0)myPlane.y -= myPlane.speed;break;//向左移动case 'a':case 'A':if (myPlane.x>=0)myPlane.x -= myPlane.speed;break;//向右移动case 'd':case 'D':if (myPlane.x<=BGWIDETH- myPlaneBGWIDETH)myPlane.x += myPlane.speed;break;//向下移动case 'x':case 'X':if (myPlane.y <= BGHIGHT- myPlaneBGHIGHT)myPlane.y += myPlane.speed;break;//手动发射子弹case 'b':case 'B':creatmyBullet();break;}}}//绘制地图
void DrawMap()
{BeginBatchDraw();//开始批量绘图putimage(0, 0, &img[0]);//绘制背景//绘制敌机for (Node*temp = enemyPlane.head; temp; temp = temp->next){//循环遍历整个飞机链表putimage(temp->x, temp->y, &img[1]);}//绘制飞机putimage(myPlane.x, myPlane.y, &img[2]);//绘制子弹for (Node*temp = myBullet.head; temp; temp = temp->next){//循环遍历整个子弹链表putimage(temp->x,temp->y, &img[3]);}TCHAR str[50];//需要包含头文件tchar.h,能够很好的保存中文,宽字节字符//定义一个宽字节字符TCHAR数组str,用于存储即将显示的分数字符串,sprintf(str, "当前的分:%d", score);//输入函数,将其中 "当前的分:"这个字符串放到宽字节字符TCHAR数组str中,可以使用//格式占位符(如:%d、%c%f等)向字符串中插入变量的值setbkmode(TRANSPARENT);outtextxy(0, 0, str);EndBatchDraw();//开始批量绘图
}//子弹碰撞检测函数
int Blt_isColllision(Node*p,Node*q)
{//用中心点判断//求子弹中心点坐标int px = p->x + BulletBGWIDETH / 2;//x坐标int py = p->y + BulletBGHIGHT / 2;//y坐标//求敌机中心点坐标int qx = q->x + enemyPlaneBGWIDETH / 2;//x坐标int qy = q->y + enemyPlaneBGHIGHT / 2;//y坐标if (abs(px - qx) >=( (BulletBGWIDETH + enemyPlaneBGWIDETH) / 2)|| abs(py - qy) >= ((BulletBGHIGHT + enemyPlaneBGHIGHT) / 2)){return 0;}else{return 1;}
}//敌机、飞机碰撞检测函数
int Air_isColllision(Node*p, Node*q){//求飞机中心点坐标int px = p->x + myPlaneBGWIDETH / 2;//x坐标int py = p->y + myPlaneBGHIGHT / 2;//y坐标//求敌机中心点坐标int qx = q->x + enemyPlaneBGWIDETH / 2;//x坐标int qy = q->y + enemyPlaneBGHIGHT / 2;//y坐标if (abs(px - qx) >= ((myPlaneBGWIDETH + enemyPlaneBGWIDETH) / 2)|| abs(py - qy) >= ((myPlaneBGHIGHT + enemyPlaneBGHIGHT) / 2)){return 0;}else{return 1;}}//子弹销毁和敌机的销毁
void Delete()
{for (Node*temp = myBullet.head; temp; temp = temp->next){if (temp->y <0- BulletBGHIGHT){//如果子弹的y坐标小于0,则判断子弹移动到屏幕外面,销毁子弹Node_delete(&myBullet, temp);//销毁子弹链表return;//一次只释放一个节点}}for (Node*temp2 = enemyPlane.head; temp2; temp2 = temp2->next){if (temp2->y > BGHIGHT){//如果子弹的y坐标大于屏幕高度,则判断子弹移动到屏幕外面,销毁子弹Node_delete(&enemyPlane, temp2);//销毁子弹链表return;//一次只释放一个节点}for (Node*temp1 = myBullet.head; temp1; temp1 = temp1->next){if (Blt_isColllision(temp1, temp2)/*子弹消灭敌机*/){Node_delete(&myBullet, temp1);//销毁子弹Node_delete(&enemyPlane, temp2);//销毁敌机score++;return;}}if (Air_isColllision(&myPlane, temp2)){//如果我方飞机碰到了敌机//游戏失败isWin = 1;//游戏失败return;}}}void start()
{//打开图形库窗口initgraph(BGWIDETH, BGHIGHT);//加载图片init();//初始化飞机数据myPlane_init();while (1){//绘制地图DrawMap();//移动play();createEnemyPlane();//随机生成敌机//子弹和敌机的移动move();//子弹和敌机的销毁Delete();if (isWin){linklist_dekete(&enemyPlane);//游戏结束,释放整个敌机列表linklist_dekete(&myBullet);//游戏结束,释放整个子弹列表TCHAR str[50];//需要包含头文件tchar.h,能够很好的保存中文,宽字节字符//定义一个宽字节字符TCHAR数组str,用于存储即将显示的分数字符串,sprintf(str, "当前的分:%d\n是否重新开始游戏?", score);int temp=MessageBox(GetForegroundWindow(), str, "游戏失败", MB_YESNO);//临时变量temp接受弹窗按键后的返回值if (6 == temp)//'6'表示弹窗里按下“是”这个按钮{init();//重新初始化游戏myPlane_init();}else if(7 == temp)//'7'表示弹窗里按下“否”这个按钮{break;}}Sleep(10);//延迟一毫秒}closegraph();
}​
​#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE
#define _CRT_NONSTDC_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include"AirWar.h"
/*
飞机(我方,敌方),地图,子弹* 1、初始化地图窗口,加载图片,飞机链表结构体的实现,变量的定义*   2、生成我放飞机,并移动*    3、发射子弹、移动、销毁4、敌方飞机生成、移动、销毁5、子弹消灭敌机6、敌机和我放飞机碰撞7、表示游戏结束8、计分9、背景音乐*/int main()
{start();//开始函数system("pause");return 0;
}​

飞机大战——有图片,有声音相关推荐

  1. MFC实现简单飞机大战(含游戏声音)

    1 实验内容 本实验主要是实现简单的飞机大战游戏,包含游戏声音.碰撞后爆炸效果,有大小敌机等.所用到的知识点如下: 1.贴图技术 2.飞机类.子弹类实现 3.位图移动 4.碰撞判断,实现爆炸效果 5. ...

  2. java飞机大战程序图片不显示

    作为一个java初学者,最近在学习尚学堂免费的基础java课程时,跟着视频做一个planewar/飞机大战的程序,遇到了背景和飞机图片加载不了的问题,几经搜索,终于解决,分享一下过程和解决办法: 代码 ...

  3. java飞机大战背景图片_Java简单飞机大战(1)

    在完成了多线程小球之后,就可以写一个飞机大战小游戏了,虽然比较简单,但玩起来还是有一点乐趣的.下面就讲一下我的大概思路和一些实现步骤. 一开始当然要想好一个框架,毕竟框架还是很重要的.当点击开始按钮的 ...

  4. android 飞机大战背景图片,安卓飞机大战(一) 背景移动

    在制作游戏时,背景可以移动,原理就是两张图片的循环移动. package com.example.backgroundtest; import com.example.hundouluo.R; imp ...

  5. 全网首份pyQt6飞机大战

    全网首份pyQt6飞机大战 该飞机大战具备较为完善的框架 可自动调整飞机与屏幕的位置 具备单点开火,半自动开火,全自动开火三种开火状态 每个作品作者花了不少头发,希望路过的大神多多留言点赞,对于不足的 ...

  6. android项目飞机大战,Android 项目之飞机大战

    首先,我们要创建一个GameSurface()类:我们此次采用的是画登入界面的方式,所以GameSurface()需要继承SurfaceView类而且要执行SurfaceHolder.Callback ...

  7. python飞机大战联网版_Python实现飞机大战(搞怪)游戏!这是你没见过的全新版本!...

    (飞机为迷你亚索,外星人为迷你小诺手,由于时间关系和图片素材较难寻找,仅仅做了简易版,没有贴上背景图片.由于篇幅原因,对于函数讲解较为简略,可以自行搜索相应函数的用法) 主要利用pygame内置库进行 ...

  8. Python实现飞机大战(搞怪)游戏!这是你没见过的全新版本!

    (飞机为迷你亚索,外星人为迷你小诺手,由于时间关系和图片素材较难寻找,仅仅做了简易版,没有贴上背景图片.由于篇幅原因,对于函数讲解较为简略,可以自行搜索相应函数的用法) 主要利用pygame内置库进行 ...

  9. python飞机大战联网版_Python 飞机大战搞怪版本

    python 飞机大战搞怪版本 (飞机为迷你亚索,外星人为迷你小诺手,由于时间关系和图片素材较难寻找,仅仅做了简易版,没有贴上背景图片.由于篇幅原因,对于函数讲解较为简略,可以自行搜索相应函数的用法) ...

最新文章

  1. endnote能自动翻译吗_人工智能能翻译古文吗?跟小编点评专业翻译PK人工智能翻译...
  2. 天龙源码分析 - 选择角色流程
  3. 国内整车厂“造芯”还缺什么?
  4. redis集群方式介绍
  5. Module(模块)
  6. Notepad++ 查找替换 换行符的方法
  7. 人大副教授从细节上教你如何快速进行研究生早期的科研之路
  8. [转]vc6如何设置Unicode字符集
  9. (6)Spring框架----Bean生命周期分析(详细)
  10. 服务器接千兆无线网卡,用户吓跑!千兆宽带就是坑爹货:真相崩溃
  11. 读书笔记 | 4.3 基于征信系统的征信基础产品
  12. Pytorch实战__反向攻击(Adversarial Attack)
  13. GraphPad Prism 科研绘图(一)
  14. discourse 安装_如何使用Discourse在半天之内建立内部团队论坛
  15. 面试了37位数据分析师,发现厉害的人都有这4个特质
  16. 字节跳动面试流程以及注意事项,各大厂具有通点,看看不吃亏!
  17. Android hilt 依赖注入使用详解
  18. 微信接入服务器源码,经典论坛程序Discuz! Q 1.0 发布:完全开放源码,原生接入微信...
  19. 南京大学软件工程842参考书攻略
  20. 【纪中受难记】——Day15:今晚吃烧烤(最后吃了火锅)

热门文章

  1. 用python画苹果_Python爬取京东Iphone X用户评论并绘制词云
  2. mac 允许任何来源应用安装
  3. JS统计一个字符串中数字字符的个数。
  4. PyTorch - FashionMNIST + LeNet / AlexNet / VGG / GooLeNet / NiN / ResNet / DenseNet
  5. 传播正能量-IT的笑傲江湖
  6. Qt笔记 -- QSetting的使用
  7. 关于计算机知识的手抄报图片大全,网络安全知识手抄报图片
  8. python 因果推断_[Python]因果检验工具
  9. Perforce (P4)版本控制使用指南
  10. JS设置CSS样式的方法。