《C++小游戏》
游戏持续更新中,目前版本V1.8 \ 最近可能会断更一段时间,因为最近训练强度上来了摸不了鱼了qwq,感觉别人都是巨佬,而自己还是个蒟蒻 \ 代码长度:1627
废话不多说直接上代码!
喜欢的点个赞支持一下吧 \ (小声bb:感觉自己的码风排版都还不错,希望有人能看懂自己的代码并提出点改进建议(比如怪物巡逻机制,这是我个人目前还不满意的))
#include<bits/stdc++.h>
#include<conio.h>
#include<windows.h>
#define rint register int
#define mmt(a,b) memset(a,b,sizeof(a))
#define test(x) cout<<#x<<" = "<<x<<endl
#define made by Polynswin
#define endl '\n'
#define enter putchar(endl)
//#define int long long
using namespace std;
const int inf=0x3f3f3f3f,N=5e2+10;
const int dir_get_dpx[9]={0,0,-1,-1,-1,0,1,1,1},
dir_get_dpy[9]={0,1,1,0,-1,-1,-1,0,1},
item_cht[N] = {-1, 4, 5, 6, 7};
int mapw, maph, score, cnt, dir;
int lasts, lasts2, fps, run, vision_radius, startTime, choose=1, Rclick, key, mob_dizzy_time = 4000, shown_dir;
int item[N], item_len=4;
vector<int> item_score= {-1, 20, 10, 15, 20},
item_color= {-1, 1, 2, 5, 6};
bool clean_screen = true, enable =false, update_map, custom_map;
vector<string> item_name={"", "guide", "flash", "bomb", "vision"};
vector<string> mode_name =
{ "",
"特殊道具", "迷宫塌方", "收集钥匙", "爆炸伤害", "怪物追击",
"灯光不足(尚未开放)", "双人对战(尚未开放)", "特殊道具2(尚未开放)",
};
double cntttt=3, b_r = 0.75;//blocking_radius
int debug_cnt = 1,player_speed,mob_speed;
int last_time[N] = {-1, 0, -5001},
interval[N] = {-1, 2000, 5000};
string numball[N] = {" ","①","②","③","④","⑤","⑥","⑦","⑧","⑨"};
int mode_init[N][N]=
{
{},
{-1, 10, 10, 2, 2, 1, 10},
{-1, 20, 20, 5, 4, 3, 40} ,
{-1, 40, 40, 12, 4, 8, 60},
{-1, 100, 100, 100, 10, 20, 100},
{-1, 0, 0, 0, 0},
},
mode_item[N][N]=
{
{},
{-1, 1, 2, 0, 1},
{-1, 3, 5, 3, 2},
{-1, 7, 8, 5, 5},
{-1, 20, 40, 20, 10},
{-1, 0, 0, 0},
},
mode_item_init[N][N]=
{
{},
{-1, 1, 1, 1, 0},
{-1, 3, 1, 1, 0},
{-1, 4, 2, 2, 0},
{-1, 0, 3, 3, 1},
{-1, 0, 0, 0},
}
;
bool mode[N];
string state;
char ptmap[N][N], mapx[N][N], map2[N][N];
bool game_over = false, out_of_menu = false;
bool debug=0,vis[N][N];
struct pos{
int x,y;
bool operator == (const pos &a) const
{
return a.x==x && a.y==y;
}
bool operator != (const pos &a) const
{
return a.x!=x || a.y!=y;
}
}p, cam, vision, cam_dp, aim, last_pos, anchor, start, vision2, vision_init;
pos fa[N][N];
struct Path{
pos ps;
bool highlight;
};
struct Mob{
int x,y,dir;
int last_time_dizzy;
pos locate;
bool chasing;
};
char mob_cht = '!',mob_dizzy_cht = '~';
pos pre[N][N];
vector<Mob> mob;
vector<pos> wall, keys;
vector<Path> path;
void Color(int a);
void Setpos(int x,int y);
void RealSetpos(int x,int y);
void SlowDisplay(int x,string p);
void HideCursor();
void showCursor();
void win();
void lose();
int sprand(int l,int r);
int pow2(int x){ return x * x; }
double _pow2(double x){ return x * x; }
double calc_dist(pos a,pos b){ return sqrt( pow2(a.x-b.x) + pow2(a.y-b.y) ); }
void canvas(pos x,int color,string s){ Setpos(x.x,x.y); Color(color); cout<<s; }
double set_float(double x,int t){return int(x*pow(10,t))/pow(10,t);}
void fps_count();
void paint();
void button_check();
void player_check();
void player_move();
void game_update();
void print_menu();
void enter_menu();
void enter_custom_choose();
void enter_game(bool custom);
void enter_updates();
void enter_rule();
void enter_rule_item();
void enter_rule_mode();
void data_update();
void enter_setting();
void enter_difficulty_setting();
void enter_mode_setting();
void generate_item(int idx,int n);
void generate_mob(int n);
void generate_block(int n);
void generate_key(int n);
void generate_maze();
string str(int x);
pos find(pos x);
void ending_of_game();
bool join(pos a, pos b);
bool wall_check(int x);
bool dfs_get_way(pos cur);
bool bfs_get_way(pos s);
bool check_time(int x);
void mob_move();
void mob_detect(int i);
bool detecting_check(pos a,pos b);
void debug_out(string text);
bool mob_dizzy(int i);
bool press(char k,char x){bool res = k == x; if('a'<=x&&x<='z')res|= k == x - 'a' + 'A'; if('A'<=x&&x<='A')res|= k == x - 'A' + 'a';return res; }
inline void read(int &x);
inline void ffout(int x);
inline void ffout(int x,char b);
void enter_editor();
void save_map();
void load_map();
signed main()
{
//made by Polynswin
//部分windows代码 借鉴于胎神 luogu@TSzza
int i,j;
srand(time(0));
HideCursor();
enter_menu();
return 0;
}
bool bfs_get_way(pos s)
{
for(rint i=1; i<=maph; ++i)
for(rint j=1; j<=mapw; ++j)
vis[i][j] = false;
queue<pos> q;
q.push(s);
vis[s.x][s.y] = true;
pre[s.x][s.y] = {-1,-1} ;//注:不重置也可以正常run
while(!q.empty())
{
pos u = q.front();
q.pop();
for(rint i=1; i<=4; ++i)
{
int tx = u.x+dir_get_dpx[(i<<1)-1], ty = u.y+dir_get_dpy[(i<<1)-1];
if(tx<0 || ty<0 || tx>maph || ty>mapw || vis[tx][ty] || mapx[tx][ty]=='#')continue;
vis[tx][ty] = true;
pre[tx][ty] = u ;
if(mapx[tx][ty] == '*')
{
pos cur = {tx,ty};
while(pre[cur.x][cur.y] != pos({-1,-1}) )
{
cur = pre[cur.x][cur.y];
path.push_back(Path({cur.x,cur.y,false}));
}
for(rint i=0; i<=(path.size()-1>>1); ++i)
swap(path[i],path[path.size()-i-1]);
return true;
}
q.push(pos({tx,ty}));
}
}
return false;
}
void edst_clean(int seth,int setw)
{
for(rint i=1;i<=seth;++i)
{canvas( {i,0}, 8, " "); canvas( {i,setw+1}, 8, " "); }
for(rint i=0;i<=setw+1;++i)
{canvas( {seth+1,i}, 8, " "); canvas( {0,i}, 8, " "); }
for(rint i=1; i<=seth; ++i)
for(rint j=1; j<=setw; ++j)
canvas({i,j},0," ");
}
void enter_edst_cur2(int seth,int setw,bool *e_mode)
{
int ent = 10, column = 2, cur = 1, len = mode_name.size() ;
edst_clean(seth, setw);
while(1)
{
for(rint i=1; i<=len; ++i)
{
int tx = 1+(i-1)/column*2, ty = 2 + (i-1)%column*ent;
if(cur == i)canvas({tx, ty-1},0, " >");
else canvas({tx, ty-1},0, " ");
if(i==len)
{
canvas({tx,ty},0, "返回上一级");
break;
}
int col=0;
if(e_mode[i])col=2;
canvas( {tx,ty}, col, mode_name[i]);
}
char k = getch();
if(press(k, 'w'))cur = (cur-1 - column + len) % len + 1;
if(press(k, 's'))cur = (cur-1 + column)%len + 1;
if(press(k, 'a'))cur = (cur-2 + len) % len + 1;
if(press(k, 'd'))cur = cur % len + 1;
if(press(k, 'o'))
if(cur!=len)e_mode[cur] ^= 1;
else break;
if(press(k, 27))break;
}
edst_clean(seth, setw);
}
void enter_edcs_setting()
{
}
void enter_editor()
{
int curx = 1,cury = 1, chs = 1;
int ct_maph = 10, ct_mapw = 10, tool_len, item_chs = 1;
string state = "map";
pos ct_start = {0,0}, ct_vision = {10,10},ed_vision = {10,10};
int ct_item_init[N] = {-1, 0, 0, 0, 0};
char ct_map[N][N];
bool ct_mode[N];
mmt(ct_mode,false);
vector<char> tool_bar = {'1', ' ', '#', '*', 's', '@', (char)mob_cht, (char)item_cht[1]}; tool_len = tool_bar.size() - 1;
mmt(ct_map,' ');
cam_dp = {7,1};
system("cls");
update_map = true;
while(1)
{
if(!ct_mode[1]) item_chs = 1;
if(update_map)
{
canvas({-7,1},0, "map width: "+str(ct_mapw)+" ");
canvas({-6,1},0, "map height:"+str(ct_maph)+" ");
for(rint i=0;i<=ct_maph+1;++i)
{canvas( {i,-1}, 8, " "); canvas( {i,ct_mapw+2}, 8, " "); }
for(rint i=-1;i<=ct_mapw+2;++i)
{canvas( {ct_maph+2,i}, 8, "▁▁"); canvas( {-1,i}, 8, "▁▁"); }
for(rint i=0; i<=ct_mapw+1; ++i)
{canvas( {ct_maph+1,i}, 0, "■"); canvas( {0,i}, 0, "■"); }
for(rint i=1; i<=ct_maph; ++i)
{canvas( {i,0}, 0, "■"); canvas( {i,ct_mapw+1}, 0, "■"); }
for(rint i=1;i<=ct_maph;++i)
{
for(rint j=1;j<=ct_mapw;++j)
{
Setpos(i,j);
if(ct_map[i][j] == '#'){ Color(0); cout<<"■"; }
if(ct_map[i][j] == '*'){ Color(8); cout<<"* "; }
if(ct_map[i][j] == 's'){ Color(8); cout<<"s "; }
if(ct_map[i][j] == '@'){ Color(8); cout<<"^ "; }
if(ct_map[i][j] == ' '){ Color(0); cout<<" "; }
if(ct_map[i][j]==mob_cht){ Color(8); cout<<"●";}
for(rint k=1;k<=item_len;++k)
if(ct_map[i][j] == item_cht[k])
{ Color(item_color[k]); cout<<"☆"; }
}
}
for(rint i=1;i<=tool_len; ++i)
if( i==chs)canvas({-4,i<<1},0,"↓");
else canvas({-4,i<<1},0," ");
for(rint i=1;i<=tool_len; ++i)
{
Setpos(-3,i<<1);
if(tool_bar[i] == '#'){ Color(0); cout<<"■"; }
if(tool_bar[i] == '*'){ Color(8); cout<<"* "; }
if(tool_bar[i] == 's'){ Color(8); cout<<"s "; }
if(tool_bar[i] == ' '){ Color(3); cout<<"×"; }
if(tool_bar[i] == '@'){ Color(8); cout<<"^ "; }
if(tool_bar[i]==mob_cht){ Color(8); cout<<"●";}
if(i == 7 ){ Color( item_color[item_chs] ); cout<<"☆"; }
}
for(rint i=1;i<=tool_len; ++i)
canvas({-2,i<<1},0,numball[i]);
// if(clock()%1000 < 500)canvas({curx,cury},0, " ");
canvas({curx+1,cury},0, "↑");
}
update_map = false;
if(kbhit())
{
char k =getch();
if(state == "map")
{
if(press(k, 'w'))curx = (curx-2+ct_maph) % ct_maph + 1, update_map = true;
if(press(k, 's'))curx = curx%ct_maph + 1, update_map = true;
if(press(k, 'a'))cury = (cury-2+ct_mapw) % ct_mapw + 1, update_map = true;
if(press(k, 'd'))cury = cury%ct_mapw + 1, update_map = true;
if('1'<=k&&k<=tool_len + '0')
{
if(k == '7' && chs == 7)
{
if(ct_mode[1]) item_chs = item_chs%item_len + 1;
else item_chs = 1;
tool_bar[7] = item_cht[item_chs];
}
chs = k - '0'; update_map = true;
}
}
if(press(k, 27))
{
cam_dp = {7,ct_maph>>1};
int setw = 22,seth = 10, cur = 1,len;
vector<string> text = {" ", "修改游戏参数", "修改游戏模式", "加载地图", "保存地图", "退出编辑器"};
len = text.size() - 1;
int column = 2, ent = 14;
edst_clean(seth, setw);
while(1)
{
for(rint i=1; i<=len ; ++i)
{
int tx = 1+(i-1)/column*2, ty = 2 + (i-1)%column*ent;
if(cur == i)canvas({tx, ty-1},0, " >");
else canvas({tx, ty-1},0, " ");
canvas( {tx,ty}, 0, text[i]);
}
char k = getch();
if(press(k, 'w'))cur = (cur-1 - column + len) % len + 1;
if(press(k, 's'))cur = (cur-1 + column)%len + 1;
if(press(k, 'a'))cur = (cur-2 + len) % len + 1;
if(press(k, 'd'))cur = cur % len + 1;
if(press(k, 27))
{
update_map = true;
break;
}
if(press(k, 'o'))
{
if(cur == 1)
{
int cur2 = 1, column2 = 1, len2 = 4;
vector<string> text = {"", "迷宫宽度:", "迷宫长度:", "初始视野宽度:", "初始视野长度:"
, "初始引导之星数量:", "初始闪现数量:", "初始炸弹数量:", "初始探远星数量:"
};
vector<int*> value = {NULL, &ct_mapw, &ct_maph, &ct_vision.x, &ct_vision.y};
for(rint i=1; i<=item_len; ++i)
value.push_back(&ct_item_init[i]);
len2 = text.size() - 1;
edst_clean(seth, setw);
while(1)
{
for(rint i=1; i<=len2; ++i)
{
if(i == cur2)canvas({i,2},0 , " >");
else canvas({i,2},0 , " ");
canvas({i,3},0 , text[i]);
canvas({i,3+text[i].size()/2},0 , str(*value[i]) + " ");
}
char k = getch();
if(press(k, 27))
break;
if(press(k, 'w'))cur2 = (cur2-1 - column2 + len2) % len2 + 1;
if(press(k, 's'))cur2 = (cur2-1 + column2)%len2 + 1;
if(press(k, 'o'))
{
showCursor();
canvas({cur2,3+text[cur2].size()/2},0 , " ");
Setpos(cur2,3+text[cur2].size()/2);
cin>>*value[cur2];
HideCursor();
}
}
edst_clean(seth, setw);
}
if(cur == 2) enter_edst_cur2(seth,setw,ct_mode);
if(cur == len - 2)
{
edst_clean(seth, setw);
canvas({seth>>1,setw/2-7}, 0, "这会覆盖当前地图编辑,你确定要这么做吗");
canvas({seth/2+2,setw/2-4}, 0, "确认");
canvas({seth/2+2,setw/2+4}, 0, "取消");
bool confirm = 1;
while(1)
{
if(confirm)canvas({seth/2+2,setw/2-5}, 0, " >"), canvas({seth/2+2,setw/2+3}, 0, " ");
else canvas({seth/2+2,setw/2-5}, 0, " "), canvas({seth/2+2,setw/2+3}, 0, " >");
char k =getch();
if(press(k, 'a') || press(k, 'd')) confirm ^= 1;
if(press(k, 'o'))break;
}
if(!confirm)
{
edst_clean(seth, setw);
continue;
}
ifstream in("maze.pm");
in>>ct_mapw>>ct_maph>>ct_vision.x>>ct_vision.y;
for(rint i=1; i<=item_len; ++i)
in>>ct_item_init[i];
for(rint i=1; i<=mode_name.size() - 1; ++i)
in>>ct_mode[i];
for(rint i=1; i<=ct_maph; ++i)
for(rint j=1; j<=ct_mapw; ++j)
{
int x;
in>>x;
ct_map[i][j]=char(x);
if(ct_map[i][j] == 's') ct_start = pos({i,j});
}
in.close();
for(rint i=0; i<=ct_mapw+1; ++i)
ct_map[0][i] = ct_map[ct_maph+1][i] = '#';
for(rint i=1; i<=ct_maph; ++i)
ct_map[i][0] = ct_map[i][ct_mapw+1] = '#';
edst_clean(seth, setw);
canvas({seth>>1,setw/2-2}, 0, "地图已读取");
Sleep(2000);
break;
}
if(cur == len - 1)
{
ofstream out("maze.pm");
// out<<ct_mob.size()<<" ";
// for(rint i=0; i<mob.size(); ++i)
// out<<"{"<<mob[i].x<<","<<mob[i].y<<"} ";
out<<ct_mapw<<" "<<ct_maph<<" "<<ct_vision.x<<" "<<ct_vision.y<<endl;
for(rint i=1; i<=item_len; ++i)
out<<ct_item_init[i]<<" ";
out<<endl;
for(rint i=1; i<=mode_name.size() - 1; ++i)
out<<ct_mode[i]<<" ";
out<<endl;
for(rint i=1; i<=ct_maph; ++i)
{
for(rint j=1; j<=ct_mapw; ++j)
out<<int(ct_map[i][j])<<" ";
out<<endl;
}
out<<endl;
out.close();
edst_clean(seth, setw);
canvas({seth>>1,setw/2-2}, 0, "地图已保存");
Sleep(2000);
break;
}
if(cur == len)
enter_menu();
}
}
update_map = true;
system("cls");
cam_dp = {7,1};
}
// if(press(k, 'q'))
// {
// if(state == "map")
// update_map = true;
// }
}
if(GetAsyncKeyState('O')&0x8000)
{
if(tool_bar[chs] == 's')
{
ct_start = {curx,cury};
if(ct_map[ct_start.x][ct_start.y] == 's') ct_map[ct_start.x][ct_start.y] = ' ';
}
ct_map[curx][cury] = tool_bar[chs];
update_map = true;
}
}
}
void load_map()
{
ifstream in("maze.pm");
vector<int*> value = {NULL, &mapw, &maph, &vision_init.x, &vision_init.y};
for(rint i=1; i<=item_len; ++i)
value.push_back(&mode_item_init[0][i]);
int len = value.size() - 1;
for(rint i=1; i<=len; ++i) in>>*value[i];
for(rint i=1; i<=mode_name.size() - 1; ++i) in>>mode[i];
for(rint i=1; i<=item_len ; ++i) item[i] = mode_item_init[0][i];
// debug_out(str(mapw));
// debug_out(str(maph));
// debug_out(str(maph));
for(rint i=0; i<=mapw+1; ++i)
mapx[0][i] = mapx[maph+1][i] = '#';
for(rint i=1; i<=maph; ++i)
mapx[i][0] = mapx[i][mapw+1] = '#';
for(rint i=1; i<=maph; ++i)
for(rint j=1; j<=mapw; ++j)
{
int x;
in>>x;
// debug_out(str(i)+" "+str(j)+" "+str(x));
// system("pause");
// debug_out(str(i)); debug_out(str(j));
if(x == '!') mob.push_back(Mob( {i,j,1, 0, {0,0}, false} ));
if(x == '#' || x == '*') mapx[i][j] = x;
if(x == 's')
{
p = pos({i,j});
continue;//纪念第一个调了我1个小时的bug,continue 打成 break 了
}
bool flag = false;
for(rint k=1; k<=item_len; ++k)
if(x == item_cht[k])
{
flag = true;
break;
}
if(flag || x == '@')
{
map2[i][j] = x;
if(x == '@')
{
key++;
keys.push_back(pos({i,j}));
}
}
}
// system("pause");
}
void save_map()
{
ofstream out("maze.pm");
out<<mob.size()<<" ";
for(rint i=0; i<mob.size(); ++i)
out<<"{"<<mob[i].x<<","<<mob[i].y<<"} ";
out.close();
for(rint i=1; i<=maph; ++i)
{
for(rint j=1; j<=mapw; ++j)
out<<int(mapx[i][j])<<" ";
out<<endl;
}
out<<endl;
for(rint i=1; i<=maph; ++i)
{
for(rint j=1; j<=mapw; ++j)
out<<int(map2[i][j])<<" ";
out<<endl;
}
out<<endl;
}
void debug_out(string text)
{
// return;
Setpos(++debug_cnt,-20);
cout<<text<<" ";
debug_cnt%=20;
}
bool mob_dizzy(int i)
{
return clock()-mob[i].last_time_dizzy <= mob_dizzy_time;
}
void mob_move()
{
update_map = true;
for(rint i=0;i<mob.size();++i)
{
if(mob_dizzy(i))continue;
mob_detect(i);
if(!mob[i].chasing)
{
// continue;
int tx= mob[i].x + dir_get_dpx[mob[i].dir * 2 -1],
ty= mob[i].y + dir_get_dpy[mob[i].dir * 2 -1];
int t=(mob[i].dir+1)%4+1;
vector<int> go_dir = {0,1,2,3,4};
go_dir.erase(go_dir.begin()+ (mob[i].dir+1)%4+1 );
mob[i].dir = go_dir[sprand(1, go_dir.size()-1)];
while(mapx[tx][ty]=='#' && go_dir.size()>1)
{
int ri=sprand(1, go_dir.size()-1);
mob[i].dir = go_dir[ri];
tx= mob[i].x + dir_get_dpx[mob[i].dir * 2 -1],
ty= mob[i].y + dir_get_dpy[mob[i].dir * 2 -1];
go_dir.erase(go_dir.begin()+ ri );
}
if(mapx[tx][ty]=='#')
{
mob[i].dir = t;
tx= mob[i].x + dir_get_dpx[mob[i].dir * 2 -1],
ty= mob[i].y + dir_get_dpy[mob[i].dir * 2 -1];
if(mapx[tx][ty]=='#')continue;
}
mob[i].x= tx; mob[i].y= ty;
}
else
{
if(mob[i].locate.x == mob[i].x)
{
mob[i].y += mob[i].y>p.y ? -1:1 ;
continue;
}
double k = (mob[i].locate.y-mob[i].y)*1.0 / (mob[i].locate.x-mob[i].x) ;
double c = -k * mob[i].x + mob[i].y;
int ty=mob[i].y + ( (mob[i].y>mob[i].locate.y) ? -1:1 ),
tx=mob[i].x + ( (mob[i].x>mob[i].locate.x) ? -1:1 );
// debug_out("out");
if(_pow2(-k*mob[i].x + ty - c) <= b_r*b_r * ( k*k + 1) && mapx[mob[i].x][ty]!='#')mob[i].y = ty;
else if(mapx[tx][mob[i].y]!='#')mob[i].x = tx ;
}
}
// debug_out("move_over");
}
bool detecting_check(pos a,pos b,int idx)
{
if(a.x==b.x)
{
int l=min(a.y,b.y),r=max(a.y,b.y);
for(rint i=l; i<=r; ++i)
if(mapx[a.x][i]=='#')return false;
return true;
}
//y = kx + c
//-kx + y - c = 0
double k = (b.y-a.y)*1.0 / (b.x-a.x) ;
double c = -k * a.x + a.y;
int l=min(a.x,b.x), r=max(a.x,b.x);
// debug_out("step1");
for(int i=l; i<=r; ++i)
{
// debug_out("loop");
for(int j=k*i + c; j>=min(a.y,b.y) && j<=max(a.y,b.y) ;--j)
if(_pow2(-k*i + j - c) <= b_r*b_r * ( k*k + 1))
{
// canvas({i-cam.x+1,j-cam.y+1}, 0, "@ ");
if(mapx[i][j]=='#')return false;
}
else break;
for(int j=ceil( k*i + c); j>=min(a.y,b.y) && j<=max(a.y,b.y) ;++j)
if(_pow2(-k*i + j - c) <= b_r*b_r * ( k*k + 1))
{
// canvas({i-cam.x+1,j-cam.y+1}, 0, "@ ");
if(mapx[i][j]=='#')return false;
}
else break;
}
return true;
}
void mob_detect(int i)
{
// debug_out("detecting");
if(abs(mob[i].x-p.x)+abs(mob[i].y-p.y)>=20)return;
if( detecting_check({mob[i].x,mob[i].y}, p, i) )
{
mob[i].chasing = true;
// debug_out("detected");
mob[i].locate = p;
}
else
{
if(mob[i].locate.x==mob[i].x && mob[i].locate.y==mob[i].y )mob[i].chasing = false;
// vector<int> pb_dir;//possible direction
// for(rint j=1;j<=4;++j)
}
// debug_out("over");
}
bool check_time(int x)
{
return clock()-last_time[x] >= interval[x];
}
bool dfs_get_way(pos cur)
{
debug_out(str(cur.x)); debug_out(str(cur.y));
if(mapx[cur.x][cur.y] == '*')return true;
if(vis[cur.x][cur.y])return false;
vis[cur.x][cur.y]=true;
if(cur.x!=start.x||cur.y!=start.y)path.push_back( Path( {cur, false} ));
for(int i=1;i<=4;i++)
{
int tx=cur.x+dir_get_dpx[i*2-1],ty=cur.y+dir_get_dpy[i*2-1];
if(mapx[tx][ty]=='#' || tx<0 || ty<0 || tx>maph || ty>mapw)continue;
if(dfs_get_way( {tx,ty} ))return true;
}
path.pop_back();
vis[cur.x][cur.y]=false;
return false;
}
struct node{
int idx;
double dis;
};
vector<node> t;
bool cmp(node a, node b){
return a.dis<b.dis;
}
pos find(pos x)
{
return (fa[x.x][x.y].x == x.x && fa[x.x][x.y].y == x.y) ? x : fa[x.x][x.y] = find(fa[x.x][x.y]);
}
bool join(pos a, pos b)
{
pos af = find(a), bf = find(b);
if(af.x != bf.x || af.y != bf.y)
{
fa[bf.x][bf.y]=af;
return true;
}
return false;
}
bool wall_check(int x)
{
if(wall.empty())return false;
int ax,ay,bx,by;
if(wall[x].x&1)ax = wall[x].x, ay = wall[x].y-1, bx = wall[x].x, by = wall[x].y+1;
else ax = wall[x].x-1, ay = wall[x].y, bx = wall[x].x+1, by = wall[x].y;
if( join( {ax,ay}, {bx,by} ) )
{
// test(wall[x].x);
// test(wall[x].y);
mapx[wall[x].x][wall[x].y] = ' ';
wall.erase(wall.begin()+x);
return true;
}
wall.erase(wall.begin()+x);
return false;
}
void generate_maze()
{
mmt(mapx,' ');
int tot = 0;
wall.clear();
for(rint i=1;i<=maph;++i)
for(rint j=1;j<=mapw;++j)
{
fa[i][j] = { i, j };
if( i&1 && j&1 )mapx[i][j]=' ',tot++;
else mapx[i][j]='#';
if( (i&1) ^ (j&1) )wall.push_back(pos( {i,j} ) );
}
for(rint i=0;i<=maph+1;++i)
mapx[i][0]=mapx[i][mapw+1]='#';
for(rint i=1;i<=mapw;++i)
mapx[0][i]=mapx[maph+1][i]='#';
for(rint i=1; i<=tot && !wall.empty(); ++i)
while(wall_check( sprand( 0, wall.size()-1 ) ) && !wall.empty());
mapx[maph][mapw] = '*';
wall.clear();
if(mode[5])
{
for(rint i=1; i<=maph; ++i)
for(rint j=1; j<=mapw; ++j)
if(mapx[i][j]=='#')wall.push_back(pos({i,j}));
for(rint i=1; i<=mode_init[choose][6]; ++i)
{
int rx=sprand(1,maph),
ry=sprand(1,mapw);
while(mapx[rx][ry]!='#')rx=sprand(1,maph),ry=sprand(1,mapw);
mapx[rx][ry]=' ';
}
}
}
void generate_item(int idx,int n)
{
for(int i=1;i<=n;++i)
{
int rx=sprand(1,maph),
ry=sprand(1,mapw);
while(mapx[rx][ry]!=' ' || map2[rx][ry]!=' ')rx=sprand(1,maph),ry=sprand(1,mapw);
map2[rx][ry]=item_cht[idx];
}
}
void generate_mob(int n)
{
for(int i=1;i<=n;++i)
{
int rx=sprand(1,maph),
ry=sprand(1,mapw);
while(mapx[rx][ry]!=' ' || map2[rx][ry]!=' ')rx=sprand(1,maph),ry=sprand(1,mapw);
mob.push_back(Mob( { rx, ry, 1, 0, {0,0}, false} ));
}
}
void generate_key(int n)
{
key = n;
for(int i=1;i<=n;++i)
{
int rx=sprand(1,maph),
ry=sprand(1,mapw);
while(mapx[rx][ry]!=' ' || map2[rx][ry]!=' ')rx=sprand(1,maph),ry=sprand(1,mapw);
map2[rx][ry]='@';
keys.push_back( pos({rx,ry}) );
}
}
void generate_block(int n)
{
int ln=sprand(1,n>>1);
for(rint i=1;i<=ln;++i)
{
int ri=sprand(0,path.size()-1);
int rx = path[ri].ps.x,ry = path[ri].ps.y;
int tot = 0;
while(mapx[rx][ry]!=' ' || map2[rx][ry]!=' ')
{
rx=sprand(1,maph),ry=sprand(1,mapw);
if(tot>=1000)break;
}
if(tot>=1000)break;
mapx[rx][ry]= '#';
}
for(rint i=1;i<=n-ln;++i)
{
int rx=sprand(1,maph),
ry=sprand(1,mapw);
while(mapx[rx][ry]!=' ' || map2[rx][ry]!=' ')rx=sprand(1,maph),ry=sprand(1,mapw);
mapx[rx][ry]= '#';
}
}
void game_update()
{
paint();
if(clean_screen)
{
clean_screen = false;
system("cls");
}
for(rint i=1;i<=vision.x;++i)
{canvas( {i,0}, 8, " "); canvas( {i,vision.y+1}, 8, " "); }
for(rint i=0;i<=vision.y+1;++i)
{canvas( {vision.x+1,i}, 8, "▁▁"); canvas( {0,i}, 8, "▁▁"); }
for(rint i=1; i<=vision.x; ++i)
for(rint j=1; j<=vision.y; ++j)
{
int tx=i+cam.x-1,ty=j+cam.y-1;
Setpos(i,j);
if(tx<0 || ty<0 || tx>maph+1 || ty>mapw+1 )
{
Color(0);
cout<<" ";
continue;
}
// Color(0); cout<<"--";
if(ptmap[tx][ty]==' '){ Color(0); cout<<" ";}
if(ptmap[tx][ty]==0){ Color(7); cout<<"●";}
if(ptmap[tx][ty]==1){ Color(3); cout<<"●";}
if(ptmap[tx][ty]==2){ Color(4); cout<<"●";}
if(ptmap[tx][ty]==3){ Color(8); cout<<"☆";}
if(ptmap[tx][ty]=='#'){ Color(0); cout<<"■";}
if(ptmap[tx][ty]=='*'){ if(mode[3]&&key)Color(5);else Color(8); cout<<"* ";}
if(ptmap[tx][ty]=='@'){ Color(8); cout<<"^ ";}
if(ptmap[tx][ty]==mob_cht){ Color(8); cout<<"●";}
if(ptmap[tx][ty]==mob_dizzy_cht){ Color(7); cout<<"●";}
if(ptmap[tx][ty]==item_cht[1]){ Color(1); cout<<"☆";}
if(ptmap[tx][ty]==item_cht[2]){ Color(2); cout<<"☆";}
if(ptmap[tx][ty]==item_cht[3]){ Color(5); cout<<"☆";}
if(ptmap[tx][ty]==item_cht[4]){ Color(6); cout<<"☆";}
}
canvas({-2,0},0,"time = " + str( (clock()*1.0-startTime)/1000 ) + " score = "+str(score) + " fps =" + str(fps));
canvas({-1,0},0,"x,y = " + str(p.x) + " " + str(p.y) + " ");
int top=0,cur=0;
while(top<item_len)
{
top++;
if(mode[2] && top==1 && !mode[3])continue;
if(!mode[1] && top>1)continue;
canvas({vision.x+2+cur/2,1+cur%2*6}, 0, item_name[ top ] +" = "+ str(item[top]) + " ");
cur++;
}
if(mode[3])canvas({vision.x+2+cur/2,1+cur%2*6}, 0, "key = "+ str(key) ),cur++;
if(!check_time(2))
{
// if(last_pos.x != -1 && (last_pos.x!=cx || last_pos.y!=cy) )canvas({last_pos.x,last_pos.y},0, " ");
string out;
if(anchor.x==p.x)
if(anchor.y < p.y)shown_dir = 1;
else shown_dir = 5;
if(anchor.y==p.y)
if(anchor.x < p.x)shown_dir = 3;
else shown_dir = 7;
if(anchor.x<p.x && anchor.y>p.y) shown_dir = 2 ;
if(anchor.x<p.x && anchor.y<p.y) shown_dir = 4 ;
if(anchor.x>p.x && anchor.y<p.y) shown_dir = 6 ;
if(anchor.x>p.x && anchor.y>p.y) shown_dir = 8 ;
int cx = p.x - cam.x + 1 + dir_get_dpx[shown_dir], cy = p.y - cam.y + 1 + dir_get_dpy[shown_dir];
if(shown_dir == 1)out = "→";
if(shown_dir == 5)out = "←";
if(shown_dir == 3)out = "↑";
if(shown_dir == 7)out = "↓";
if(shown_dir == 2)out = "↗";
if(shown_dir == 4)out = "↖";
if(shown_dir == 6)out = "↙";
if(shown_dir == 8)out = "↘";
if((clock()-last_time[2]) % 1000 < 500) canvas({cx,cy},0, out) ;
}
else if(shown_dir)shown_dir = 0;
}
void player_move()
{
update_map = true;
if(GetAsyncKeyState('W')&0x8000)
{
if(mapx[p.x-1][p.y]!='#' || debug)p.x--;
dir=2;
}
if(GetAsyncKeyState('S')&0x8000 )
{
if(mapx[p.x+1][p.y]!='#' || debug)p.x++;
dir=4;
}
if(GetAsyncKeyState('A')&0x8000 )
{
if(mapx[p.x][p.y-1]!='#' || debug)p.y--;
dir=3;
}
if(GetAsyncKeyState('D')&0x8000 )
{
if(mapx[p.x][p.y+1]!='#' || debug)p.y++;
dir=1;
}
if(maph-vision.x>0)cam.x=min( max(p.x-(vision.x-1 >> 1), 0) , maph-vision.x+2);
else cam.x= maph-vision.x+2>>1;
if(mapw-vision.y>0)cam.y=min( max(p.y-(vision.y-1 >> 1), 0) , mapw-vision.y+2);
else cam.y= mapw-vision.y+2>>1;
if(mode[1])
for(rint i=3; i>=0 ; --i)
{
int tx= p.x+dir_get_dpx[dir*2-1]*i, ty= p.y+dir_get_dpy[dir*2-1]*i;
if(tx<0 || tx>maph || ty<0 || ty>mapw || mapx[tx][ty]=='#')continue;
aim = {tx,ty};
break;
}
}
void player_check()
{
if(mapx[p.x][p.y] == '*' && (!key || !mode[3])) win();
for(rint i=1; i<=item_len ; ++i)
if(map2[p.x][p.y]==item_cht[i])
{
item[i]++;
map2[p.x][p.y] = ' ';
score += item_score[4];
update_map = true;
}
for(rint i=0; i<mob.size() ; ++i)
if(p == pos( {mob[i].x,mob[i].y} ) && !mob_dizzy(i) ) lose();
if(map2[p.x][p.y]=='@' && mode[3])
{
update_map = true;
key --;
for(rint i=0; i<keys.size(); ++i)
if(keys[i].x == p.x && keys[i].y == p.y)
keys.erase(keys.begin() + i);
map2[p.x][p.y] = ' ';
}
}
void paint()
{
for(rint i=1;i<=vision.x;++i)
for(rint j=1;j<=vision.y;++j)
{
int tx=i+cam.x-1,ty=j+cam.y-1;
if(tx<0 || ty<0 || tx>maph+1 || ty>mapw+1 )
continue;
ptmap[tx][ty]=mapx[tx][ty];
}
for(rint i=1;i<=vision.x;++i)
for(rint j=1;j<=vision.y;++j)
{
int tx=i+cam.x-1,ty=j+cam.y-1;
if(tx<0 || ty<0 || tx>maph+1 || ty>mapw+1 )
continue;
if(map2[tx][ty]!=' ')ptmap[tx][ty]=map2[tx][ty];
}
if(mode[1])ptmap[aim.x][aim.y]=2;
for(rint i=0;i<mob.size();++i)
if(!mob_dizzy(i))ptmap[mob[i].x][mob[i].y]=mob_cht;
else ptmap[mob[i].x][mob[i].y]=mob_dizzy_cht;
ptmap[p.x][p.y]=1;
}
void button_check()
{
if(kbhit())
{
char k=getch();
if( press( k, 'r') )
{
update_map = true;
Rclick ++;
if(Rclick == 1)
{
last_time[1] = clock();
canvas({-3,0}, 0, "Press R again to confirm suicide");
}
if(Rclick == 2)lose();
}
if(check_time(1))update_map = true, Rclick = 0,canvas({-2,0}, 0, " ");
if(press( k, 'u') && item[1]>0 )
{
if(mode[3] && key )
{
double minx = inf;
for(rint i = 0; i<keys.size(); ++i)
if(minx > calc_dist(keys[i], p) )
{
minx = calc_dist(keys[i], p);
anchor = keys[i];
}
// debug_out(str(chs.x) + " " + str(chs.y) + " " + str(shown_dir));
last_time[2] = clock();
}
if(!mode[2] && path.size())
{
t.clear();
for(rint i=0;i<path.size();++i)
if(!path[i].highlight)t.push_back( node( { i, calc_dist(p,path[i].ps) } ) );
sort(t.begin(),t.end(),cmp);
int l=t.size();
for(rint i=0; i< min(5, l-1 ) ; ++i)
{
path[t[i].idx].highlight=true;
mapx[ path[t[i].idx].ps . x ][ path[t[i].idx].ps . y ] = 3;
}
}
if(!mode[2] || (mode[3] && key)) item[1] --, score += item_score[1],update_map = true;
}
if(press( k, 'i') && item[2]>0 && mode[1])
{
update_map = true;
p = aim;
item[2] --; score += item_score[2];
}
if(press(k, 'o') && item[3]>0 && mode[1])
{
update_map = true;
for(rint i=0; i<=8 ; ++i)
{
int tx= aim.x+dir_get_dpx[i],ty= aim.y+dir_get_dpy[i];
if(tx==p.x && ty==p.y && mode[4])lose();
if(mode[4])
for(rint j=0; j<mob.size(); ++j)
if( pos({mob[j].x,mob[j].y}) == pos({tx,ty}) )
mob[j].last_time_dizzy=clock();
if(mapx[tx][ty] == '#' && (tx>0 && tx<=maph && ty<=mapw && ty>0) )
mapx[ tx ][ ty ] = ' ';
}
item[3] --; score += item_score[3];
}
}
}
void data_update()
{
run++; cnt++;
int calc= -pow2(item[4])/4 + 4*item[4] ;
vision2 = {max(vision2.x,calc), max(vision2.y,calc)};
vision = {vision2.x+vision_init.x,vision2.y+vision_init.y};
fps_count();
}
void fps_count()
{
if(clock()-lasts>=1000)
{
fps=run/ ( (clock()-lasts)*1.0/1000);
run=0;
lasts=clock();
}
}
void enter_game(bool custom)
{
game_over = false; key = 0;
path.clear(); wall.clear(); mob.clear(); keys.clear();
system("cls");
startTime=clock();
mmt(mapx,' '); mmt(map2,' '); mmt(item,0); mmt(vis,false);
if(!custom)
{
p= { 1, 1 }; vision_init={ 15, 15 }; vision2 = {-999,-999};
data_update();
int ttx = vision.x>>1, tty= (vision.y>>1) ;
canvas({ttx,tty},0, "世界生成中...");
for(rint i=1; i<=item_len ; ++i) item[i] = mode_item_init[choose][i];
maph = mode_init[choose][2]; mapw = mode_init[choose][1];
maph = maph >> 1 << 1 | 1; mapw = mapw >> 1 << 1 | 1;
generate_maze();
canvas({ttx,tty+8},0, "33%");
for(rint i=1; i<=item_len ; ++i)
{
if(i==1 && !mode[2])generate_item(i,mode_item[choose][i]);
if(i!=1 && mode[1])generate_item(i,mode_item[choose][i]);
}
canvas({ttx,tty+8},0, "45%");
bfs_get_way(p);
if(mode[2]) generate_block(mode_init[choose][3]);
canvas({ttx,tty+8},0, "60%");
if(mode[3]) generate_key(mode_init[choose][4]);
canvas({ttx,tty+8},0, "85%");
if(mode[5]) generate_mob(mode_init[choose][5]);
system("cls");
canvas({ttx,tty},0, "done!");
}
else
{
load_map();
vision2 = {-999,-999};
bfs_get_way(p);
//debug_out("1");
// dfs_get_way(p);
}
data_update();
for(rint i=0; i<mob.size(); ++i)
mob[i].last_time_dizzy = clock();
cnt = 0; run = 0; score = 0; mob_speed = 12; shown_dir = 0; cam_dp={ 4, 20 };
player_speed = 8;
// save_map();
//debug_out("1");
//debug_out("Polynswin")
while(!game_over)
{
update_map = false;
// char k =getch();
// if(k == 'a') enable ^= 1;
if(clock()-lasts2<1000/ ( 60 + 0 ))continue;
lasts2=clock();
data_update();
button_check();
//debug_out("2");
if(game_over)break;
if( cnt%player_speed==0) player_move();
if( cnt%mob_speed == 0) mob_move();
player_check();
if(update_map) game_update();
}
enter_menu();
}
void print_menu()
{
canvas( {1,1}, 0, "欢迎来到 多重迷宫 V1.5 ");
canvas( {2,1}, 0, " made by Polynswin ");
canvas( {5,2}, 0, "按 Z 进入游戏 ");
canvas( {7,2}, 0, "按 C 修改迷宫模式");
canvas( {9,2}, 0, "按 Q 查看规则");
}
void enter_custom_choose()
{
system("cls");
cam_dp = {3,20};
ifstream in("level_list.info");
vector<string> name = {""};
string x;
while(in>>x)name.push_back(x);
int len = name.size() - 1,cur = 1;
while(1)
{
int curx = 0;
for(rint i=1; i<=len; ++i)
canvas({curx = curx + 2, 1}, 0, name[i]);
for(rint i=1;i<=len;++i)
if(cur == i)canvas({i*2,-1},0," ");
else canvas({i*2,-1},0,">");
// if(1<=cur && cur<=6)
char k =getch();
if(press( k, 'w'))cur = (cur-1+len-1)%len+1;
if(press( k, 's'))cur = cur%len+1;
if(press( k, 'o'))
{
if(cur==1) enter_game(false);
if(cur==2) enter_custom_choose();
if(cur==3) enter_editor();
if(cur==4) enter_setting();
if(cur==5) enter_rule();
if(cur==6) enter_updates();
}
}
}
void enter_menu()
{
system("cls");
cam_dp = {3,20};
int len = 6,cur = 1;
while(1)
{
int curx=3;
cam_dp = {3,20};
canvas({curx,0},0,"多重迷宫 V1.8!!!"); curx += 1;
canvas({curx,0},0,"made by Polynswin"); curx += 2;
canvas({curx,0},0,"开始游戏"); curx += 2;
canvas({curx,0},0,"自定义关卡"); curx += 2;
canvas({curx,0},0,"关卡编辑器"); curx += 2;
canvas({curx,0},0,"修改迷宫模式"); curx += 2;
canvas({curx,0},0,"查看游戏介绍"); curx += 2;
canvas({curx,0},0,"更新日志 "); curx += 3;
canvas({curx,0},0,"按 W / S 键上下移动"); curx += 1;
canvas({curx,0},0,"按 O 键确认"); curx += 1;
for(rint i=1;i<=len;++i)
canvas({i*2+4,-1},0," ");
// if(1<=cur && cur<=6)
canvas({cur*2+4,-1},0,">");
char k =getch();
if(press( k, 'w'))cur = (cur-1+len-1)%len+1;
if(press( k, 's'))cur = cur%len+1;
if(press( k, 'o'))
{
if(cur==1) enter_game(false);
if(cur==2) enter_custom_choose();
if(cur==3) enter_editor();
if(cur==4) enter_setting();
if(cur==5) enter_rule();
if(cur==6) enter_updates();
}
}
}
void enter_setting()
{
int cur = 1, len = 4;
while(1)
{
cam_dp = {3,20};
system("cls");
if(1<=cur && cur<=3)
canvas({cur*2-1,0},0,">");
string text[10]={"",
"难度选择", "模式选择", "颜色设置(尚未开放)", "UI设置(尚未开放)",
"按 W / S 键改位置", "按 O 键确认", "按 Q 键退出并保存设置"
};
for(rint i=1;i<=len+3;i++)
{
int col=0;
canvas({i*2-1,1},col,text[i]);
}
char k =getch();
if(press( k, 'w'))cur = (cur-1+len-1)%len+1;
if(press( k, 's'))cur = cur%len+1;
if(press( k, 'o'))
{
if(cur == 1) enter_difficulty_setting();
if(cur == 2)enter_mode_setting();
if(cur == 3);
}
if(press( k, 'q'))enter_menu();
}
}
void enter_mode_setting()
{
system("cls");
cam_dp = {3,20};
int cur = 1, len = mode_name.size() - 1;
while(1)
{
system("cls");
if(1<=cur && cur<=len)
canvas({cur*2-1,0},0,">");
for(rint i=1;i<=len;i++)
{
int col=0;
if(mode[i])col=2;
canvas({i*2-1,1},col,mode_name[i]);
}
canvas({ (len+1<<1) - 1, 1}, 0, "按 W / S 键改位置");
canvas({ len+1 << 1, 1}, 0, "按 O 键确认");
canvas({ len+1 << 1 | 1, 1}, 0, "按 Q 键退出并保存设置");
char k =getch();
if(press(k, 'w'))cur = (cur-1+len-1)%len+1;
if(press(k, 's'))cur = cur%len+1;
if(press(k, 'o'))
{
mode[cur] ^= 1;
if(mode[2])mode[1]=1;
}
if(press(k, 'q'))enter_setting();
}
}
string str(int x)
{
if(!x) return "0";
string res="",res2=".";
// int tot = -99;
// if(int(x) != x)
// {
// double cx = x;
// while(cx && tot<2)
// {
// cx = cx - int(cx);
// cx = cx * 10;
// res2 += int(cx) + '0';
// tot++;
// }
//// Setpos(0,-10);test(res2);
// }
int tx=x;
while(tx)
{
res+=tx%10+'0';
tx=tx/10;
}
for(int i=0;i< (res.size()>>1) ;i++)
{
char t=res[i];
res[i]=res[res.size()-i-1];
res[res.size()-i-1]=t;
}
if(res2==".")return res;
else return res+res2;
}
void enter_updates()
{
int curx=0,len=2;
cam_dp = {3,10};
system("cls");
// canvas({curx,0},0," "); curx += ;
canvas({curx,0},0,"V1.5更新"); curx += 2;
canvas({curx,0},0,"更新 钥匙收集 模式"); curx += 2;
canvas({curx,0},0,"V1.6更新"); curx += 2;
canvas({curx,0},0,"修复了一堆显示bug"); curx += 1;
canvas({curx,0},0,"优化了游戏算法,反正作者的机房电脑是能在地狱难度\\模式拉满\\视野拉满下也能跑满62fps"); curx += 1;
canvas({curx,0},0,"引导之星增添新功能,在钥匙收集模式中,还能显示钥匙大致方位"); curx += 1;
canvas({curx,0},0,"新增 怪物追击 模式"); curx += 1;
canvas({curx,0},0,"更新 UI"); curx += 2;;
canvas({curx,0},0,"V1.7&1.8更新"); curx += 2;
canvas({curx,0},0,"新增 自定义关卡&关卡编辑器 模式"); curx += 1;
canvas({curx,0},0,"按 Q 键退出");
while(1)
{
char k =getch();
if(press(k, 'q')) break;
}
system("cls");
}
void enter_rule_editor()
{
system("cls");
while(1)
{
int curx = 0;
cam_dp = {3,20};
canvas({curx,0},0,"编辑器上方有工具栏,按下相应数字键切换选中物品,按O键即可在预瞄点处摆放"); curx += 2;
canvas({curx,0},0,"箭头上方为你的预瞄点,按WASD键进行上下左右移动"); curx += 2;
canvas({curx,0},0,"如果要对地图进行设置,按下ESC进入菜单界面"); curx += 2;
canvas({curx,0},0,"大部分界面都可以用ESC退出,同时大部分选项都可以按下O键(注意)确认"); curx += 2;
canvas({curx,0},0,"编辑好地图后,别忘了在菜单界面保存地图,会导出至与游戏本体同级地址为maze.pm"); curx += 1;
canvas({curx,0},0,"如果想加载地图,可在菜单界面选择加载地图确认,会读入文件maze.pm"); curx += 3;
canvas({curx,0},0,"按 Q 键退出");
char k =getch();
if(press( k, 'q'))return;
}
}
void enter_rule()
{
int curx=0,cur=1,len=3;
while(1)
{
curx=0;
cam_dp = {3,20};
system("cls");
canvas({curx,0},0,"游戏目标为移动至迷宫位于右下角的终点(符号*)"); curx += 2;
canvas({curx,0},0,"按方向键进行上下左右移动"); curx += 2;
canvas({curx,0},0,"你拥有道具,需要按下相应的键位使用,使用即可得分"); curx += 2;
canvas({curx,0},0,"当你遇到死局时,可双击 R 键紫砂"); curx += 3;
canvas({curx,0},0,"查看 道具介绍"); curx += 1;
canvas({curx,0},0,"查看 模式介绍"); curx += 1;
canvas({curx,0},0,"查看 编辑器介绍"); curx += 2;
canvas({curx,0},0,"按 W / S 键上下移动"); curx += 1;
canvas({curx,0},0,"按 O 键确认"); curx += 1;
canvas({curx,0},0,"按 Q 键退出");
for(rint i=1;i<=len;++i)
canvas({i+8,-1},0," ");
canvas({cur+8,-1},0,">");
char k =getch();
if(press( k, 'w'))cur = (cur-1+len-1)%len+1;
if(press( k, 's'))cur = cur%len+1;
if(press( k, 'q'))enter_menu();
if(press( k, 'o'))
{
if(cur==1)enter_rule_item();
if(cur==2)enter_rule_mode();
if(cur==3)enter_rule_editor();
}
}
}
void enter_rule_mode()
{
system("cls");
cam_dp = {3,15};
int curx=0;
canvas({curx,0},0,"特殊道具: 场上会多出特殊道具"); curx += 2;
canvas({curx,0},0,"特殊道具2: 同上"); curx += 2;
canvas({curx,0},0,"迷宫塌方:迷宫坍塌,场上会随机出现方块"); curx += 1;
canvas({curx,0},0," (强制打开特殊道具)"); curx += 2;
canvas({curx,0},0,"收集钥匙:要收集一定钥匙后才能通往终点"); curx += 2;
canvas({curx,0},0,"爆炸伤害:炸弹会炸死范围内单位,包括你自己"); curx += 1;
canvas({curx,0},0," (强制打开特殊道具)"); curx += 2;
canvas({curx,0},0,"怪物追击:场上会存在一定的怪物,它们会随机游走,但当看到你时,它们会向你追击"); curx += 1;
canvas({curx,0},0," 但是你可以甩开它们,同时要利用地形卡好视野,同时地图上会出现安全点"); curx += 1;
canvas({curx,0},0," 相应的,地图的路径将不再单一,你拥有多种路径通往终点"); curx += 2;
canvas({curx,0},0,"灯光不足:玩家出生时会携带灯源,随着时间流逝灯光会减弱,视野也会相应变小,"); curx += 1;
canvas({curx,0},0," 需要去地图上搜寻燃料补充灯光,视野也会相应变小,需要去地图上搜寻"); curx += 1;
canvas({curx,0},0," 燃料补充灯光"); curx += 2;
canvas({curx,0},0,"双人对战:开启双人模式,玩家出生在地图对角线,需不断搜寻道具击败对方"); curx += 1;
canvas({curx,0},0," (强制打开特殊道具 & 2)"); curx += 2;
canvas({curx,0},0,"按 Q 键退出");
while(1)
{
char k =getch();
if(press( k, 'q'))break;
}
}
void enter_rule_item()
{
system("cls");
cam_dp = {3,15};
int curx=0;
canvas({curx,0},0,"道具1: 引导之星(guide) U 键"); curx += 1;
canvas({curx,0},0," 使用后可以显示通往终点的道路,但只能显示距离你最近的5格"); curx += 1;
canvas({curx,0},0," (迷宫塌方中不可用)"); curx += 2;
canvas({curx,0},0,"接下来的为特殊道具,只有打开特殊模式才能使用"); curx += 2;
canvas({curx,0},0,"道具2:闪现(flash) I 键"); curx += 1;
canvas({curx,0},0," 使用后可以闪现至预瞄点"); curx += 2;
canvas({curx,0},0,"道具3:炸弹(bomb) O 键"); curx += 1;
canvas({curx,0},0," 使用后可以炸掉预瞄点3*3范围内的墙壁(不可炸掉边界,别想着偷鸡)"); curx += 2;
canvas({curx,0},0,"道具4:探远星(vision) \\"); curx += 1;
canvas({curx,0},0," 收集之后可以增加视野,但存在上限,非线性增长"); curx += 2;
canvas({curx,0},0,"按 Q 键退出");
while(1)
{
char k =getch();
if(press( k, 'q'))break;
}
}
void enter_difficulty_setting()
{
system("cls");
cam_dp = {3,20};
int cur = 1, len = 5;
while(1)
{
system("cls");
if(1<=cur && cur<=5)
canvas({cur*2-1,0},0,">");
vector<string> text={"",
"迷宫:简单难度", "迷宫:正常难度", "迷宫:困难难度",
"迷宫:地狱难度", "迷宫:自定义模式(尚未开放)", "按 W / S 键改位置",
"按 O 键确认", "按 Q 键退出并保存设置"
};
for(rint i=1;i<=len+3;i++)
{
int col=0;
if(choose==i)col=2;
canvas({i*2-1,1},col,text[i]);
}
char k =getch();
if(press( k, 'w'))cur = (cur-1+len-1)%len+1;
if(press( k, 's'))cur = cur%len+1;
if(press( k, 'o'))
{
if(1<=cur && cur<=5)
{
choose = cur;
if(cur==5)
{
system("cls");
canvas({1,1},0,"暂未开放 ");
choose = 4;
// canvas({-1,1},0,"尽量不要进行非合法/常规输入,否则会出bug ");
// canvas({1,1},0,"输入迷宫宽度: "); cin>>mode[5][1];
// canvas({3,1},0,"输入迷宫长度: "); cin>>mode[5][2];
// canvas({5,1},0,"输入迷宫引导之星数量: "); cin>>mode_item[5][1];
// canvas({7,1},0,"输入完毕 ");
Sleep(2000);
}
}
}
if(press( k, 'q'))enter_setting();
}
}
void lose()
{
game_over = true;
ending_of_game();
system("cls");
cam_dp= {3,20};
string s=str(score);
int sx= vision.x>>1, sy= vision.y>>1;
Setpos( sx, sy ); Color(0); SlowDisplay(100,"You lost!");
Setpos( sx +1 , sy ); Color(0); SlowDisplay(100,"used time:"+str( (clock()-startTime)/1000 ) + " score:"+str(score));
Setpos( sx +2 , sy ); system("pause");
}
void win()
{
game_over = true;
ending_of_game();
system("cls");
string s=str(score);
cam_dp= {3,20};
int sx= vision.x>>1, sy= vision.y>>1;
Setpos( sx, sy ); Color(0); SlowDisplay(100,"You won!");
Setpos( sx +1 , sy ); Color(0); SlowDisplay(100,"used time:"+str( (clock()-startTime)/1000 ) + " score:"+str(score));
Setpos( sx +2 , sy ); system("pause");
}
void ending_of_game()
{
paint();
game_update();
for(int i=1;i<=3;i++)
{
Setpos(p.x-cam.x+1,p.y-cam.y+1); Color(4); cout<<"●";
Sleep(500);
Setpos(p.x-cam.x+1,p.y-cam.y+1); Color(3); cout<<"●";
Sleep(500);
}
for(int i=max(vision.y,vision.x);i>=-vision.y-vision.x+2; --i)
{
for(int j=0;vision.x-j>=1&&i+j<=vision.y; ++j)
if(i+j>=1){Setpos(vision.x-j,i+j); Color(0); cout<<" ";}
Sleep(50);
}
}
void HideCursor(){CONSOLE_CURSOR_INFO cursor_info = {1,0};SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);/*Po*/}
void showCursor()
{
HANDLE h_GAME = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursor_info;
GetConsoleCursorInfo(h_GAME,&cursor_info);
cursor_info.bVisible = true;
SetConsoleCursorInfo(h_GAME,&cursor_info);
}
void Setpos(int x,int y){RealSetpos(x+cam_dp.x,y+cam_dp.y);}
void RealSetpos(int x,int y){COORD pos;pos.X=y*2,pos.Y=x;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);}
void SlowDisplay(int x,string p)
{
for(int i=0;i<p.size();i++)
{
cout<<p[i];
if(kbhit())x = 0;
Sleep(x);
}
}
int sprand(int l,int r){return rand()%(r-l+1)+l;}
void Color(int a)
{
if(a==0) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
if(a==1) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_BLUE);
if(a==2) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_GREEN);
if(a==3) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE);
if(a==4) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED);
if(a==5) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN);
if(a==7) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN);
if(a==8) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|BACKGROUND_RED);
}
inline void read(int &x)
{
int f=1;x=0;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
x=x*f;
}
inline void ffout(int x)
{
if(x<0){x=-x; putchar('-'); }
short sta[63],top=0;
do{ sta[top++]=x%10; x/=10; }while(x);
while(top) putchar(sta[--top]+'0');
}
inline void ffout(int x,char b)
{
if(x<0){x=-x; putchar('-'); }
short sta[63],top=0;
do{ sta[top++]=x%10; x/=10; }while(x);
while(top) putchar(sta[--top]+'0');
putchar(b);
}