|
翻硬盘时翻出来个小玩意,试了试 现在还能跑起来,哈哈。
当时答主事带一学生,很有精神;刚学一点西加加;头发浓密。萌新的憧憬之下,用devcpp这个瞎眼ide 写了个控制台坦克大战。3k来行
那会刚看完少战,中二附体max
手打像素矩阵
欢乐の小曲儿
穿甲爆炸燃烧 瞬间完成,事战车中的豪杰
用txt文件储存地图,玩家可自己设计地图,哈哈。当时还想弄地图编辑器的,最后还是咕咕咕了
相当搞笑的一点:前面有段代码是获取地图文件夹下所有文件名,存入字符数组。当时不知道字符串尾部要加结束符,导致后面使用该字符串读入文件时屡屡崩溃(没有结束符嘛)。
于是,宇宙大聪明答主写了这么一段处理代码,大概思路是将这个字符串复制一遍,检查复制后字符串的长度是否异常,如果异常则再复制一遍……(笑哭.jpg)
当时win7和现在win10的控制台空格长度不相同,现在运行会字符错位,地图看上去乱糟糟。正常应该是没有这些缝缝的。
穿甲弹,击中墙壁后产生2格杀伤区
穿甲弹杀伤大,但是有几率跳弹。有效击穿时会在对方炮塔处显示“#”。
高爆弹,产生3x3爆炸范围
“谢尔曼M1型”自带速射主炮,每分钟350发(大雾)。可惜为了平衡,并没有采用原版APHEI(高爆穿甲燃烧弹),而是杀伤力很低的糖豆炮。
炮射导弹,射出去能拐个弯。cd长 伤害低,但打掩体后的敌人是为一绝。
炸药桶地图块,被击中产生5x5爆炸范围。灰色地图块无法被破坏,浅黄色的可以。
坦克被击毁时有几率殉爆,产生5x5爆炸范围,而且持续时间比炸药桶长得多。
程序的稳定性相当差劲,截这些图的时候答主n次卡死或控制台弹窗报错了……
是的,当时连printf都不知道,打印字符用效率奇低的cout;而且一帧里逻辑处理和渲染混杂执行,导致画面容易闪烁甚至掉帧……
这是敌人AI的一部分,用n个套娃循环实现类似A*算法的寻路。AI寻找能射击到敌人的最近位置,还会根据自身血量等计算攻击欲望,躲避可能伤害到自己的炮弹,拾取有用的道具。整套算法效率特别特别低,每帧都要完整执行一次;容易导致掉帧。所以场上只能有一只精英怪使用完整的AI,其他小怪用随机函数xjb乱逛。
小怪:不是很聪明的亚子
类似移动、碰撞检测之类的部分,每一份代码都要手动复制四次,对应上下左右四个方向。
再放开头定义的一段吧:
#include <iostream>
#include <windows.h>
#include <fstream>
//#include <iomanip>
//#include <string.h>
//#include <stdio.h>
//#include <conio.h>
#include <sstream>
#include <cstdlib>
#include <ctime>
#include <io.h>//文件
#include <vector>//文件
#include<Mmsystem.h>//音频相关
#pragma comment(lib,&#34;winmm.lib&#34;)//音频
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)
using namespace std;
int map[38][55] = {0};//储存地图
int mapX = 55;//地图x大小
int mapY = 38;//地图y大小
int allX = 30;//整体x位移
int allY = 0;//整体y位移
int circlet = 0;//循环次数
int model;//当前游玩模式
int buff[3] = {0};//0[储存道具:1动能弹,2高爆弹,9生命值 ] ,1x,2y
int tank[10][8] = {0};//储存坦克:[编号],[0朝向,1x,2y,3生命值,4武器,5移速,6外形,7开炮装填时间]
//武器:0普通炮,1速射炮,2高爆弹,3破甲弹,4跟踪弹
int shell[10][10][4] = {0};//储存炮弹:[所属坦克],[编号],[0朝向,1x,2y,3类型]
int smoke[100][3] = {0};//储存硝烟&#34;#&#34;:[编号],[0已歼灭时间,1x,2y]
//**********基础功能**********
void ProgramBegin();//初始化程序
void FuZhi();//初始赋值
void gotoxy(int,int);//跳转光标
void color(int);//颜色
void getFiles(string, vector<string>&);//获取目标文件夹内所有文件名
void InMap(char*);//将地图导入数组
void Tout(int);//打印地图方块
void PrintMap();//打印地图
void PrintTank(int,int,int,int);//打印坦克,朝向,x,y,类型
void DelTank(int,int);//屏幕删除坦克
void sound(int);//音效
//**********菜单界面**********
int MenuModel();//模式菜单
char* MenuMap();//选图菜单
void MenuTank1vN();//选车菜单1vN模式
void MenuTank1v1();//选车菜单1v1模式
void Interface();//玩家状态界面
void NewUI();//刷新状态界面
int MenuPveWin(int);//结束人机战局
int MenuPvpWin(int);//结束双人战局
//**********战斗功能**********
void CtrlTank(int,int);//坦克控制
void InShell(int);//载入炮弹
void SkyShell();//炮弹移动
bool HitTank(int,int,int);//判断坦克是否受到伤害
void HitShell(int,int,int,int,int,int);//炮弹命中.朝向,x,y,弹药类型,被命中者 ,发射者
void Boom(int,int,int);//爆炸。半径,x,y
void InBuff();//载入道具
void OffBuff(int);//使用(消除)道具
void InSmoke(int,int);//载入硝烟
void OffSmoke();//删除硝烟
//**********AI功能**********
int FindMap(int,int,int,int);//寻路。起点x,y,终点x,y。返回方向,1234上下左右。
void AiTank();//坦克AI
void XieTank(int);//屑AI
void Born(int,int);//生成新车,编号、难度
//**********模式**********
void annihilate();//歼灭模式
void pve();//人机
void pvp();//双人对战
//**********附加**********
void op();//片头
void loading();//伪加载界面
void xy();//显示硝烟参数
void pd();//显示炮弹参数
void MenuZhanYi();//战役是不是已经想吐了~3.5k行代码塞在一个.cpp里
有没有留意到,上面那一堆全局变量的数据结构只有int数组。怎么用它储存数量和参数不等的坦克、炮弹、粒子(爆炸火光、烟雾……)等东西的呢?答主“发明”了这样一种方法:
一个数组储存一种类的物体,第一维记录该类所有物体。如坦克tank数组第一维长度是10,那地图上最多只能同时存在10辆坦克;tank[5] 表示编号为5的坦克。数组第二维储存这个物体的个体属性。如tank[5][0]代表5号坦克的朝向,[1]、[2]代表其坐标,等。
游戏中每一帧,依次遍历坦克、炮弹、特效等数组,提取数组中每一位物体,根据玩家输入和游戏逻辑更新该物体的参数(也就是更新这个数组)。
关键的来了:怎么实现生成和销毁物体,比如炮弹命中时销毁自身?很简单,要销毁物体,将那个物体所在的数组第二维清零就行了。刷新物体遍历数组时,遇到这种“空槽”就跳过。要增加物体,也遍历一遍该数组,找到一个“空槽”,将新物体的初始数据写入。
一段时间后,答主知道了有种东西叫结构体,有门课叫数据结构,有种数据结构叫链表,有种对象叫面向对象。可惜到现在也没找到对象,唉。
最烂的代码果然还是自己写的代码,这简直是个珠穆奥力给峰。好在没有人需要为这个“项目”负责,没有人需要维护它,它只需要静静地躺在硬盘深处的角落就行了。
总结:
后来呢我还是一直热衷于游戏开发。坦克大战后不久,写的第二个“大工程”是基于qt的2d海战游戏,有点类似顶视角的wows。为啥当时突然想学qt?也许是前一个学期写作业用mfc太痛苦了吧。总之,按我的坏习惯,看了两三天文档就兴冲冲开工写demo了。后期的代码和工程现在已经找不到了,只找到一些前期的素材:
按照舰船的真实顶视图 用ps画svg矢量图精灵
代码风格也是极其奥力给,回忆一下大概像这样:
thisGuanQia->ui->myship->labelPao->setText(&#34;主炮0开火cd:&#34;+QString::number(thisGuanQia->jianDui->ship->my->ship[0]->wuQiZu[0]->pao[0]->cd->nowCD));//在标签上打印 我方舰队 第一只船 第一个武器组 第一门炮的cd
thisGuanQia->ui->myship->labelKey->setText(&#34;W&#34;+QString::number(ctrl.keyW)+&#34;S&#34;+QString::number(ctrl.keyS)+&#34;A&#34;+QString::number(ctrl.keyA)+&#34;D&#34;+QString::number(ctrl.keyD)+&#34;↑&#34;+QString::number(ctrl.keyUp)+&#34;↓&#34;+QString::number(ctrl.keyDown)+&#34;←&#34;+QString::number(ctrl.keyLeft)+&#34;→&#34;+QString::number(ctrl.keyRight)+&#34;GN&#34;+QString::number(ctrl.keyShift)+QString::number(ctrl.keyCtrl)+QString::number(ctrl.keyAlt)); //打印键盘事件那时不会调编辑器缩进,现在也忘了qt原生编辑器是长啥样的。反正基本上整段代码写在一行里…………看代码要按紧shift+滚轮,对小拇指可是个考验。
终于会用队列了,比如开炮时的火光就是将特效序列帧存入一个队列,然后每帧读取一张。还写了一套几何碰撞检测,虽然只支持点、线、椭圆、长方形这四种元素。逻辑和渲染终于分开了。还写了一段帧率控制算法,按本帧逻辑部分的执行时间决定接下来sleep多久,使帧率尽量稳定在30。(然而加这玩意使帧率更不稳定,后来全删了)
最后先帝创业未半而中道崩黜,加了很多功能后帧率实在太低。用的应该是2代i5m集显,帧率只有12不到……
再后来接触了“真正”的游戏引擎,发现啊这个也太方便太易用了。原来之前花了很多时间瞎折腾的烂代码,在引擎里竟然全有对应功能的接口?我想到的,前人全都想到过啊。
随便聊一下,引擎里最让我愉悦的是cocos creator。新手教程级的文档,极其舒服的环境。对比隔壁unity,去unity和ccc的api文档用中文搜点东西,ccc大多是你想要的,unity文档搜索是什么玩意。ccc的中文社区建设的也挺好,活跃度高,干货多;而且中文搜索引擎能直接搜到帖子内容。unity中文社区,??? 可惜ccc本质还是个轻(棋)量(牌)级引擎,论功能跟unity、ue暂时还没得比。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|