当前位置:文档之家› 坦克大战,及源代码

坦克大战,及源代码

采用双向循环链表作太极形式旋转的图案,图案的变化采用刷新屏幕的方法做到。

首先,建立一个二维字符数组,保存图形数据,然后通过更改该二维字符数组和清屏,再显示,做到图像的变化。

用它提示坦克大战游戏的操作方法。

再显示问题解决后,通过无回显读取函数getch();和输入流检查函数kbhit();读取输入的方向键或回车键进入下一页面。

用同样的方法,读取方向键和回车键,更改内部图案方法,使用户选择关:第一关:仅有4个坦克同时作战,总数为30个!第二关:仅有5个坦克同时作战,总数为40个!第三关:有6个坦克同时作战,总数为50个!第四关:有7个坦克同时作战,总数为60个!第五关:有8个坦克同时作战,总数为70个!选择关卡后,进入下一页面:进行相关提示。

最后进入游戏界面。

也可以通过按左方向键返回上一级重新选择!!!第一关到第三关:都是宽80,高42的。

最后两关:都是宽160,高42的。

右击标题栏选择属性,进入设置。

接着就是进入最重要的坦克大战游戏了:这时采用的就不是刷新屏幕能解决的问题了。

由于界面太大,不能刷新屏幕,仅能用光标移动函数来更改图像。

光标移动函数为gotoxy(int ,int );读者自己查看定义。

采用同样输入流读取方法。

接着是游戏规则,操作者用W.w.A.a.S.s.D.d移动坦克,空格是停下。

用方向键改变炮筒的方向,回车键是开火。

但当自己的炮弹还在运行时,不得开火!!!用链表保存每一辆坦克(包括主坦克)的数据。

电脑控制的坦克,被控制者的坦克炮弹击中,就会发生爆炸,并死亡。

当界面上的所有坦克小于特定值时,如果内部还有未出现的坦克,就会在上方的随机位置,产生新坦克。

如果操作者的坦克被击中,它的HP(我称为生命值)就会减一点。

刚开始游戏时的HP=5;但升级进入下一关时保留上一局的最后分数和HP。

不会重置。

但游戏中有补血包,可以补充生命值(HP)补血包每90秒出现一次,出现的时间长为60秒。

如果在这期间操作者的坦克运动到它的位置,补血包将给操作者的坦克补血。

补血包不会给其它坦克补血,仅会给操作者的坦克补血。

补血包会闪烁,提示它的出现。

界面还提供了每局的游戏时间。

和剩敌数,及一些操作命令。

当游戏结束或胜利要进入下一关时,界面还会运行5秒钟。

B.b.的暂停是用getch();读取做到的。

退出是直接将循环条件重置为0;重载视图会在视图为80×42的视图中显示边界,或消失边界。

操作者可以自己调整。

为了更好的游戏,让操作者的坦克跑得比其它坦克块。

当电脑控制的坦克在正前方发现操作者的坦克就准备并等待着开火。

开火完就跑。

游戏的目的是反映的挑战。

当游戏结束或退出时会回到关卡的选择界面,在那里选择退出,就会有留恋的告别对话,此时仍然可以返回上一级,继续游戏。

通过设置颜色改变字体和背景颜色,使界面更好看:以下是总结:在这个有点大的游戏中最大的难题,不是显示问题,也不是同时控制多个对象的问题。

最难的有两个:一、坦克的智能化处理。

二、修复同时控制最多有23个对象时共用数据时产生的bug。

如,当坦克被击中,就应该扫描是谁被击中,否则不可能知道是谁。

可是扫描到链表的最后一个节点时,直接往下就将指针重置为NULL了,可是返回主函数我还在求那个指针所指向的链表节点的数据。

直接接bug,并且把所有的函数分开测或,重新检查,再100年也检查不出问题的所在。

这就是最大的痛苦,前一次尝试,就是吃了这个苦头,前一天晚上检差到第二天的晚上都检查不出来。

心理陷入极度的痛苦,最终放弃。

这就是最大的教训之一!!!又比如:前一次尝试中,采用同一种方法控制所有内部的坦克,结果所有的坦克,聚成一团,怎么也拆不开。

用统一的“引力”和“排斥力”都不管用。

写了一个又一个方案都只能宣告失败。

自信受到了极大的打击,十分痛苦。

经过演示版本(操作者的坦克阵亡后,不自动退出)的测试:在长达13小时多的运行中没有任何bug的出现。

