📄 mazemain.c
字号:
/* 文件名 : mazeMain.c
* 描述 : 超级迷宫 (Super Maze) 主游戏模块
* 作者 : 文曦畅 Wen Xichang 2004-11-10
*/
#define UP 0x4800 /* 定义BIOS 键盘码 */
#define DOWN 0x5000
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define KEY_W 0x1157
#define KEY_w 0x1177
#define KEY_S 0x1f53
#define KEY_s 0x1f73
#define KEY_A 0x1e41
#define KEY_a 0x1e61
#define KEY_D 0x2044
#define KEY_d 0x2064
#define ENTER 0x1c0d
#define SPACE 0x3920
#define F1 0x3b00
#define ESC 0x11b
#include <stdio.h>
#include <graphics.h>
#include <stdlib.h>
#include <bios.h>
#include "chn.h"
#include "crtMaze.c"
#include "menu.c"
#include "logo.c"
#include "music.c"
unsigned char playerNum = 1; /* 游戏人数, 玩家status = 6 | 7 */
unsigned char gameLevel = 0; /* 初级 */
unsigned char reachIdx[75][97];
/*01*/ void initMaze (int flag); /* 初始化迷宫,flag为标记,0为要初始化随机发生器 */
/*02*/ void initGrphErrExit (void); /* 初始化进入图形模式,并处理可能的错误 */
/*03*/ void playGame (void); /* 负责游戏的主循环 */
/*04*/ void updateThe (Index idx); /* 更新迷宫的一格,为了简便,只对通道和玩家部分更新 */
/*05*/ void updateRect (Index idx, int len); /* 更新以idx为正方形中心,2*len为正方形长的一部分迷宫,有下标越界处理 */
/*06*/ void mazeUpdateEx (Index p1, Index p2); /* mazeUpdate的高级版本,以玩家为中心更新迷宫 */
/*01*/
void initMaze(int flag){
int i,j;
for(i = 0; i < maxIdxY; i++){
for(j = 0; j < maxIdxX; j++){
maze[i][j] = 0;
if(gameLevel == 0) reachIdx[i][j] = 1;
else reachIdx[i][j] = 0;
if((i == 0) || (j == 0) || (i == maxIdxY - 1) || (j == maxIdxX - 1)){
maze[i][j] = 1;
} /* 生成外围墙 */
else if((i % 2 == 0) && (j % 2 == 0)){
maze[i][j] = 1;
} /* 生成点状 */
}
}
if (flag == 0)
randomize();
}
/*02*/
void initGrphErrExit (void){
int gd = VGA, gm = VGAHI, errorcode;
registerbgidriver(EGAVGA_driver);
/* 进入图形模式 */
initgraph(&gd, &gm, "");
/* 错误处理 */
errorcode = graphresult();
if (errorcode != grOk) /* 有错误发生 */
{
printf("\nGraphics error: %s\n", grapherrormsg(errorcode));
printf("\nI am sorry that an error occurred(in initgraph).\n\n");
printf("\t\tPress any key to exit...");
getch();
exit(0);
}
}
/*03*/
void playGame(void){
Index bgIdx = {1, 1};
Index edIdx;
Index player1 = bgIdx,
player2; /* 记录玩家1,2的当前位置 */
Index tmp;
int key = 0; /* 键盘按键 */
int i,j;
int musIdx = random(4); /*音乐部分*/
initMusic();
playerNum = inMenu(MENU_MAIN);
edIdx.x = maxIdxX - 2;
edIdx.y = maxIdxY - 2;
player2 = edIdx;
initMaze(1);
createMaze(bgIdx, edIdx);
maze[player1.y][player1.x] = 6;
if (playerNum > 1)
maze[player2.y][player2.x] = 7;
logo(2);
mazeUpdateEx(player1,player2); /* 初步准备 */
for(;;){ /* 游戏主循环 */
if (bioskey(1))
key=bioskey(0);
else
key=0;
switch(key){
case UP: /* player1 */
if(maze[player1.y - 1][player1.x] != 1){
maze[player1.y][player1.x] = 2;
updateThe(player1);
player1.y--;
maze[player1.y][player1.x] = 6;
updateThe(player1);
}
if (gameLevel != 0) mazeUpdateEx(player1,player2);
break;
case DOWN:
if(maze[player1.y + 1][player1.x] != 1){
maze[player1.y][player1.x] = 2;
updateThe(player1);
player1.y++;
maze[player1.y][player1.x] = 6;
updateThe(player1);
}
if (gameLevel != 0) mazeUpdateEx(player1,player2);
break;
case LEFT:
if(maze[player1.y][player1.x - 1] != 1){
maze[player1.y][player1.x] = 2;
updateThe(player1);
player1.x--;
maze[player1.y][player1.x] = 6;
updateThe(player1);
}
if (gameLevel != 0) mazeUpdateEx(player1,player2);
break;
case RIGHT:
if(maze[player1.y][player1.x + 1] != 1){
maze[player1.y][player1.x] = 2;
updateThe(player1);
player1.x++;
maze[player1.y][player1.x] = 6;
updateThe(player1);
}
if (gameLevel != 0) mazeUpdateEx(player1,player2);
break;
case KEY_W:
case KEY_w:
if(playerNum > 1){
if(maze[player2.y - 1][player2.x] != 1){
maze[player2.y][player2.x] = 2;
updateThe(player2);
player2.y--;
maze[player2.y][player2.x] = 7;
updateThe(player2);
}
}
if (gameLevel != 0) mazeUpdateEx(player1,player2);
break;
case KEY_S:
case KEY_s:
if(playerNum > 1){
if(maze[player2.y + 1][player2.x] != 1){
maze[player2.y][player2.x] = 2;
updateThe(player2);
player2.y++;
maze[player2.y][player2.x] = 7;
updateThe(player2);
}
}
if (gameLevel != 0) mazeUpdateEx(player1,player2);
break;
case KEY_A:
case KEY_a:
if(playerNum > 1){
if(maze[player2.y][player2.x - 1] != 1){
maze[player2.y][player2.x] = 2;
updateThe(player2);
player2.x--;
maze[player2.y][player2.x] = 7;
updateThe(player2);
}
}
if (gameLevel != 0) mazeUpdateEx(player1,player2);
break;
case KEY_D:
case KEY_d:
if(playerNum > 1){
if(maze[player2.y][player2.x + 1] != 1){
maze[player2.y][player2.x] = 2;
updateThe(player2);
player2.x++;
maze[player2.y][player2.x] = 7;
updateThe(player2);
}
}
if (gameLevel != 0) mazeUpdateEx(player1,player2);
break;
case ENTER:
inMenu(MENU_PAUSE);
logo(2);
setcolor(WHITE);
if (gameLevel != 3){
for(i = 0; i < maxIdxY; i++){
for(j = 0; j < maxIdxX; j++){
if(reachIdx[i][j] == 1){
tmp.x = j;
tmp.y = i;
updateThe(tmp);
}
}
}
}
else
mazeUpdateEx(player1,player2);
break;
case ESC: /**/
switch(inMenu(MENU_GAMING)){
case 1:
case 0:
logo(2);
setcolor(WHITE);
if (gameLevel != 3){
for(i = 0; i < maxIdxY; i++){
for(j = 0; j < maxIdxX; j++){
if(reachIdx[i][j] == 1){
tmp.x = j;
tmp.y = i;
updateThe(tmp);
}
}
}
}
else
mazeUpdateEx(player1,player2);
break;
case 2: /* 选择新游戏 */
initMaze(1);
edIdx.x = maxIdxX - 2;
edIdx.y = maxIdxY - 2;
player1 = bgIdx;
player2 = edIdx;
createMaze(bgIdx, edIdx);
maze[player1.y][player1.x] = 6;
if (playerNum > 1)
maze[player2.y][player2.x] = 7;
logo(2);
setfillstyle(SOLID_FILL,0);
bar(50,50,MWIDTH+60,MHEIGHT+40);
mazeUpdateEx(player1,player2);
break;
case 3: /* 返回主菜单 */
playerNum = inMenu(MENU_MAIN);
initMaze(1);
edIdx.x = maxIdxX - 2;
edIdx.y = maxIdxY - 2;
player1 = bgIdx;
player2 = edIdx;
createMaze(bgIdx, edIdx);
maze[player1.y][player1.x] = 6;
if (playerNum > 1)
maze[player2.y][player2.x] = 7;
logo(2);
mazeUpdateEx(player1,player2);
break;
case 4: /* 选择退出 */
closegraph();
exit(1);
}
}
if ((player1.x == edIdx.x && player1.y == edIdx.y) || (player2.x == bgIdx.x && player2.y == bgIdx.y)){
inMenu(MENU_SUCCESS);
initMaze(1);
edIdx.x = maxIdxX - 2;
edIdx.y = maxIdxY - 2;
player1 = bgIdx;
player2 = edIdx;
createMaze(bgIdx, edIdx);
maze[player1.y][player1.x] = 6;
if (playerNum > 1)
maze[player2.y][player2.x] = 7;
logo(2);
setfillstyle(SOLID_FILL,0);
bar(50,50,MWIDTH+60,MHEIGHT+40);
mazeUpdateEx(player1,player2);
musIdx = (musIdx >= 3 ? 0 : (musIdx + 1));/*音乐部分*/
}
playMusic(musIdx, 1); /*音乐部分*/
}
}
/*04*/
void updateThe(Index idx){
int width;
int height;
width = MWIDTH / maxIdxX; /* 每一小块的宽 */
height = MHEIGHT / maxIdxY; /* .........高 */
/*x,y (50+width*idx.x) (60+height*idx.y)*/
if(showMode == 0) {
if(maze[idx.y][idx.x] == 1){
if(idx.y > 0)
if(maze[idx.y - 1][idx.x] == 1)
line((50+width*idx.x), (60+height*idx.y), (50+width*idx.x), (60+height*idx.y) - (height / 2));
if(idx.y < maxIdxY - 1)
if(maze[idx.y + 1][idx.x] == 1)
line((50+width*idx.x), (60+height*idx.y), (50+width*idx.x), (60+height*idx.y) + (height / 2));
if(idx.x > 0)
if(maze[idx.y][idx.x - 1] == 1)
line((50+width*idx.x), (60+height*idx.y), (50+width*idx.x) - (width / 2), (60+height*idx.y));
if(idx.x < maxIdxX - 1)
if(maze[idx.y][idx.x + 1] == 1)
line((50+width*idx.x), (60+height*idx.y), (50+width*idx.x) + (width / 2), (60+height*idx.y));
}
else if (maze[idx.y][idx.x] == 6 || maze[idx.y][idx.x] == 7){
setfillstyle(SOLID_FILL,maze[idx.y][idx.x]);
bar((50+width*idx.x) - (width / 2), (60+height*idx.y) - (height / 2), (50+width*idx.x) + (width / 2), (60+height*idx.y) + (height / 2));
}
else {
setfillstyle(SOLID_FILL,0);
bar((50+width*idx.x) - (width / 2), (60+height*idx.y) - (height / 2), (50+width*idx.x) + (width / 2), (60+height*idx.y) + (height / 2));
}
}
else{
if(maze[idx.y][idx.x] == 2){
setfillstyle(SOLID_FILL,15);
bar((50+width*idx.x), (60+height*idx.y), (50+width*idx.x) + width, (60+height*idx.y) + height);
}
else{
setfillstyle(SOLID_FILL,maze[idx.y][idx.x]);
bar((50+width*idx.x), (60+height*idx.y), (50+width*idx.x) + width, (60+height*idx.y) + height);
}
}
}
/*05*/
void updateRect(Index idx, int len){
Index bg,ed,tmp;
int i,j;
bg.x = (idx.x - len < 0 ? 0 : idx.x - len);
bg.y = (idx.y - len < 0 ? 0 : idx.y - len);
ed.x = (idx.x + len > maxIdxX - 1 ? maxIdxX - 1 : idx.x + len);
ed.y = (idx.y + len > maxIdxY - 1 ? maxIdxY - 1 : idx.y + len);
for(i = bg.y; i <= ed.y; i++){
for(j = bg.x; j <= ed.x; j++){
if(reachIdx[i][j] != 1){
tmp.x = j;
tmp.y = i;
updateThe(tmp);
if(gameLevel != 3)
reachIdx[i][j] = 1;
}
}
}
updateThe(idx);
}
/*06*/
void mazeUpdateEx(Index p1, Index p2){
static Index PP1 = {0, 0},PP2 = {0, 0};
int width;
int height;
setcolor(WHITE);
switch(gameLevel){
case 0: /* 容易全部更新 */
mazeUpdate();
break;
case 1: /* 一般,显示玩家周围10 */
updateRect(p1, 8);
updateRect(p2, 8);
break;
case 2: /* 难 */
updateRect(p1, 4);
updateRect(p2, 4);
break;
case 3: /* 难以致信 */
width = MWIDTH / maxIdxX; /* 每一小块的宽 */
height = MHEIGHT / maxIdxY; /* .........高 */
setfillstyle(SOLID_FILL, BLACK);/*x,y (50+width*p1.x) (60+height*p1.y)*/
if (PP1.x > p1.x) bar((50+width*p1.x) + 4 * width, (60+height*p1.y) - 4 * height, (50+width*p1.x) + 5 * width, (60+height*p1.y) + 4 * height);
else if (PP1.x < p1.x) bar((50+width*p1.x) - 5 * width, (60+height*p1.y) - 4 * height, (50+width*p1.x) - 2 * width, (60+height*p1.y) + 4 * height);
if (PP1.y > p1.y) bar((50+width*p1.x) - 4 * width, (60+height*p1.y) + 2 * height, (50+width*p1.x) + 4 * width, (60+height*p1.y) + 5 * height);
else if (PP1.y < p1.y) bar((50+width*p1.x) - 4 * width, (60+height*p1.y) - 5 * height, (50+width*p1.x) + 4 * width, (60+height*p1.y) - 2 * height);
if (PP2.x > p2.x) bar((50+width*p2.x) + 4 * width, (60+height*p2.y) - 4 * height, (50+width*p2.x) + 5 * width, (60+height*p2.y) + 4 * height);
else if (PP2.x < p2.x) bar((50+width*p2.x) - 5 * width, (60+height*p2.y) - 4 * height, (50+width*p2.x) - 2 * width, (60+height*p2.y) + 4 * height);
if (PP2.y > p2.y) bar((50+width*p2.x) - 4 * width, (60+height*p2.y) + 2 * height, (50+width*p2.x) + 4 * width, (60+height*p2.y) + 5 * height);
else if (PP2.y < p2.y) bar((50+width*p2.x) - 4 * width, (60+height*p2.y) - 5 * height, (50+width*p2.x) + 4 * width, (60+height*p2.y) - 2 * height);
PP1 = p1;
PP2 = p2;
setcolor(WHITE);
updateRect(p1, 3);
updateRect(p2, 3);
break;
}
}
int main(){
initGrphErrExit(); /* 进入图形 */
initMaze(0); /* 初始化迷宫和随机发生器 */
playGame();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -