#include <stdio.h>
#include <graphics.h>
#include <stdlib.h>
#include <dos.h>
#include <ctype.h>
#define TRUE 1
#define FLASE 0
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define UP 72
#define ENTER 28
#define ESC 1
#define Q 16
#define N 49
#define R 19
#define B 48
#define BKCOLOR 0
#define SIZE 15
#define MX 5
#define MY 5
#define MAX_LEVEL 12
#define MAX_COINS 14
int GetRow(int row, int menuNum);
int GetKey();
int GetAct();
void *lightbar;
int data[SIZE][SIZE];
int pointp[MAX_COINS][2];
int x,y,gameDone,NCoins,levelNum,WorkerFace;
main()
{
int driver, mode;
int done1, act;
int i, k, menuNum, done, row;
unsigned size;
driver = VGA;
mode = VGAHI;
initgraph(&driver, &mode, "");
MENU:
levelNum = 1;
setlinestyle(0, 0, 3);
setcolor(WHITE);
rectangle(2, 2, 638, 478);
/*显示标题*/
setcolor(15);
rectangle(120, 60, 500, 140);
setlinestyle(0, 0, 1);
settextstyle(4, HORIZ_DIR, 7);
settextjustify(1, 2);
setcolor(15);
outtextxy(310,60, "Push box");
for (i=11; i<20; i++) DrawWall(i*20, 180);
for (i=11; i<20; i++) DrawWall(i*20, 280);
for (i=10; i<14; i++) DrawWall(200, i*20);
for (i=10; i<14; i++) DrawWall(400, i*20);
WorkerFace = 1;
DrawWorker(300, 210);
for (i=12; i<19; i++) DrawBox(i*20, 240);
for (i=13; i<18; i++) DrawBox(i*20, 260);
/*显示菜单*/
menuNum = 2;
setcolor(LIGHTBLUE);
setfillstyle(1,YELLOW);
for (k=0; k<menuNum; k++)
{
rectangle(230, 340+30*k, 390, 370+30*k);
bar(231, 341+30*k, 389, 369+30*k);
}
settextstyle(1, HORIZ_DIR, 2);
settextjustify(1, 2);
setcolor(LIGHTRED);
outtextxy(310, 342, " New Game");
outtextxy(310, 372, "Exit");
/*设置显示亮条*/
size = imagesize(0,0,158,28);
if (size != 1) lightbar = malloc(size);
setfillstyle(1, 12);
bar(4, 4, 162, 32);
getimage(4, 4, 162, 32, lightbar);
setfillstyle(1, BLACK);
bar(4, 4, 162, 32);
/*将显示亮条放到NewGame菜单上*/
putimage(232,341,lightbar,XOR_PUT);
row = 0;
done = FLASE;
do
{
row = GetRow(row, menuNum);
switch (row)
{
case 0:
/*游戏开始*/
cleardevice();
setbkcolor(BKCOLOR);
done1 = FLASE;
gameDone = FLASE;
ReadFile(data, levelNum, pointp);
act = 0;
do
{
act = GetAct();
switch (act)
{
case 1: /*向下移动*/
WorkerFace = 1;
MoveBox(x, y+1, x, y+2);
if (gameDone) NextLevel();
break;
case 2: /*向上移动*/
WorkerFace = 2;
MoveBox(x, y-1, x, y-2);
if (gameDone) NextLevel();
break;
case 3: /*向左移动*/
WorkerFace = 3;
MoveBox(x-1, y, x-2, y);
if (gameDone) NextLevel();
break;
case 4: /*向右移动*/
WorkerFace = 4;
MoveBox(x+1, y, x+2, y);
if (gameDone) NextLevel();
break;
case 5: /*返回主菜单*/
cleardevice();
goto MENU;
case 6: /*恢复关卡初始状态*/
cleardevice();
ReadFile(data, levelNum, pointp);
break;
case 7: /*循环递增关卡序号*/
if (levelNum == MAX_LEVEL)
levelNum = 1;
else
levelNum++;
cleardevice();
ReadFile(data, levelNum, pointp);
break;
case 8: /*循环递减关卡序号*/
if (levelNum == 1)
levelNum = MAX_LEVEL;
else
levelNum--;
cleardevice();
ReadFile(data, levelNum, pointp);
break;
case 9: /*直接退出游戏*/
done1 = TRUE;
closegraph();
break;
default:
break;
}
}while(!done1);
done = TRUE;
break;
case 1:
/* 退出程序 */
done = TRUE;
closegraph();
exit(0);
}
}while(!done);
}
int GetKey()
{
union REGS rg;
rg.h.ah = 0;
int86(0x16, &rg, &rg);
return rg.h.ah;
}
int GetRow(int row, int menuNum)
{
int key, done = FLASE;
do{
key = GetKey();
switch (key)
{
case DOWN:
putimage(232, 341+row*30, lightbar, XOR_PUT);
if (row == menuNum-1)
row = 0;
else
row++;
putimage(232, 341+row*30, lightbar, XOR_PUT);
break;
case UP:
putimage(232, 341+row*30, lightbar, XOR_PUT);
if (row == 0)
row = menuNum - 1;
else
row --;
putimage(232, 341+row*30, lightbar, XOR_PUT);
break;
case ENTER:
done = TRUE;
break;
case ESC:
row = 2;
done = TRUE;
break;
}
}while (!done);
return row;
}
int GetAct()
{
int act = 0;
int k;
int done = FLASE;
do{
k = GetKey();
switch (k)
{
case DOWN: /*向下移动*/
act = 1;
done = TRUE;
break;
case UP: /*向上移动*/
act = 2;
done = TRUE;
break;
case LEFT: /*向左移动*/
act = 3;
done = TRUE;
break;
case RIGHT: /*向右移动*/
act = 4;
done = TRUE;
break;
case ESC: /*返回主菜单*/
act = 5;
done = TRUE;
break;
case R: /*恢复关卡初始状态*/
act = 6;
done = TRUE;
break;
case N: /*循环递增关卡序号*/
act = 7;
done = TRUE;
break;
case B: /*循环递减关卡序号*/
act = 8;
done = TRUE;
break;
case Q: /*直接退出游戏*/
act = 9;
done = TRUE;
break;
default:
break;
}
}while (!done);
return act;
}
int ReadFile(int data[SIZE][SIZE],int levelNum,int pointp[MAX_COINS][2])
{
int i,j;
FILE *fl = NULL;
char test;
for (i=0; i<MAX_COINS; i++)
{
pointp[i][0] = 0;
pointp[i][1] = 0;
}
NCoins = 0;
WorkerFace = 1;
if ((fl = fopen("level.txt", "rt")) == NULL)
{
settextstyle(1,HORIZ_DIR,2);
setcolor(RED);
outtextxy(300,250,"Make sure a level.txt in the same dir.");
return 0;
}
setlinestyle(0, 0, 3);
setcolor(15);
rectangle(2, 2, 638, 478);
setcolor(7);
rectangle(460, 10, 630, 470);
setfillstyle(1, 6);
bar(462, 12, 628, 468);
settextstyle(4, HORIZ_DIR, 4);
setcolor(15);
outtextxy(545, 50, "Good Luck");
settextstyle(1, HORIZ_DIR, 2);
setcolor(14);
outtextxy(490, 120, "ESC:");
outtextxy(490, 180, "R :");
outtextxy(490, 240, "N :");
outtextxy(490, 300, "B :");
outtextxy(490, 360, "Q :");
settextstyle(0, HORIZ_DIR, 1);
setcolor(11);
outtextxy(545, 155, " return to MENU");
outtextxy(545, 215, " reload the level");
outtextxy(545, 275, " level increase");
outtextxy(545, 335, " level decrease");
outtextxy(545, 395, " quit directly");
for (i=1; i<=SIZE*(levelNum-1); i++)
{
do {
test = fgetc(fl);
}while (test != '\n');
}
for (i=0; i<SIZE; i++)
for (j=0; j<SIZE; j++)
{
test = fgetc(fl);
if (test == '\n')
{
j--;
continue;
}
data[i][j] = test - 48;
switch(data[i][j])
{
case 1:
x = j;
y = i;
DrawWorker((j+MX)*20, (i+MY)*20);
break;
case 2:
DrawWall((j+MX)*20, (i+MY)*20);
break;
case 3:
pointp[NCoins][0] = j;
pointp[NCoins][1] = i;
NCoins++;
DrawCoins((j+MX)*20, (i+MY)*20);
break;
case 4:
DrawBox((j+MX)*20, (i+MY)*20);