(图书介绍:童晶:《C和C++游戏趣味编程》新书预告)

本章我们将编写坚持一百秒游戏,玩家通过鼠标控制火箭躲避一架UFO和越来越多的反弹子弹,效果如图所示。

首先学习图片的导入和显示,并利用结构体实现一颗反弹的子弹;然后学习面向对象编程的知识,利用类和对象实现新版本的子弹;接着添加火箭类,并实现子弹和火箭的碰撞检测、坚持时间和火箭多条生命的显示,学习如何添加音乐音效;最后学习继承的概念,在子弹类的基础上快速实现智能飞碟类。

12 坚持一百秒

讲解视频:

最终代码:

#include <graphics.h>
#include <conio.h>
#include <time.h>
#include "EasyXPng.h"  // 用于显示带透明通道的png图片
// 引用 Windows Multimedia API
#pragma comment(lib,"Winmm.lib")
#define  WIDTH 560 // 画面宽度
#define  HEIGHT 800 // 画面高度
#define  MaxBulletNum 200  // 最多子弹个数void sleep(DWORD ms)  // 精确延时函数
{static DWORD oldtime = GetTickCount();while(GetTickCount() - oldtime < ms)Sleep(1);oldtime = GetTickCount();
}void PlayMusicOnce(TCHAR fileName[80]) // 播放一次音乐函数
{TCHAR cmdString1[50];_stprintf(cmdString1, _T("open %s alias tmpmusic"), fileName);    // 生成命令字符串mciSendString(_T("close tmpmusic"), NULL, 0, NULL); // 先把前面一次的音乐关闭mciSendString(cmdString1, NULL, 0, NULL); // 打开音乐mciSendString(_T("play tmpmusic"), NULL, 0, NULL); // 仅播放一次
}class Rocket  // 定义火箭类
{
public:IMAGE im_rocket; // 火箭图像IMAGE im_blowup; // 爆炸图像float x,y; // 火箭坐标float width,height; // 火箭图片的宽度、高度int liveSecond; // 火箭存活了多长时间int life;  // 火箭有几条命void draw() // 显示火箭相关信息   {// 窗口左上角显示life个火箭图片,表示火箭生命数for (int i=0;i<life;i++)putimagePng(i*width*0.9,0,&im_rocket);// 窗口正上方显示坚持了多少秒TCHAR s[20];setbkmode(TRANSPARENT); // 文字字体透明_stprintf(s, _T("%d秒"), liveSecond);   settextcolor(WHITE); // 设定文字颜色settextstyle(40, 0, _T("黑体"));//  设定文字大小、样式outtextxy(WIDTH*0.85, 20, s); //  输出文字内容if (life>0) // 根据有命没命,显示不同的图片putimagePng(x - width/2,y-height/2,&im_rocket);  // 游戏中显示火箭图片elseputimagePng(x - width/2,y-height/2,&im_blowup);  // 游戏中显示爆炸图片}void update(float mx,float my) // 根据输入的坐标更新火箭的位置{x = mx;y = my;}void updateWhenLifeLost() // 当火箭减命时执行的操作{PlayMusicOnce(_T("explode.mp3"));  // 播放一次爆炸音效life --; // 生命减少}
};class Bullet  // 定义子弹类
{
public:IMAGE im_bullet; // 子弹图像float x,y; // 子弹坐标float vx,vy; // 子弹速度float radius; // 接近球体的子弹半径大小void draw()// 显示子弹 {putimagePng(x - radius,y-radius,&im_bullet);  }void update() // 更新子弹的位置、速度{x += vx;y += vy;if (x<=0 || x>=WIDTH)vx = -vx;if (y<=0 || y>=HEIGHT)vy = -vy;}int isCollideRocket(Rocket rocket) // 判断子弹是否和火箭碰撞{float distance_x = abs(rocket.x - x);float distance_y = abs(rocket.y - y);if ( distance_x < rocket.width/2 && distance_y < rocket.height/2 )return 1; // 发生碰撞返回1elsereturn 0; // 不碰撞返回0   }
};class SmartUFO: public Bullet // 智能飞碟类,由Bullet类派生出来
{
public:void updateVelforTarge(Rocket targetRocket) // 让飞碟的速度瞄向目标火箭{float scalar = 1*rand()/double(RAND_MAX) + 1; // 速度大小有一定的随机性if (targetRocket.x>x) // 目标在飞碟左边,飞碟x方向速度向右vx = scalar;else if (targetRocket.x<x) // 目标在飞碟右边,飞碟x方向速度向左vx = -scalar;if (targetRocket.y>y) // 目标在飞碟下方,飞碟y方向速度向下vy = scalar;else if (targetRocket.y<y) // 目标在飞碟上方,飞碟y方向速度向上vy = -scalar;}
};IMAGE im_bk,im_bullet,im_rocket,im_blowup,im_UFO;  // 定义图像对象
Bullet bullet[MaxBulletNum]; // 定义子弹对象数组
Rocket rocket;  // 定义火箭对象
SmartUFO ufo;  // 定义飞碟对象
int bulletNum = 0; // 已有子弹的个数void startup()  //  初始化函数
{   mciSendString(_T("open game_music.mp3 alias bkmusic"), NULL, 0, NULL);//打开背景音乐mciSendString(_T("play bkmusic repeat"), NULL, 0, NULL);  // 循环播放srand(time(0)); // 初始化随机种子loadimage(&im_bk, _T("background.png")); // 导入背景图片loadimage(&im_bullet, _T("bullet.png")); // 导入子弹图片loadimage(&im_rocket, _T("rocket.png")); // 导入火箭图片loadimage(&im_blowup, _T("blowup.png")); // 导入爆炸图片loadimage(&im_UFO, _T("ufo.png")); // 导入飞碟图片// 对飞碟的一些成员变量初始化ufo.x = WIDTH/2;  // 设置飞碟位置ufo.y = 10;ufo.im_bullet = im_UFO; // 设置飞碟图片ufo.radius = im_UFO.getwidth()/2; // 设置飞碟半径大小ufo.updateVelforTarge(rocket); // 更新飞碟的速度// 对rocket一些成员变量初始化rocket.im_rocket = im_rocket;  // 设置火箭图片rocket.im_blowup = im_blowup;  // 设置火箭爆炸图片rocket.width = im_rocket.getwidth(); // 设置火箭宽度rocket.height = im_rocket.getheight(); // 设置火箭高度rocket.life = 5; // 火箭初始5条命 initgraph(WIDTH,HEIGHT); // 新开一个画面BeginBatchDraw(); // 开始批量绘制
}void show()  // 绘制函数
{putimage(0, 0, &im_bk);    // 显示背景 ufo.draw();  // 显示飞碟for (int i=0;i<bulletNum;i++)bullet[i].draw();  // 显示已有的子弹rocket.draw();  // 显示火箭及相关信息FlushBatchDraw(); // 批量绘制sleep(10); // 暂停
}void updateWithoutInput() // 和输入无关的更新
{if (rocket.life<=0) // 火箭没有命了,不处理return; // 直接返回static int lastSecond = 0; // 记录前一次程序运行了多少秒static int nowSecond = 0; // 记录当前程序运行了多少秒static clock_t start = clock(); // 记录第一次运行时刻clock_t now = clock(); // 获得当前时刻// 计算程序目前一共运行了多少秒nowSecond =( int(now - start) / CLOCKS_PER_SEC);rocket.liveSecond = nowSecond; // 火箭生成了多少秒赋值if (nowSecond==lastSecond+1) // 时间过了1秒钟,更新下飞碟的速度ufo.updateVelforTarge(rocket); // ufo速度方向瞄准火箭if (nowSecond==lastSecond+2) // 时间过了2秒钟,新增一颗子弹{lastSecond = nowSecond; // 更新下lastSecond变量// 如果没有超出最大子弹数目的限制,增加一颗新的子弹if (bulletNum<MaxBulletNum){bullet[bulletNum].x = WIDTH/2; // 子弹初始位置bullet[bulletNum].y = 10;float angle = (rand()/double(RAND_MAX)-0.5)*0.9*PI;float scalar = 2*rand()/double(RAND_MAX) + 2;bullet[bulletNum].vx = scalar*sin(angle); // 子弹随机速度bullet[bulletNum].vy = scalar*cos(angle);bullet[bulletNum].im_bullet = im_bullet;  // 设置子弹图像bullet[bulletNum].radius = im_bullet.getwidth()/2; // 子弹半径为图片宽度一半}bulletNum++; // 子弹数目加一}for (int i=0;i<bulletNum;i++) // 对所有已有的子弹{bullet[i].update(); // 更新子弹的位置、速度        if (bullet[i].isCollideRocket(rocket)) // 判断子弹是否和火箭碰撞{rocket.updateWhenLifeLost(); // 火箭减命相关操作bullet[i].x = 5; // 当前子弹移开,防止重复碰撞bullet[i].y = 5; break; // 火箭已炸,不用再和其他子弹比较了}}ufo.update(); // 更新飞碟的位置、速度       if (ufo.isCollideRocket(rocket)) // 判断飞碟是否和火箭碰撞{rocket.updateWhenLifeLost(); // 当火箭减命时执行的操作ufo.x = 5; // 当前飞碟移开,防止重复碰撞ufo.y = 5; }
}void updateWithInput()  // 和输入相关的更新
{if (rocket.life<=0) // 火箭没有命了,不处理return; // 直接返回MOUSEMSG m;      // 定义鼠标消息while (MouseHit())  // 检测当前是否有鼠标消息{m = GetMouseMsg();if(m.uMsg == WM_MOUSEMOVE)  // 到鼠标移动时         rocket.update(m.x,m.y); // 火箭的位置等于鼠标所在的位置}
}int main() // 主函数
{startup();  // 初始化 while (1)  // 重复运行{show();  // 绘制updateWithoutInput();  // 和输入无关的更新updateWithInput();  // 和输入相关的更新}return 0;
}

这一章主要学习了面向对象编程,包括类和对象、成员变量、成员函数、继承等概念,利用这些知识实现了坚持一百秒的游戏。

读者可以尝试在本章代码基础上继续改进:

1、利用继承实现道具类,吃到道具后可以加命或子弹速度减慢;

2、碰撞后给火箭一段时间的无敌状态;

3、游戏结束后增加得分记录显示、游戏重玩等功能。

读者可以尝试应用面向对象的知识,改进之前章节的游戏案例;也可以利用本章提供的素材,尝试实现一个面向对象版的太空大战游戏。

C++的面向对象编程博大精深,然而大多图书讲解过于抽象。本书通过一个具体的游戏案例,让读者体会到面向对象编程的好处,想要继续深入的读者可以进一步查阅其他学习资料。

第12章 坚持一百秒(《C和C++游戏趣味编程》教学视频)相关推荐

  1. 《Python游戏趣味编程》第12章 坚持一百秒

    12 坚持一百秒 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了 本章我们将编写一个坚持一百秒的游戏,玩家通过鼠标控制飞机躲避飞舞的小球,效果如图12-1所示.首先学习 ...

  2. 第13章 祖玛(《C和C++游戏趣味编程》配套教学视频)

    (图书介绍:童晶:<C和C++游戏趣味编程>新书预告) 本章我们将编写祖玛游戏,各种颜色的小球沿着轨道移动,玩家必须阻止小球进入轨道终点的城堡.鼠标可以移动控制炮台旋转.鼠标右键更换小球颜 ...

  3. 第5章 见缝插针(《C和C++游戏趣味编程》配套教学视频)

    (图书介绍:童晶:<C和C++游戏趣味编程>新书预告) 本章我们将实现一个见缝插针的游戏.按下空格键后发射一根针到圆盘上,所有针逆时针方向转动:如果新发射的针碰到已有的针,游戏结束. 首先 ...

  4. 第11章 樱花树(《C和C++游戏趣味编程》配套教学视频)

    (图书介绍:童晶:<C和C++游戏趣味编程>新书预告) 本章我们将绘制一些漂亮的樱花树,如图所示.鼠标位置设定樱花树的高度和分散程度,鼠标右键点击设置是否显示过程动画,鼠标左键点击开始绘制 ...

  5. c++中outtextxy_第12章 坚持一百秒(《C和C++游戏趣味编程》配套教学视频)

    本章我们将编写坚持一百秒游戏,玩家通过鼠标控制火箭躲避一架UFO和越来越多的反弹子弹,效果如图所示. 首先学习图片的导入和显示,并利用结构体实现一颗反弹的子弹:然后学习面向对象编程的知识,利用类和对象 ...

  6. opencv python 生成画布_第16章 坚持一百秒(《Python趣味创意编程》教学视频)

    (图书介绍:童晶:<Python趣味创意编程>新书预告) 本章我们将实现坚持一百秒的游戏,玩家通过移动人脸控制飞碟躲避越来越多的反弹子弹,效果如图所示.首先利用面向对象的知识,实现了一个鼠 ...

  7. python趣味编程100_《Python游戏趣味编程》 第8章 勇闯地下一百层

    知乎视频​www.zhihu.com 图书简介可以看这里:童晶:<Python游戏趣味编程>新书上架了​zhuanlan.zhihu.com 本章我们将编写一个勇闯地下一百层的游戏,键盘控 ...

  8. 《Python游戏趣味编程》 第8章 勇闯地下一百层

    8 勇闯地下一百层 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了 本章我们将编写一个勇闯地下一百层的游戏,键盘控制游戏角色左右移动,跳到下方随机生成的砖块上,尝试坚持 ...

  9. 《Python游戏趣味编程》 第10章 拼图游戏

    10 拼图游戏 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了 本章我们将编写一个拼图游戏,鼠标先后点击两个小拼图块,交换其坐标,直到全部达到正确位置,效果如图10-1 ...