这是一张代表图:图案不同于其它的是操作者控制的坦克。

有一辆坦克将炮筒指向了它。

它却先跑了一段。

圆球都是敌方坦克的炮弹。

它身陷危险之中。

因为这些坦克是猛兽而并不像表面那么温和。

它的右上方有一个补血包正在闪烁。

下方有很多重要的提示信息。

#include<iostream>#include<conio.h>#include<stdlib.h>#include<windows.h>#include<time.h>using std::cin;using std::cout;const int S_X=80;const int S_Y=40;int welcome(void);void start_restart_end(int cammand);void message(int cammand);void new_tank(void);void auto_aim(void);void find_control_tank(void);void through_all_aim(void);int tank_move(void);void fire(void);void shell_move(void);void shell_explode(void);void delete_tank(void);void tank_die(void);void renew_tank(void);int HP_plus(int cammand);void gotoxy(int x, int y);void write_1(int x,int y,char type);void write_3(int x,int y,char type);void write_3_no(int x,int y,char type);char S_S[S_Y][S_X];int the_right;char tank_xx[3][7]= {"■■■"," █","■■■"},tank_yy[3][7]= {"■■","■█■","■■"};char tank_0_xx[3][7]={"███"," █","███"},tank_0_yy[3][7]={"██","███","██"};char clear_3[3][7]={" "," "," "};char HP_showing[3][7]={"┏┓"," ╋","┗┛"};char explode_showing_0[3][7]={"╳╋╳","╋╳╋","╳╋╳"},explode_showing_1[3][7]={"╋╳╋","╳╋╳","╋╳╋"};char fire_xx[3]="━",fire_yy[3]="┃";char shell[3]="●";char clear_1[3]=" ";char well[3]="▓";int control_tank_HP;int auto_tank_sum,auto_tank_now;int grade=0,score;struct tank{int tank_direction_and_life;int change_direction_temporary;int tank_x;int tank_y;int shell_direction;int shell_explode;int shell_x;int shell_y;int aim_x;int aim_y;int fire_direction;int found_enemy_and_wasting_fire;tank *next;}*head=NULL,*here;void main(){while(welcome()){int control_upgrade=1;score=0;control_tank_HP=5;do{int control_gaming=1,control_out=200;start_restart_end(1);message(1);int time_to_message=(int)time(0);int time_to_plus_HP=(int)time(0),have_HP_plus=0,time_pause_save;int control_tank_wasting_go=0,control_tank_going=0;int auto_tank_wasting_go=0,auto_tank_going=1;here=head->next;do{Sleep(25);int direction_key=0,cammand_to_control_tank=0;while(kbhit()){switch(getch()){case(224):direction_key=1;break;case(72):if(direction_key)cammand_to_control_tank=11;break;case(77):if(direction_key)cammand_to_control_tank=12;break;case(75):if(direction_key)cammand_to_control_tank=14;break;case(80):if(direction_key)cammand_to_control_tank=13;break;case(13):cammand_to_control_tank=5;break;case(119):case(87):cammand_to_control_tank=1;break;case(97): case(65):cammand_to_control_tank=4;break;case(115):case(83):cammand_to_control_tank=3;break;case(100):case(68):cammand_to_control_tank=2;break;case(32):cammand_to_control_tank=6;break;case(114):case(82):message(2);break;case(112):control_upgrade=0;control_gaming=0;break;case(66):case(98):message(3);time_pause_save=(int)time(0);getch();time_to_plus_HP+=(((int)time(0))-tim e_pause_save);message(4);break;}}if(control_tank_HP){tank *temp_here=here;here=head;if(control_tank_wasting_go==0){if(control_tank_going){tank_move();control_tank_wasting_go=4;}}else{--control_tank_wasting_go;}switch(cammand_to_control_tank){case(11):case(12):case(13):case(14):{here->fire_direction=cammand_to_control_tank%10;new_tank();}break;case(1):case(2):case(3):case(4):{here->tank_direction_and_life=cammand_to_control_tank;new_tank();control_tank_going=1;}break;case(5):{fire();}break;case(6):{control_tank_going=0;}break;}here=temp_here;}if(auto_tank_going){if(here->tank_direction_and_life){if(here->found_enemy_and_wasting_fire){if(--here->found_enemy_and_wasting_fire==0)fire();}else{through_all_aim();auto_aim();if(((int)(100*rand()/RAND_MAX))<5)fire();if(control_tank_HP)find_control_tank();}}if(here->next){here=here->next;}else{auto_tank_going=0;here=head->next;}}if(auto_tank_wasting_go==0){auto_tank_going=1;auto_tank_wasting_go=8;}else --auto_tank_wasting_go;if(here==head->next){if(((int)time(0))-time_to_plus_HP>=90){HP_plus(1);have_HP_plus=1;time_to_plus_HP+=90;}if(have_HP_plus){have_HP_plus=HP_plus(0);}}{tank *temp_here=here;here=head;while(here){if(here->shell_direction){shell_move();if(control_tank_HP==0&&control_upgrade){here=head;delete_tank();control_upgrade=0;break;}}if(here->shell_explode)shell_explode();here=here->next;}here=temp_here;}if(control_tank_HP==0||(auto_tank_sum+auto_tank_now)==0){if(--control_out==0)control_gaming=0;}if(here==head->next)if(time_to_message!=(int)time(0)){message(0);tank_die();time_to_message=(int)time(0);}}while(control_gaming);if(control_upgrade){if(grade==5)control_upgrade=0;else grade++;}}while(control_upgrade);}start_restart_end(0);}void gotoxy(int x, int y){int xx=0x0b;HANDLE hOutput;COORD loc;loc.X=x;loc.Y=y;hOutput = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleCursorPosition(hOutput, loc);return;}void write_1(int x,int y,char type){gotoxy(x*2,y);switch (type){case('x'):cout<<fire_xx;break;case('y'):cout<<fire_yy;break;case('S'):cout<<shell; S_S[y][x]='S';break;case('s'):cout<<shell; S_S[y][x]='s';break;case(' '):cout<<clear_1;S_S[y][x]=' ';break;}}void write_3(int x,int y,char type){x-=1;y-=1;int j=-1,i;switch(type){case('A'):{while(++j<3){i=-1;while(++i<3){S_S[y][x+i]='0';}gotoxy(x*2,y++);cout<<tank_0_xx[j];}}break;case('B'):{while(++j<3){i=-1;while(++i<3){S_S[y][x+i]='0';}gotoxy(x*2,y++);cout<<tank_0_yy[j];}}break;case('X'):{while(++j<3){i=-1;while(++i<3){S_S[y][x+i]='1';}gotoxy(x*2,y++);cout<<tank_xx[j];}}break;case('Y'):{while(++j<3){i=-1;while(++i<3){S_S[y][x+i]='1';}gotoxy(x*2,y++);cout<<tank_yy[j];}}break;case(' '):{while(++j<3){i=-1;while(++i<3){S_S[y][x+i]=' ';}gotoxy(x*2,y++);cout<<clear_3[j];}}break;}}void write_3_no(int x,int y,char type){x-=1;y-=1;int j=-1;switch(type){case(' '):{while(++j<3){gotoxy(x*2,y++);cout<<clear_3[j];}}break;case('+'):{while(++j<3){gotoxy(x*2,y++);cout<<HP_showing[j];}}break;case('x'):{while(++j<3){gotoxy(x*2,y++);cout<<explode_showing_0[j];}}break;case('X'):{while(++j<3){gotoxy(x*2,y++);cout<<explode_showing_1[j];}}break;}}int welcome(){system("CLS");char S_1[][3]={"█","▉","▊","▋","▌","▍","▎","▏"};char S_2[][3]={"█","▇","▆","▅","▄","▃","▂","▁"};int page_now=1,page_showing=0;char S_H_0[]="↑",S_H_1[]="请用←↓→方向键控制坦克的开火方向",S_H_2[]="请用回车键开火",S_H_3[]="请用W.w.A.a.S.a.D.a.空格键.控制坦克的运行",S_H_4[]="R.r.键为重载视图",S_H_5[]="p.键是游戏中止,B.b.键是游戏暂停",S_H_6[]="(→键)下一步";char S_C_0[]="请用(↑↓键)选择:",S_C_1[]="(←键)返回上一级",S_C_2[]="我选→",S_C[][7]={"第一关","第二关","第三关","第四关","第五关","退出"}; char S_OK_0[]="当窗口大小和屏幕缓冲区大小为宽160,高42时",S_OK_1[]="也可用通过重载视图显示右界而不用设置",S_OK_2[]="可设置窗口属性->布局->(窗口大小和屏幕缓冲区大小)为宽80,高42。

相关主题