想了想还是发下这东西,太喜欢写注释了,虽然没啥营养内容,但还是希望新人轻松点。
极致偷懒不想用图形库,所以被批评简陋了
内容:没有推箱子的Helltaker(下附有推箱子的代码)
大概是三天赶作业的原因,所以没加推箱子逻辑,参考的只有推箱子绘制地图的方法(还不就是造点没用的轮子)
能看出的缺点太多,但是不太想完善了(画面音乐和把妹王差太多了)
不管怎么说吧,也是小成就了哈哈哈
有挺多没用的代码,为了凑要求的……见谅
/*没有推箱子的Helltaker
作者:chiha
游戏说明:
1、选择地图;
2、设置人物初始位置;
3、地图图标说明:★是钥匙,♀是操控人物,◎是出口;
4、操作方法:
大小写WASD或方向键控制移动;
大小写R重置所选地图的人物初始位置;
大小写Q退出游戏;
---函数库---
--初始目标--
步数计数器 有
位置记录 有
移动键 有
人物输出&地图输出(图) 有
地图创建(包括入口和出口) 有
初始人物位置 有
--最终目标--
地图选择 有
最优路径查找(限制步数) 无
钥匙设置 有
添加音乐 无
-新想法-
限制只能用小写awsdqr(加入ctype.h中的识别函数islower())
*/
// #include
#include
#include
#include //getch()
#include //Sleep()
#include
#define MAX 10
typedef int Key;
typedef struct Position{
int x,y;
}POS;
typedef struct MAP{
int x[MAX][MAX];
}map;
//int next[4][2]={(1,0),()} 如果采用小括号赋值,括号整体的值是最后一个元素的值
int next[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; //移动坐标
int cnt = 0; //步数计数
POS Origin; //人物原始位置
//地图库
map Maplib_1 = {
1,1,1,1,1,1,1,1,1,1,
1,0,0,1,0,1,0,0,0,1,
1,0,0,1,0,0,0,0,0,1,
1,0,0,0,1,0,1,0,0,1,
1,0,0,0,0,0,0,1,0,1,
1,1,1,0,1,1,1,0,0,1,
1,0,0,0,0,0,0,1,0,5,
1,0,1,1,0,1,0,0,0,1,
1,0,1,0,0,1,0,1,1,1,
3,0,0,0,1,1,1,1,1,1};//10行10列
map Maplib_2 = {
1,1,1,1,1,1,1,1,1,1,
1,0,0,0,0,0,0,0,0,1,
1,0,1,1,0,1,1,1,0,1,
1,0,0,3,1,0,1,0,0,1,
1,0,1,0,0,0,0,1,0,1,
1,0,1,0,1,1,1,1,0,1,
1,0,1,0,0,1,0,1,0,5,
1,0,0,0,0,0,0,1,0,1,
1,0,1,0,0,1,0,0,0,1,
1,1,0,1,1,1,1,1,1,1};
int move_Ctrl(POS &A, map M); //移动控制
int move_Judge(POS A,map M); //移动判断 判断人物是否与地图障碍重叠 返回值为 1重叠 0正常
void create_Map(map &M); //创建地图 int M[][10] int只存地址 (全局变量map实现,无法换地图)
void init_Pos(POS &A, map M); //初始位置 手动输入xy
int pace_Count(int &c); //步数记录 全局变量cnt实现
int output_Cha(POS A,map M); //人物输出 修改地图来实现
int key_exit(POS A,map M,Key &k,int c);//钥匙设置
int key_Delete(map &M, POS A); //在地图上删除钥匙的位置
void game_WIN(int c); //游戏结束
void game_load(); //游戏加载模拟
void game_intr(); //游戏介绍
int map_Select(map &M); //地图选择
void map_Show(map M1,map M2); //地图展示
int main(){
map Map; //地图地址
POS pos; //人物位置
Key k = 0; //钥匙是否获取flag
int move_Status = 0;
game_intr();
map_Show(Maplib_1,Maplib_2);
map_Select(Map);
init_Pos(pos,Map);
game_load();
//create_Map(Map);
do{
system("cls"); //刷新屏幕
key_exit(pos,Map,k,cnt); //1111
output_Cha(pos, Map);
move_Status = move_Ctrl(pos,Map);
key_exit(pos,Map,k,cnt); //2222必须两遍,否则会无法结束游戏
key_Delete(Map, pos);
if(move_Status != 7) //加了这句if步数正常了,不用再/2处理
pace_Count(cnt);
}while(1);
return 0;
}
void game_intr(){
printf("游戏说明:\n1、选择地图;\n2、设置人物初始位置;\n3、地图图标说明:★是钥匙,♀是操控人物,◎是出口;\n4、操作方法:\n大小写WASD或方向键控制移动;\n大小写R重置所选地图的人物初始位置;\n大小写Q退出游戏;\n");
}
int key_Delete(map &M, POS A){
if(M.x[A.x][A.y] == 3)
M.x[A.x][A.y] = 0;
return 0;
}
void game_load(){
system("cls");printf("正在生成所选地图");Sleep(500);printf(".");
Sleep(500);printf(".");Sleep(500);printf(".");Sleep(500);
system("cls");printf("正在加载人物");Sleep(500);printf(".");
Sleep(500);printf(".");Sleep(500);printf(".");Sleep(500);
}
void map_Show(map Maplib_1,map Maplib_2){
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
switch (Maplib_1.x[i][j])
{
case 0:
printf(" "); //空白的地方
break;
case 1:
printf("■"); //墙
break;
case 3:
printf("★"); //钥匙
break;
case 5:
printf("◎"); //出口
break;
}
}
printf("\n");
}
printf("地图1\n\n");
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
switch (Maplib_2.x[i][j])
{
case 0:
printf(" "); //空白的地方
break;
case 1:
printf("■"); //墙
break;
case 3:
printf("★"); //钥匙
break;
case 5:
printf("◎"); //出口
break;
}
}
printf("\n");
}
printf("地图2\n\n");
}
int map_Select(map &M){
int n;
printf("地图选择");
sss:printf("(可选1,2):");//sss
scanf("%d",&n);
printf("\n");
switch (n)
{
case 1:
M=Maplib_1;
printf("你选择了我,我是いちぽ哒!\n");
break;
case 2:
M=Maplib_2;
printf("你选择了我,我是にぽ哒!\n");
break;
default:
printf("我没有那么厉害啦!!!\n");
printf("重新选咯~");
// map_Select(M); //递归不好实现,改用goto
goto sss;
}
return 0;
}
void game_WIN(int c){
int n;
system("cls");
printf("成功\n");
printf("花费步数:%d\n",c);//计数会计数两遍,暂时作/2处理
printf("按R重置游戏,按Q退出游戏\n");
}
int key_exit(POS A,map M,Key &k,int c){
if(M.x[A.x][A.y] == 3)
k = 1; //拿到钥匙
if(k == 1 && M.x[A.x][A.y] == 5)
game_WIN(c); //拿到钥匙且走到出口
return 0;
}
int move_Ctrl(POS &A,map M){
int dir;//方向键
// Origin_CG = A;//保留上一步
dir = getch();//getchar()需要回车
// if(islower(dir)||dir==75||dir==72||dir==77||dir==80)//加这句只限制小写后,用方向键操作会加倍步数
switch (dir){
//case 'A':
case 'a':
case 75: //左
A.y--; //数组反向思维
if(move_Judge(A,M)==1)
A.y++; //重叠就重新输入
break;
//case 'W':
case 'w':
case 72: //上
A.x--;
if(move_Judge(A,M)==1)
A.x++;
break;
//case 'D':
case 'd':
case 77: //右
A.y++;
if(move_Judge(A,M)==1)
A.y--;
break;
//case 'S':
case 's':
case 80: //下
A.x++;
if(move_Judge(A,M)==1)
A.x--;
break;
//case 'R':
case 'r':
A = Origin;
//cnt = -1; //因为main执行后会加一所以需要改为-1
cnt = 0; //或者和退出Q一样用返回值7
return 7;
//case 'Q':
case 'q':
Sleep(1000); //慢一点退出
exit(-2);
default:
//exit(-2); //测试暂定直接退出
return 7; //7的意志!!!
}
return 0;
}
void init_Pos(POS &A,map M){
printf("\n请输入人物的初始位置: x = ");
scanf("%d",&A.y);
printf("%23sy = ");//刚刚好对齐
scanf("%d",&A.x);
A.y--;
A.x--;
Origin = A;
if(A.y > 9 || A.x > 9 || move_Judge(A, M)){ //人物是否生成越界或者与地图重叠
printf("你不能出现在这!!!\n");
init_Pos(A,M);
}
}
int move_Judge(POS A,map M){
if(M.x[A.x][A.y]==1)
return 1; //重叠地图 1
return 0; //正常 0
}
int pace_Count(int &c){
c++;
return 0;
}
int output_Cha(POS A,map M){
M.x[A.x][A.y] = 2; //把人放到地图上先————先前已经判断重叠,这里直接放
for(int i = 0; i < 10; i++){
for(int j = 0; j < 10; j++){
switch (M.x[i][j])
{
case 0:
printf(" "); //空白的地方
break;
case 1:
printf("■"); //墙
break;
case 2:
printf("♀"); //人
break;
case 3:
printf("★"); //钥匙
break;
case 5:
printf("◎"); //出口
break;
default:
break;
}
if(i==6 && j==9)
printf(" 已走步数:%d",cnt);
if(i==7 && j==9)
printf(" 按R重新开始");
}
printf("\n");
}
return 0;
}以下是推箱子的,实在找不到原作者了,实在抱歉。。。(作为轮子来说应该也没太大关系)
#include<stdio.h>
#include<conio.h>
#include<windows.h>
int map[9][11]={
{0,1,1,1,1,1,1,1,1,1,0},
{0,1,0,0,0,1,0,0,0,1,0},
{0,1,0,0,3,0,0,0,0,1,0},
{0,1,0,3,0,3,3,3,0,1,1},
{0,1,0,0,0,2,0,0,0,0,1},
{1,1,0,0,1,1,1,0,3,0,1},
{1,0,4,4,0,4,0,0,0,0,1},
{1,0,4,4,0,4,4,3,0,1,1},
{1,1,1,1,1,1,1,1,1,1,0}
};//原始的图表,五行六列,其中 0 代表着空白的地方; 1 代表着墙;2 代表着人;
//3 代表着箱子;4 代表着箱子的终点位置。
//图的变化要靠自己来编写数组,通过数字来进行图的构造。
int drawmain();
int tuidong();
int winshu();
int main()//主函数
{
while(1)
{
system("cls");//对其进行清屏
drawmain();
tuidong();
}
printf("shuchu \n");
return 0;
}
//把图形刻画出来
int drawmain()
{
int i,j;
winshu();//调用输赢的函数
for(i=0;i<9;i++)
{
for(j=0;j<11;j++)
{
switch(map[i][j])
{
case 0:
printf(" "); //空白的地方
break;
case 1:
printf("■"); //墙
break;
case 2:
printf("♀"); //人
break;
case 3:
printf("☆"); //箱子
break;
case 4:
printf("◎"); //终点地方
break;
case 6:
printf("♂");//人加终点位置
break;
case 7:
printf("★") ;//箱子加终点位置
break;
}
}
printf("\n");
}
}
//进行小人的移动,整个移动的过程就是数组变化的过程
int tuidong()
{
int count,caw=0;//行和列
int i,j,tui;
for(i=0;i<9;i++){
for (j=0;j<11;j++)
{
if(map[i][j]==2||map[i][j]==6)
{
count=i;
caw=j;
}
}
}
tui=getch();//与getchar()有区别的是:getchar()输入一个字符后需要回车来进行下一个字符的输入,
//比较麻烦 ,getch()则不需要回车就能连续输入多个字符。
switch(tui)
{//上
case 'W':
case 72:
// 1.人的前面是空地;
// 2.人的前面是终点位置;
// 3.人的前面是箱子
//3.1.箱子的前面是空地;
//3.2.箱子的前面是终点位置。
if(map[count-1][caw]==0||map[count-1][caw]==4)
{
map[count][caw]-=2;
map[count-1][caw]+=2;
}
else if(map[count-1][caw]==3||map[count-1][caw]==7)
{
if(map[count-2][caw]==0||map[count-2][caw]==4)
{
map[count][caw]-=2;
map[count-1][caw]-=1;
map[count-2][caw]+=3;
}
}
break;
//下
case 'S':
case 80://键值
if(map[count+1][caw]==0||map[count+1][caw]==4)
{
map[count][caw]-=2;
map[count+1][caw]+=2;
}
else if(map[count+2][caw]==0||map[count+2][caw]==4)
{
if(map[count+1][caw]==3||map[count+1][caw]==7)
{
map[count][caw]-=2;
map[count+1][caw]-=1;
map[count+2][caw]+=3;
}
}
break;
//左
case 'A':
case 75:
if(map[count][caw-1]==0||map[count][caw-1]==4)
{
map[count][caw]-=2;
map[count][caw-1]+=2;
}
else if(map[count][caw-2]==0||map[count][caw-2]==4)
{
if(map[count][caw-1]==3||map[count][caw-1]==7)
{
map[count][caw]-=2;
map[count][caw-1]-=1;
map[count][caw-2]+=3;
}
}
break;
//右
case 'D':
case 77:
if(map[count][caw+1]==0||map[count][caw+1]==4)
{
map[count][caw]-=2;
map[count][caw+1]+=2;
}
else if(map[count][caw+2]==0||map[count][caw+2]==4)
{
if(map[count][caw+1]==3||map[count][caw+1]==7)
{
map[count][caw]-=2;
map[count][caw+1]-=1;
map[count][caw+2]+=3;
}
}
break;
}
}
int winshu()
{
int k = 0;//初始化
int j,i;
for(i=0;i<9;i++)
{
for (j=0;j<11;j++)
{
if(map[i][j]==3)
k++;
}
}
if(k==0)
printf("恭喜你,你赢了!\n");
}共勉

京公网安备 11010502036488号