最新文章

  1. 天气情况(思维,dp思想)
  2. 程序员面试题精选100题(03)-子数组的最大和[算法]
  3. Spark HistoryServer日志解析清理异常
  4. python框架Flask学习笔记之get和post请求
  5. 自定义线程池-线程类和任务类代码实现
  6. datatable 如何修改 某行 某列 的 字体颜色
  7. c语言20152016真题及答案,2016年计算机二级《C语言》基础练习题及答案(15)
  8. idea 无效的目标发行版_maven构建异常(无效的目标发行版: 1.8)
  9. matlab 预测值一样,matlab BP神经网络建造如下,预测时,预测值反归一化报错,求大神指教!!!!!...
  10. 【深度学习】之Caffe的solver文件配置(转载自csdn)
  11. ROS安装教程|从零开始
  12. 完美数c语言程序_C中的完美数
  13. 蓝桥杯嵌入式旧版子驱动问题-keil5下载卡死解决方法
  14. 为什么年轻人会活的越来越难?
  15. 都市丽人2022春夏新品订货会“清春·焕境”惊艳开启
  16. php 国际标准时间_关于时区:PHP date_default_timezone_set()东部标准时间(EST)
  17. C 语言(int )和(int*)的区别
  18. 还在为乱七八糟的桌面而忧桑吗
  19. 微信小程序注册/登陆,若依后台获取token
  20. 恐龙快打无限子弹修改方案

热门文章

  1. python 批量自动搜索、自动抓取需要的信息简单教程【selenium】
  2. PCB BOM也能如此好看?图形化交互式BOM工具Interactive Html Bom使用分享
  3. 单片机电源自动切换电路,mos双电源自动切换电路,电池与usb供电自动切换电路
  4. IO流 (五) ----- 对象数据的序列化与反序列化
  5. IaaS、PaaS、SaaS
  6. extjs fieldset 和 radio
  7. 斯大林格勒拖拉机厂LCA项目研制成功
  8. django 环境配置.
  9. 封装一个时间百分比多个数比较
  10. 使用git stash命令保存和恢复进度