开发一款游戏也许看起来十分困难,但在C++的帮助下,将会变得更加简单。
如果你是一个开发游戏的老手,应该知道Unity引擎。这个引擎不但提供了逻辑的支持,还提供了UI的支持。可以说的五脏俱全。
但是,我们也想开发一个游戏引擎。可以实现。但是……
今天我们的主角是纯逻辑引擎,意思就是说,给与逻辑(也就是功能)的支持,不给予UI的支持。
好了,不要说这么多了,赶紧进入正题吧!
选用C还是C++
也许很多人更偏向C++。因为C++的功能明显比C强很多。以及C++的面向对象。(这点十分重要!)
C++的面向对象可以说是至关重要。为什么呢?一个例子“秒懂”:
//C
#include <stdio.h>
int main(){
int player1_hp=100,player1_agg=50;
int player2_hp=120,player2_agg=20;
printf("player1攻击了player2");
player1_hp-=player2_agg;
printf("%d",player1_hp);
return 0;
}
而C++:
//C++
#include <iostream>
#include <string>
using namespace std;
class Player{
public:
string name="无名氏";
double hp=100.00;
double agg=50.00;
double dv=20.00;
void agg_to(double *hp,double *dv){
*hp-=agg-*dv;
}
};
int main(){
Player Player1;
Player Player2;
Player2.hp=120.00;
Player1.agg_to(&Player2.hp,&Player2.dv);
cout<<Player2.hp<<endl;
}
C++的指针以及面向对象给了我们很好的开发方法。我们利用这些新特性,可以更快、更好的开发游戏逻辑引擎!
项目声明
版权归本人所有,未经允许不可转载。
不可用于商业用途,可联系作者购买版权并用于商业。
项目开发过程
纠结症必看
我们采用的是dev-cppIDE开发环境。其实我觉得已经足够了。如果用vs怕磁盘爆掉,用codeblock怕不熟练。想来想去最后还是决定使用dev-cpp,各位可以使用也可以自选。
开始开发
我们新建一个项目,新建一个文件(game.h),准备开始开发:
#include <iostream>
using namespace std;
先将这个基础打好后,我们再来写一个class:
class Player{
public:
string name="Guest"; //角色名 可用Player.name=xxx更改
double hp=0; //生命值 必须使用Player.set_hp设置,如需减少需使用Player.reduce_hp减少指定数值,增加需使用Player.plus_hp增加
double dv=0; //防御值 必须使用Player.set_dv设置,当触发攻击时自动运算并修改
string buff="无BUFF"; //New! 你可以设置Buff来让角色更加强大 此选项供开发者自行调用,可使用Player.buff=xxx
double agg=0; //攻击力 必须使用Player.set_agg设置,会自动修改
double chp=0; //暴击力 必须使用Player.set_chp设置,会自动修改
double scp=0; //超级暴击伤害力 必须使用Player.set_scp设置,会自动修改
double power=0; //力气,让角色的攻击力、暴击力通过力气提升 必须使用Player.set_power修改
double endurance=0; //耐力,耐力越高,生命值以及暴击伤害越高 必须用Player.set_endurance 修改
double agile=0; //敏捷力。如果敏捷力高,角色可以更高概率躲避暴击 必须用Player.set_agile
double intelligence=0; //智力。如果智力高,敏捷力、耐力都会随之变高。 必须用Player.set_intelligence
int player=0; //需使用Player.set_player(X)设置,可选:1:剑士 2:弓箭手 3:巨人
int player_buff=0; //使用Player.set_player_buff(X)设置,可选:1:神清气爽(耐力、力气、智力、敏捷力提高10)2:大快朵颐(通常在食用某种食品后,智力、耐力提高50)
double dwa=0; //收到攻击时的额外伤害,可直接修改,可用于特殊关卡
double ms=0; //移速,可直接修改,供自行调用
int chr=0;//暴击可能性(1 几率小 2 随机 3 几率大),需使用Player.set_chr(X)设置
bool obm=false; //是否打开“荆棘模式”(伤害反弹) 需使用Player.set_obm(True or False)
bool survival=true; //是否存活。需使用Player.set_survival(True or False)设置
bool debug=false; //角色是否开启Debug.需使用Player.set_debug(True or False)设置
double x=0; //坐标X,供2D/3D游戏定位使用 ,直接修改
double y=0; //坐标Y ,供2D/3D游戏定位使用 ,直接修改
double z=0; //坐标Z,,供3D游戏定位使用,直接修改
int lv=1; //等级 可直接修改,但不会有属性提升。需要使用upgrade升级
这些基本的功能我们都必须要实现。否则这个逻辑引擎将会没有意义。本引擎可用于很多开发用途,自选。
既然框架已经打好了,接下来,便是一个个完成功能了!
生命值
生命值是游戏里很关键的一部分。(缩写hp)它用来判断这个角色的存活,以及这个角色的——用最简单的网络用语来说,就是“血厚不厚”。
生命值越高,不一定能决定胜负。假设你的生命值500,对方100,但是你攻击力10,它攻击力100,这简直不能比,对不对?
既然生命值这么重要,我们就来开发第一个功能:生命值设置、减少、增加。
也许你很奇怪,为啥不直接Player.hp=xxx?
因为我们还得加上一些“连锁反应”!
void set_hp(double sethp){
hp=sethp;
if(debug){
cout<<"设置了角色"<<name<<"的生命值为"<<hp;
}
}
void reduce_hp(double reducehp){
hp-=reducehp;
if(debug){
cout<<"将角色"<<name<<"的生命值减去了"<<reducehp<<endl;
}
}
void plus_hp(double plushp){
hp+=plushp;
if(debug){
cout<<"将角色"<<name<<"的生命值增加了"<<plushp<<endl;
}
}
细心地朋友发现了,之前有一个debug选项。没错,为了让开发者可以看到debug,不得不让他们使用函数修改。(我表示我太难了)
防御值
防御值也十分重要!如果你有100HP,50DV,20AGG。而对方有100HP,0DV,50AGG,你猜猜,谁赢谁输?
当然是你赢啊!因为——你的50DV完全免疫了对方的攻击力(AGG)。
所以,为了保证游戏合理性,推荐各位开发者在使用引擎时务必注意这个DV的设置(虽然有时候有暴击可以把盾打穿,但……)
好吧,废话不多说,上代码。
void set_dv(double setdv){
dv=setdv;
if(debug){
cout<<"将角色"<<name<<"的防御值设置为了"<<dv<<endl;
}
}
哈哈哈,又是Debug,是不是感觉很无语?
自定义BUFF
上面有两个BUFF——一个buff和一个player_buff。这两个有什么不同?仔细阅读注释,你应该会恍然大悟。
buff值供开发者自行调用(例如自己编写一个BUFF特性),而player_buff存储了一些已经写好的buff特效,供开发者调用。
buff这个单词,其实很早就出现了。如果你敲上fanyi.baidu.com,一搜……浅黄色!
呵呵,其实不是这个意思。这个词主要是在网络上经常出现。意思就是一种技能。获取后可以加强某些参数(例如agg)
好了,也不废话了,上代码!
唉唉,搞错了搞错了,注释后面写了直接调用[笑],真是糊涂了。
攻击力
“一寸攻击一寸金,寸金难买VIP”这句话最近在我身边朋友口中疯传(我说的……)。哈哈,这句话很好的说明了攻击力的作用。攻击力越高,取胜可能性越大。但也要结合DV、HP来进行分析(我听到有人说hp是*普,不是不是)(我又听到有人说我做植入广告,不是的啦!)
好了,接下来,上代码!
void set_agg(double setagg){
agg=setagg;
if(debug){
cout<<"将角色"<<name<<"的攻击力设置为了"<<agg<<endl;
}
}
emmm……继续debug……
CHP AND SCP:暴击力 And 超级暴击力!
暴击力其实没啥用(我玩游戏从来不看暴击……),为什么?因为暴击顶多多几个伤害,但却可能性非常小。
“风吹马尾千条线,暴击完全不兑现。”这句话也许也是挺………………但是也可以体现出暴击的不重要性(偷笑)。
好了,上代码!
void set_chp(double setchp){
chp=setchp;
if(debug){
cout<<"将角色"<<name<<"的暴击力设置为了"<<agg<<endl;
}
}
void set_scp(double setscp){
scp=setscp;
if(debug){
cout<<"将角色"<<name<<"的超级暴击力设置为了"<<scp<<endl;
}
}
哈哈,继续Debug,嘚嘚~
特殊选项
玩游戏经常有一些特殊选项。例如肚子饿不饿啊,力气足不足啊,精力咋样啊,这些都是很常见的。所以,我们不得不实现。
code!
void set_power(double setpower){
power=setpower;
agg+=setpower*5;
chp+=setpower*5;
if(debug){
cout<<"将角色"<<name<<"的力气设置为了"<<power<<endl;
}
}
void set_endurance(double setendurance){
endurance=setendurance;
hp+=setendurance*10;
chp+=setendurance*5;
if(debug){
cout<<"将角色"<<name<<"的耐力设置为了"<<endurance<<endl;
}
}
void set_agile(double setagile){
agile=setagile;
if(debug){
cout<<"将角色"<<name<<"的敏捷力设置为了"<<agile<<endl;
}
}
void set_intelligence(double setintelligence){
intelligence=setintelligence;
set_agile(agile+setintelligence*5);
set_endurance(endurance+setintelligence*8);
if(debug){
cout<<"将角色"<<name<<"的智力设置为了"<<intelligence<<endl;
}
}
哇塞,除了debug外终于来新人了,好Happy~~
预设
为了让游戏开发者可以先测试一下引擎,我们准备了三个角色预设:
No.1 Swordsman
No.2 Archer
No.3 giant
(PS:Google翻译果然香)
这三个预设肯定得函数设置的啦!
void set_player(int player){
if(player==1){
// 默认角色:剑士
set_hp(100.00);
set_agg(15.05);
set_dv(5.25);
name="剑士";
}
else if(player==2){
// 默认角色:弓箭手
set_hp(80.00);
set_agg(22.00);
set_dv(5.00);
name="弓箭手";
}
else{
// 默认角色:巨人
set_hp(500.50);
set_agg(25.05);
set_dv(0);
name="巨人";
}
}
接着,就是我们的自带BUFF:
void set_player_buff(int buff){
if(debug){
cout<<name<<"的系统自带BUFF被改为参数:"<<buff<<endl;
}
if(buff==1){
// 神清气爽
set_agile(agile+10);
set_endurance(endurance+10);
set_intelligence(intelligence+10);
set_power(power+10);
}
else if(buff==2){
// 大快朵颐
set_endurance(endurance+50);
set_intelligence(intelligence+50);
}else if(buff==-1){
// 恢复神清气爽buff之前的状态
set_agile(agile-10);
set_endurance(endurance-10);
set_intelligence(intelligence-10);
set_power(power-10);
}else if(buff==-2){
// 恢复大快朵颐
set_endurance(endurance-50);
set_intelligence(intelligence-50);
}
}
高级特性
一把上代码吧:
int set_chr(int setchr){
// 1 非常小 2 随机 3 很大
chr=setchr;
return 1;
}
void set_obm(bool setobm){
obm=setobm;
if(debug){
cout<<name<<"的OBM值被设置为了"<<obm<<endl;
}
}
int set_survival(bool setsurvival){
if(setsurvival!=true){
survival=false;
if(debug){
cout<<name<<"的存活值被设置为了"<<setsurvival<<" 此角色已退出游戏"<<endl;
}
}
else{
survival=true;
}
return survival;
}
int set_debug(bool setdebug){
if(setdebug){
debug=true;
}
return 1;
}
int ua(Player aPlayer){
// 角色被攻击
// aPlayer>攻击角色的另一个角色
if(survival && aPlayer.survival){
double za=0; //最后受到的攻击力
za+=aPlayer.agg;
za-=dv;
za-=rand()%5;
if(za<=0){
if((rand()%5)==1){
return -1; //-1代表免疫了
}
// 有几率免疫,如果没有免疫,就将攻击力提升
za+=aPlayer.agg;
za-=dv;
za-=rand()%3;
if(za<=0){
// 实在无法计算,返回-2,说明比赛不公平,无法进行
if(debug){
cout<<"太不公平了!通过护盾的抵御,攻击被瓦解!"<<endl;
}
return -2;
}
}
// 设置好最后受到的攻击后
// 判断暴击与超级暴击
srand((int)time(0));
if(chp!=0){
if(agile>10){
//结束暴击
}else{
if(chr==1){
if(rand()%100==18){
za=aPlayer.chp;
}
}
if(chr==2){
int randnum=rand()%100;
if(randnum==18 || randnum==12 || randnum==48 || randnum==69 || randnum==89 || randnum==99){
za=aPlayer.chp;
}
}
if(chr==3){
int randnum=rand()%100;
if(randnum>50 && randnum<80){
za=aPlayer.chp;
}
}}
}
int randnum2=rand()%100;
if(aPlayer.scp!=0){
if(randnum2==1){
za=aPlayer.scp;
}
}
if(debug){
cout<<"角色"<<name<<"即将受到"<<za<<"点攻击。"<<endl;
}
hp-=za;
if(debug){
cout<<"角色"<<name<<"的血量变为"<<hp<<"点。"<<endl;
}
if(hp<=0){
survival=false; //自动设置False
if(debug){
if(survival){
cout<<name<<"在与"<<aPlayer.name<<"的作战中死了。"<<endl;
}
}
}
return 1;
}
else{
if(debug){
cout<<"角色"<<name<<"或者角色"<<aPlayer.name<<"已经死了"<<endl;
}
}
}
void print_all(){
cout<<"PRINT_ALL"<<endl;
cout<<"角色名:"<<name<<endl; //角色名 可用Player.name=xxx更改
cout<<"生命值:"<<hp<<endl; //生命值 必须使用Player.set_hp设置,如需减少需使用Player.reduce_hp减少指定数值,增加需使用Player.plus_hp增加
cout<<"防御值:"<<dv<<endl; //防御值 必须使用Player.set_dv设置,当触发攻击时自动运算并修改
cout<<"自定义BUFF:"<<buff<<endl; //New! 你可以设置Buff来让角色更加强大 此选项供开发者自行调用,可使用Player.buff=xxx
cout<<"攻击力:"<<agg<<endl; //攻击力 必须使用Player.set_agg设置,会自动修改
cout<<"暴击力:"<<chp<<endl; //暴击力 必须使用Player.set_chp设置,会自动修改
cout<<"超级暴击力:"<<scp<<endl; //超级暴击伤害力 必须使用Player.set_scp设置,会自动修改
cout<<"特殊属性列表:"<<endl<<power<<endl; //力气,让角色的攻击力、暴击力通过力气提升 必须使用Player.set_power修改
cout<<endurance<<endl; //耐力,耐力越高,生命值以及暴击伤害越高 必须用Player.set_endurance 修改
cout<<agile<<endl; //敏捷力。如果敏捷力高,角色可以更高概率躲避暴击 必须用Player.set_agile
cout<<intelligence<<endl; //智力。如果智力高,敏捷力、耐力都会随之变高。 必须用Player.set_intelligence
cout<<"预设列表:"<<endl<<player<<endl; //需使用Player.set_player(X)设置,可选:1:剑士 2:弓箭手 3:巨人
cout<<player_buff<<endl; //使用Player.set_player_buff(X)设置,可选:1:神清气爽(耐力、力气、智力、敏捷力提高10)2:大快朵颐(通常在食用某种食品后,智力、耐力提高50)
cout<<"详细设置列表:"<<endl;
cout<<dwa<<endl; //收到攻击时的额外伤害,可直接修改,可用于特殊关卡
cout<<ms<<endl; //移速,可直接修改,供自行调用
cout<<chr<<endl;//暴击可能性(1 几率小 2 随机 3 几率大),需使用Player.set_chr(X)设置
cout<<"自定义高级参数:"<<endl;
cout<<obm<<endl; //是否打开“荆棘模式”(伤害反弹) 需使用Player.set_obm(True or False)
cout<<survival<<endl; //是否存活。需使用Player.set_survival(True or False)设置
cout<<debug<<endl; //角色是否开启Debug.需使用Player.set_debug(True or False)设置
cout<<"位置:"<<endl;
cout<<x<<endl; //坐标X,供2D/3D游戏定位使用 ,直接修改
cout<<y<<endl; //坐标Y ,供2D/3D游戏定位使用 ,直接修改
cout<<z<<endl; //坐标Z,,供3D游戏定位使用,直接修改
}
其他角色
既然Player对象已经完美完工了,接下来就得写其它的了。
玩游戏,你最常见……
NPC!
全部代码:
class npc{
public:
// NPC角色
// NPC功能不够完善,见谅
string name; //名字,使用npc.name=XX修改
double hp=0; //生命值,使用npc.set_hp(X)修改
double agg=0; //攻击力,使用npc.set_agg(X)修改
double x; //坐标X,供2D/3D游戏定位使用 ,直接修改
double y; //坐标Y ,供2D/3D游戏定位使用 ,直接修改
double z; //坐标Z,,供3D游戏定位使用,直接修改
string say[]; //设置说的话,游戏界面可以通过npc.say[x]获取,更便捷
bool survival; //自行修改,用来在游戏里判断存活
void set_hp(double sethp){
hp=sethp;
}
void set_agg(double setagg){
agg=setagg;
}
};
(PS:NPC只给了框架,没有其他的)
那么,还有……
物品!
class Prop{
public:
string name; //道具名称(可直接修改)
string introduce;//道具介绍 (可直接修改)
int prid;//道具ID(可直接修改)
string buff="无BUFF"; //设置角色会有什么自定义buff(可直接修改)
int player_buff=0; //设置角色会新增什么默认buff (直接修改)(详见player类)
int power=0; //增加力气值,让角色的攻击力、暴击力通过力气提升 必须使用prop.set_power修改
int endurance=0; //增加耐力值,耐力越高,生命值以及暴击伤害越高 必须用prop.set_endurance 修改
int agile=0; //增加敏捷力值。如果敏捷力高,角色可以更高概率躲避暴击 必须用prop.set_agile
int intelligence=0; //增加智力值。如果智力高,敏捷力、耐力都会随之变高。 必须用prop.set_intelligence
string use_type; //可加上你的使用类型(例如:饮料、食物、药品)
int use_lv=0; //限制使用等级
void set_power(int setpower){
power=setpower;
}
void set_endurance(int setendurance){
endurance=setendurance;
}
void set_agile(int setagile){
agile=setagile;
}
void set_intelligence(int setintelligence){
intelligence=setintelligence;
}
int use(Player usePlayer){
if(usePlayer.lv>=use_lv){
usePlayer.buff=buff;
usePlayer.player_buff=player_buff;
usePlayer.set_power(usePlayer.power+power);
usePlayer.set_intelligence(usePlayer.intelligence+intelligence);
usePlayer.set_agile(usePlayer.agile+agile);
usePlayer.set_endurance(usePlayer.endurance+endurance);
if(usePlayer.debug){
cout<<"角色"<<usePlayer.name<<"使用了道具"<<name<<endl;
}
return 1;
}
else{
return 0;//等级不足
}
}
};
完毕
好了,整个项目已经完工了(取名EasyGame)
版本号:1.0.0
已经开源到Gitee:https://gitee.com/tiantian520tt/easygame/
本人11,有不足见谅!