前言
这个程序是我初二写的,那是还不是很成熟,导致C、C++混在一起,警告一大堆。。
不过这个程序是我第一部 成功做成的游戏。
虽然关卡只做了3关,但是这个游戏代码框架值得参考。
(关卡可以自己再加,就在那个数组那里)
我大部分的程序都包含了我自己做的头文件,因此弄这儿来的时候必须替换一大堆东西,可能有些BUG。敬请谅解。
原来还是有音乐的,因为没有资源而且大小很大的问题,把它去了,如果真想要可以到这里下载,这里的源文件是真正的源文件,没有替换过的,当然无法通过编译,仅供参考。。。
> 点此下载控制台版 <
那个寒假前半部分又做了一个ege版,可以加载图片与音乐,效果好多了(不要问为什么都是从别的游戏里取来的资源,因为我没别的地方好取…)。做了12关,可以玩玩看,地址:
> 点此下载EGE版 <
音乐音量由于图形库的BUG我还不能调整
控制台是按键操作,EGE版是鼠标按键兼用。
我不是很在行,请忽略一些UI的外观问题及小bugs.
控制台版↑
EGE版↑
(我没有任何商业用途,不算侵权)
控制台版源码
Walker_Origin.cpp (修改后的控制台程序,可以通过编译)↓
/*
%%% COPY RIGH/LEF T <C> 2020 %%%
Name: Walker.cpp
Author: cjz2005
Description: A game
%%% ALL RIGHTS RESERVED %%%
*/
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <Windows.h>
#define _up 'w'
#define _down 's'
#define _left 'a'
#define _right 'd'
#define SINT short int
#define USINT unsigned short int //这一句作废(因为USINT就是UINT)
#define HIDH printf("\033[?25l")//隐藏光标;
#define banben "1.0"
using namespace std;
//这些函数随便用,网上都有的
int RandInt(int min,int max)
{
srand(time(NULL));
return (rand()%(max-min+1))+max;
}
VOID Cls(VOID) { //Clear the screen
system("cls");
return;
}
void HideCursor()
{
CONSOLE_CURSOR_INFO cursor_info = {10, 0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
VOID SetColor(UINT uFore,UINT uBack) {
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle,uFore+uBack*0x10);
//CloseHandle(handle);
}
VOID SetPosC(COORD a) { // set cursor
HANDLE out=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(out, a);
}
VOID SetPos(short x, short y) { // set cursor2
COORD pos= {x, y};
SetPosC(pos);
}
VOID DrawCol1(int x, int y1, int y2, char ch) {
int y=y1;
while(y!=y2+1) {
SetPos(x, y);
putchar(ch);
y++;
}
}
VOID DrawCol1D(int x, int y1, int y2, char ch,DWORD dwMilliSeconds) {
int y=y1;
while(y!=y2+1) {
SetPos(x, y);
putchar(ch);
y++;
Sleep(dwMilliSeconds);
}
}
VOID DrawRow1(int y, int x1, int x2, char ch) {
SetPos(x1,y);
for(int i = 0; i <= (x2-x1); i++)
putchar(ch);
}
VOID DrawRow1D(int y, int x1, int x2, char ch,DWORD dwMilliSeconds) {
SetPos(x1,y);
for(int i = 0; i <= (x2-x1); i++) {
putchar(ch);
Sleep(dwMilliSeconds);
}
}
VOID DrawRow(COORD a, COORD b, char ch) {
if(a.Y == b.Y)
DrawRow1(a.Y, a.X, b.X, ch);
else {
abort();
}
}
VOID DrawRowD(COORD a, COORD b, char ch,DWORD dwMilliSeconds) {
if(a.Y == b.Y)
DrawRow1D(a.Y, a.X, b.X, ch,dwMilliSeconds);
else {
abort();
}
}
COORD p={0,0};
const USINT level_w=8;
const USINT level_h=8;
bool coll[level_w][level_h];
COORD c1={0,0},c2={99,0};
USINT data[30][level_w][level_h]=
{ //这里是地图数据,可以进行添加和修改。
{
{1,1,1,1,1,1,1,1
},
{1,6,2,0,0,0,1,2
},
{1,0,0,0,2,0,1,1
},
{1,3,1,1,1,0,1,2
},
{3,0,0,0,0,0,3,1
},
{4,0,1,2,1,2,4,1
},
{4,0,0,0,0,0,0,7
},
{1,3,2,4,2,1,3,3
}},
{
{1,3,1,2,1,1,1,0
},
{1,6,3,0,0,0,1,0
},
{1,0,0,0,2,0,1,0
},
{1,0,2,1,1,0,1,0
},
{1,0,0,5,0,0,3,0
},
{3,2,1,2,1,0,4,0
},
{4,7,0,0,0,0,0,4
},
{1,4,3,2,2,1,1,3
}},
{
{1,1,1,1,1,1,1,1
},
{1,6,2,0,0,0,0,2
},
{1,0,0,0,2,5,0,1
},
{1,3,5,1,1,0,0,2
},
{3,0,5,0,0,0,4,1
},
{3,0,1,0,1,2,3,1
},
{4,5,0,0,0,0,0,7
},
{4,3,2,4,2,1,3,3
}
}
};
//HANDLE mfun;
//HANDLE mfunc;//崩溃
USINT nlevel;
USINT elevel2;
HWND hwnd=FindWindow("ConsoleWindowClass",NULL);
bool isgo=true;
bool IsBarrier(SINT blockId=-1)
{
bool r=0;
switch(blockId)
{
case -1:r=0;break;
case 0:case 5:case 6:case 7:
r=0;break;
default:
r=1;break;
}
return r;
}
void PrintLevel(USINT uLevel)
{
SetPos(4,5);
for(int i=0;i<30;i++)
{
if(i<uLevel)
{
SetColor(10,0);
cout<<" "<<i+1;
}
else
{
SetColor(8,0);
cout<<" ▓";
}
}
return;
}
/*
0 = 黑色 8 = 灰色
1 = 蓝色 9 = 淡蓝色
2 = 绿色 10 = 淡绿色
3 = 浅绿色 11 = 淡浅绿色
4 = 红色 12 = 淡红色
5 = 紫色 13 = 淡紫色
6 = 黄色 14 = 淡黄色
7 = 白色 15 = 亮白色
*/
void DrawBlock(int bid)
{
USINT f=7,b=0;
bool isch=true;
char *ch;
switch(bid)
{
case 0:isch=false;ch=(LPSTR)" ";break;
case 1:f=7;b=0;ch=(LPSTR)"□";break;
case 2:f=6;b=0;ch=(LPSTR)"■";break;
case 3:f=8;b=0;ch=(LPSTR)"■";break;
case 4:f=4;b=0;ch=(LPSTR)"▓";break;
case 5:f=12;b=0;ch=(LPSTR)"◎";break;//mine
case 6:f=2;b=10;ch=(LPSTR)"◆";break;//start
case 7:f=4;b=12;ch=(LPSTR)"◆";break;//end
default:isch=false;ch=(LPSTR)" ";break;
}
SetColor(f,b);
cout<<ch;
return;
}
void PlayLevel(USINT elevel)
{
char chp;
char menui;
string reason;
//COORD end={0,0};
const COORD start[30]= //起点
{
{1,1},{1,1},{1,1}
};
bool iswin=false;
bool ismenu=false;
//memset(data1,2,sizeof(data1));
//data1=data[elevel];
/*switch(elevel)
{
case 1:case 2:p.X=1;p.Y=1;break;
default:p.X=1;p.Y=1;break;
}*/
p.X=start[elevel-1].X;p.Y=start[elevel-1].Y;
while(1)
{
Cls();
ismenu=false;
for(int i=0;i<level_w;i++)
{
for(int j=0;j<level_h;j++)
{
if(p.X!=j||p.Y!=i)
{
DrawBlock(data[elevel-1][i][j]); //画图
}
else
{
SetColor(15,0);
cout<<"♀";
}
}
cout<<"\n";
}
if(data[elevel-1][p.Y][p.X]==7) //终点
{
iswin=true;
break;
}else if(data[elevel-1][p.Y][p.X]==5) //地雷
{
iswin=false;
reason="被地雷炸死了";
SetPos(p.X+3,p.Y);
SetColor(14,4);
cout<<"炸";
Sleep(100);
SetColor(12,0);
break;
}
SetColor(13,0);
DrawCol1(70,0,33,'|');
SetPos(72,1);
SetColor(15,0);
cout<<"第"<<elevel<<"关";
SetPos(72,0);
SetColor(7,0);
cout<<"In block's ID:"<<data[elevel-1][p.Y][p.X];
chp = getch();
switch(chp)//操作
{
case 97:if(!IsBarrier(data[elevel-1][p.Y][p.X-1]))p.X-=1;break;//A
case 115:if(!IsBarrier(data[elevel-1][p.Y+1][p.X])) p.Y+=1;break;//S
case 100:if(!IsBarrier(data[elevel-1][p.Y][p.X+1])) p.X+=1;break;//D
case 119: if(!IsBarrier(data[elevel-1][p.Y-1][p.X]))p.Y-=1;break;//W
case 27:ismenu=true;break;//Esc菜单
default:break;
}
if(ismenu)
{
Cls();
SetPos(44,3);
SetColor(11,0);
cout<<"主 菜 单";
SetPos(45,5);
SetColor(14,0);
cout<<"Q:退出";
SetPos(45,7);
cout<<"R:重来";
SetPos(41,9);
SetColor(10,0);
cout<<"[Esc:返回游戏]";
menu://菜单
menui=getch();
if(menui==113||menui==81)
{
SetPos(30,13);
SetColor(11,0);
cout<<"* 退出会放弃本关的操作,是否继续?[回车:是/其它:否] ";
if(getch()==13)
{
Cls();
isgo=false;
elevel2=1;
return;
}else
{
SetPos(42,13);
cout<<" ";
goto menu;
}
}else if(menui==114||menui==82)
{
SetPos(42,13);
SetColor(12,0);
cout<<"% 重来……";
Sleep(100);
isgo=true;
elevel2=elevel;
return;
}else if(menui==27)
{
ismenu=false;
}else
goto menu;
}
}//while
if(iswin) //成功
{
FILE *fp;
Sleep(150);
Cls();
SetColor(10,0);
if(elevel==nlevel)
DrawRowD(c1,c2,'@',20);
else
DrawRow(c1,c2,'@');
SetPos(42,2);
SetColor(10,0);
cout<<" 恭 ";
Sleep(200);
cout<<"喜!";
SetPos(39,3);
SetColor(7,0);
cout<<"第"<<elevel<<"关闯关成功!";
SetPos(0,33);
SetColor(10,0);//light green
if(elevel==nlevel)
{
DrawRow1D(40,0,99,'@',20);
SetPos(0,0);
DrawCol1D(0,0,33,'@',77);
SetPos(99,0);
DrawCol1D(99,0,33,'@',77);
}
else
{
DrawRow1(40,0,99,'@');
SetPos(0,0);
DrawCol1(0,0,33,'@');
SetPos(99,0);
DrawCol1(99,0,33,'@');
}
fp = fopen("save.wld","wb");
fprintf(fp,"%d",nlevel+1);
fclose(fp);
SetPos(42,10);
SetColor(8,0);
cout<<"回车:下一关";
SetPos(42,11);
cout<<"r:再闯一次";
SetPos(42,12);
cout<<"Esc:回到关卡页面";
Sleep(100);
SetPos(42,10);
SetColor(6,0);
cout<<"回车:下一关";
SetPos(42,11);
cout<<"r:再闯一次";
SetPos(42,12);
cout<<"Esc:回到关卡页面"; //渐变动画
Sleep(200);
SetPos(42,10);
SetColor(14,0);
cout<<"回车:下一关";
SetPos(42,11);
cout<<"r:再闯一次";
SetPos(42,12);
cout<<"Esc:回到关卡页面";
ichp:
chp=getch();
if(chp==13)//enter
{
isgo=true;
elevel2=elevel+1;
if(elevel==nlevel)
++nlevel;
//PlayLevel(++nlevel);
}else if(chp==114)//r
{
isgo=true;
elevel2=elevel;
if(elevel==nlevel)
++nlevel;
//PlayLevel(nlevel++);
}else if(chp==27)//esc
{
isgo=false;
elevel2=1;
if(elevel==nlevel)
++nlevel;
return;
}else
goto ichp;
}//success
else//失败
{
Sleep(200);
Cls();
SetColor(12,0);//dark red
if(elevel==nlevel)
{
DrawRowD(c1,c2,'%',10);
SetPos(0,33);
DrawRow1D(40,0,99,'%',10);
SetPos(0,0);
DrawCol1D(0,0,33,'%',30);
SetPos(99,0);
DrawCol1D(99,0,33,'%',30);
}else
{
DrawRow(c1,c2,'%');
SetPos(0,33);
DrawRow1(40,0,99,'%');
SetPos(0,0);
DrawCol1(0,0,33,'%');
SetPos(99,0);
DrawCol1(99,0,33,'%');
}
SetPos(41,2);
SetColor(13,0);
cout<<"失 ";
Sleep(100);
cout<<"败!";
SetPos(41,3);
SetColor(8,0);
cout<<"原因: "<<reason;
SetPos(42,6);
SetColor(8,0);
cout<<"R:重来";
SetPos(42,8);
cout<<"Esc:回到关卡页面";
Sleep(100);
SetPos(42,6);
SetColor(6,0);
cout<<"R:重来";
SetPos(42,8);
cout<<"Esc:回到关卡页面"; //渐变动画
Sleep(200);
SetPos(42,6);
SetColor(14,0);
cout<<"R:重来";
SetPos(42,8);
cout<<"Esc:回到关卡页面";
ichpf:
fflush(stdout);
chp=getch();
//CloseHandle(mfun);
if(chp==114)//R
{
isgo=true;
elevel2=elevel;
}else if(chp==27)//esc
{
isgo=false;
elevel2=1;
return;
}else
goto ichpf;
} //fail
return;
}
int main()
{
int isnl;
int elevel;
USINT rlevel=2;
char *cmd;
char r1,r2,r3;
char title[16];
char titi;
FILE *fp;
string sfilename;
srand((int)time(0)); //随机种子
/*char path[MAX_PATH];
string paths;
getcwd(path,sizeof(path));
paths=path;
sfilename = paths.substr(0,paths.length()-6); */
tit: //标题画面
HideCursor(); //隐藏光标
//HIDH;
sprintf(title,"title Walker v%s",banben);
system(title);
system("mode con cols=100 lines=40");//窗口宽度高度
SetColor(10,0);
DrawRow(c1,c2,'*');
SetPos(45,1);
SetColor(11,0);
cout<<"W A L K E R";
SetPos(44,17);
SetColor(14,0);
cout<<"回车: 开始游戏";
SetPos(44,22);
cout<<"Q或Esc:退出游戏";
SetPos(0,31);
SetColor(8,0);
cout<<"编者:cjz2005";
SetPos(0,33);
SetColor(7,0);
cout<<"Walker v"<<banben;
do
{
titi=getch();
if(titi=='q'||titi=='Q'||titi==27)
{
FlashWindow(hwnd,true);
Sleep(100);
FlashWindow(hwnd,false);
Sleep(100);
ShowWindow(hwnd,SW_HIDE);
Sleep(300);
exit(0);
}
}while(titi!='q'&&titi!='Q'&&titi!=13&&titi!=27);
Cls();
SetColor(10,0);
DrawRow(c1,c2,'#');
SetPos(45,1);
SetColor(11,0);
cout<<"W A L K E R";
SetPos(44,13);
cout<<"*正在载入存档...";
Sleep(300);
if((fp = fopen("save.wld","r")) == NULL)
{ SetPos(37,14);
cout<<"*没有找到存档,正在新建文档...";
Sleep(600);
fp = fopen("save.wld","w");
fprintf(fp,"2");
nlevel=1;
fclose(fp);
}else
{
fscanf(fp,"%d",&rlevel);
nlevel=rlevel/*-1*/;
fclose(fp);
}Cls();
//nlevel--;
if(nlevel==0)
{
system("color 0B");
SetPos(35,20);
cout<<"出错,游戏崩溃中……";
MessageBeep(MB_ICONHAND);
Sleep(100);
fp=fopen("save.wld","w");
fprintf(fp,"2");
fclose(fp);
Sleep(10000);
abort();
}
fclose(fp);
lec: // 选择关卡
Cls();
SetColor(10,0);
DrawRow(c1,c2,'=');
SetPos(45,1);
SetColor(11,0);
cout<<"选 择 关 卡";
PrintLevel(nlevel);
SetPos(4,10);
SetColor(14,0);
cout<<"·Enter:进入下一关";
SetPos(4,11);
cout<<"·Esc:返回";
SetPos(4,12);
cout<<"·其它:选择关卡";
isnl=getch();
if(isnl==13)elevel=nlevel;//enter
else if(isnl==27)//esc
{
goto tit;
}
else{//choosing
SetPos(4,13);
SetColor(11,0);
cout<<"* 输入关卡(输入0退出): ";
scanf("%d",&elevel);
if(elevel==0)
{
goto lec;
}
if(elevel<=0||elevel>nlevel)
{
do{
cout<<"\r ";
SetPos(3,11);
SetColor(12,0);
if(elevel>nlevel)
cout<<"·您输入的关卡未解锁,请";
else
cout<<"·您输入的关卡不在范围内,请";
cout<<"重新输入关卡: ";
SetColor(10,0);
scanf("%d",&elevel);
}while(elevel<=0||elevel>nlevel)
;
}
}
SetPos(3,11);
SetColor(12,0);
cout<<"\r ";
//getch();
Cls();
PlayLevel(elevel);
do{
if(isgo)
PlayLevel(elevel2);
}while(isgo);
Cls();
goto lec;
return 0;
}
后记
感谢你的浏览。
编译试试看
(还有一点,我用的IDE是Dev C++【内核是GCC编译器】,不能使用#pragma comment,因此要试图加载音乐的时候,得链接winmm。我这里就加个参数就可以了: