C语言大作业—森林冰火人
上学期写了C语言大作业,前几天发现代码丢了,多方寻找左后才找到,想想还是存到
CSDN
里面保险。第一次写,连语法都不太懂。。
大作业简介
大作业实现了森林冰火人界面切换及第一关的基本功能
第三方库
本大作业采用EGE图形库,用于输出图片
界面图片切换
界面分为:
游戏开始主界面,地图界面,第一关卡界面,游戏说明界面,关于我们界面,通关界面,人物死亡界面
游戏刚进入时为主界面,上面有开始游戏,游戏说明,关于我们按钮,点击即可切换至相应的界面,开始游戏切换至地图界面,再次点击切换至第一关,第一关死亡或通关可切换至相应界面,再次点击可回到游戏关卡界面
冰火娃动作图片切换
根据原本游戏:
冰娃有9个动作状态,分别为:
静止,上跳,下跳,向左跑,向右跑,左上跳,右上跳,左下跳,右下跳
而火娃有8个动作状态,分别为:
静止,上跳,向左跑,向右跑,左上跳,右上跳,左下跳,右下跳,因为火娃下跳或静止貌似为同一个图像
所以,大作业中,支持双键同时读入,当同时键入“AS”, “WD”, “⬆➡”…时,冰火娃的图片也会立刻发生相应的改变。
冰娃火娃的跑动
当键入相应的方向时,冰火娃的运动状态也会发生改变,开始先由静止获得一定的加速度,然后速度大到一定的程度时保持匀速,松开按键后迅速减速直到静止。
地面,墙壁,冰水,火水与毒液等的判断
用结构体数组存储地面,墙壁,各种机关的坐标(坐标是在游戏关卡界面中实际测出来的)
当遇到地面坐标,向下速度减小为0;
当遇到上方挡板,向上的速度减小为0;
当遇到墙面坐标,向左/右的速度减小为0;
当遇到冰水,火水与毒液,判断角色死亡;
当人物坐标与机关坐标重合,则机关缓缓开启;
当冰火娃坐标在出口门的范围内,门缓缓打开,游戏通关。
代码实现
头文件
#include<stdio.h>
#include<graphics.h>
#include<windows.h>
变量简介
为使得代码的可读性稍微强一些,变量名全部使用英文全称,
eg:
火娃静止图片 _firestill
火娃上跳图片 _fireup
火娃下跳图片 _firedown
火娃向左图片 _fireleft
火娃向右图片 _fireright
火娃左上图片 _firelu(lu=left up)
火娃左下图片 _fireld ( ld=left down)
火娃右上图片 _fireru(ru=right up)
火娃右下图片 _firerd(rd=right down)
冰娃同理
水平方向速度 vx 加速度ax
竖直方向速度 vy 加速度ay
其他名称也基本符合这个原则
下面是定义的所有代码
#define vx 260
#define vy 500
#define ax_normal 250
#define ax_special 150
#define ay 1200
#define time 1.0/60
#define widthleft 43
#define widthright 55
#define lengthup 30
#define lengthdown 77
#define pianyi 4
#define edgeleft 50
#define edgeright 1050
#define DOORWIDTH 60
#define DOORHEIGHT 73
#define ICEDOORX 875
#define ICEDOORY 75
#define FIREDOORX 950
#define FIREDOORY 75
PIMAGE ICEDOOR0, ICEDOOR1, ICEDOOR2, ICEDOOR3, ICEDOOR4, FIREDOOR0, FIREDOOR1, FIREDOOR2, FIREDOOR3, FIREDOOR4;
PIMAGE _enter, _back1, _back2, _barrier1, _dead, succeeded;
PIMAGE _start, _explanationbt, _about, _explanation;
PIMAGE _firestill, _fireup, _firedown, _fireleft, _fireright, _firelu, _fireld, _fireru, _firerd;
PIMAGE _icestill, _iceup, _icedown, _iceleft, _iceright, _icelu, _iceld, _iceru, _icerd;
PIMAGE SWITCH, lift;
char A, B, C, D;
int firedoormode = 24, icedoormode = 24;
int barrier = 0, lifty = 350;
double initial_firex[100] = { 100 }, initial_firey[100] = { 500 }, firex = 0, firey = 0, initial_icex[100] = { 100 }, initial_icey[600] = { 600 }, icex = 0, icey = 0;
double firevx = 0, firevy = 0, icevx = 0, icevy = 0;
结构体及数据初始化
把数据存入数组中,不再赘述
typedef struct model1
{
int x1 = 0, x2 = 1100, y1 = 699, y2 = 714;//714
}model1_;
model1_ floor[10][100], roof[10][100];
typedef struct model2
{
int x = 369, y1 = 617, y2 = 621;
}model2_;
model2_ wallleft[10][100], wallright[10][100];
void datainitial()
{
firedoormode = 24, icedoormode = 24;
lifty = 350;
firex = initial_firex[0];
firey = initial_firey[0];
icex = initial_icex[0];
icey = initial_icey[0];
firevx = 0, firevy = 0, icevx = 0, icevy = 0;
floor[0][15].y1 = 368, floor[0][15].y2 = 383;
}
void initial()
{
//1.各种图片名称=newimage();
//2.getimage(图片名称,“图片");
//3.地板横坐标
floor[0][1].x1 = 36, floor[0][1].x2 = 369;
...
floor[0][16].x1 = 730, floor[0][16].x2 = 810;
//4.地板纵坐标
floor[0][1].y1 = 605, floor[0][1].y2 = 620;
...
floor[0][16].y1 = 240, floor[0][16].y2 = 299;
//5.顶板横坐标
roof[0][1].x1 = 36, roof[0][1].x2 = 369;
...
roof[0][11].x1 = 0, roof[0][11].x2 = 1060;
//6.顶板纵坐标
roof[0][1].y1 = 618, roof[0][1].y2 = 633;
...
roof[0][11].y1 = 30, roof[0][11].y2 = 45;
//7.左墙壁横坐标
wallleft[0][1].x = 369; wallleft[0][2].x = 505;
wallleft[0][3].x = 919; wallleft[0][4].x = 575;
wallleft[0][5].x = 949; wallleft[0][6].x = 235;
//8.左墙壁纵坐标
wallleft[0][1].y1 = 617, wallleft[0][1].y2 = 621;
wallleft[0][2].y1 = 496, wallleft[0][2].y2 = 520;
wallleft[0][3].y1 = 565, wallleft[0][3].y2 = 572;
wallleft[0][4].y1 = 368, wallleft[0][4].y2 = 392;
wallleft[0][5].y1 = 297, wallleft[0][5].y2 = 313;
wallleft[0][6].y1 = 268, wallleft[0][6].y2 = 272;
//9.右墙壁横坐标
wallright[0][1].x = 974; wallright[0][2].x = 948;
wallright[0][3].x = 508; wallright[0][4].x = 148;
wallright[0][5].x = 532; wallright[0][6].x = 277;
//10.右墙壁纵坐标
wallright[0][1].y1 = 667, wallright[0][1].y2 = 687;
wallright[0][2].y1 = 447, wallright[0][2].y2 = 460;
wallright[0][3].y1 = 420, wallright[0][3].y2 = 423;
wallright[0][4].y1 = 392, wallright[0][4].y2 = 396;
wallright[0][5].y1 = 262, wallright[0][5].y2 = 272;
wallright[0][6].y1 = 163, wallright[0][6].y2 = 180;
}
冰火娃图片切换
上文说过,冰火娃跑动和静止状态下图像不同,所以要不断切换,要求不能有图片背景,png图片直接输出依然不行,所以,采用
eg:
putimage_withalpha(NULL, _icedown, int(icex), int(icey));
采用GetAsyncKeyState(‘键’ & 0x8000)来读取键入的信息
其实这一块代码都是大同小异,复制粘贴就好
//人物图片变换
void changepeople()
{
int modex = 0, modey = 0;
//冰娃图片切换,规定左 -1,右 1,上 1,下 -1
if (GetAsyncKeyState('A') & 0x8000)
{
modex--;
if (icex + widthleft >= edgeleft)
{
if (judegewall_left(icex, icey, 0) == 0)
icevx = -vx;
}
else icevx = 0;
}
if (GetAsyncKeyState('D') & 0x8000)
{
modex++;
if (icex + widthright <= edgeright)
{
if (judegewall_right(icex, icey, 0) == 0)
icevx = vx;
}
else icevx = 0;
}
if (GetAsyncKeyState('W') & 0x8000)
{
modey++;
if (judgefloor(icex, icey, barrier, icevx) == 1)
{
icevy = -vy;
}
}
if (GetAsyncKeyState('S') & 0x8000)
{
modey--;
}
//九个动作情况
if (modex == 0 && modey == -1)
{
putimage_withalpha(NULL, _icedown, int(icex), int(icey));
}
if (modex == 1 && modey == 0)
{
putimage_withalpha(NULL, _iceright, int(icex), int(icey));
}
if (modex == -1 && modey == 0)
{
putimage_withalpha(NULL, _iceleft, int(icex), int(icey));
}
if (modex == 1 && modey == -1)
{
putimage_withalpha(NULL, _icerd, int(icex), int(icey));
}
if (modex == -1 && modey == -1)
{
putimage_withalpha(NULL, _iceld, int(icex), int(icey));
}
if (modex == 1 && modey == 1)
{
putimage_withalpha(NULL, _iceru, int(icex), int(icey));
}
if (modex == -1 && modey == 1)
{
putimage_withalpha(NULL, _icelu, int(icex), int(icey));
}
if (modex == 0 && modey == 1)
{
putimage_withalpha(NULL, _iceup, int(icex), int(icey));
}
if (modex == 0 && modey == 0)
{
putimage_withalpha(NULL, _icestill, int(icex), int(icey));
}
modex = 0;
modey = 0;
//火娃图片切换,规定左 -1,右 1,上 1,下 -1
if (GetAsyncKeyState(VK_LEFT) & 0x8000)
{
modex--;
if (firex + widthleft >= edgeleft)
{
if (judegewall_left(firex, firey, 0) == 0)
firevx = -vx;
}
else firevx = 0;
}
if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
{
modex++;
if (firex + widthright <= edgeright)
{
if (judegewall_right(firex, firey, 0) == 0)
firevx = vx;
}
else firevx = 0;
}
if (GetAsyncKeyState(VK_UP) & 0x8000)
{
modey++;
if (judgefloor(firex, firey, barrier, firevx) == 1)
{
firevy = -vy;
}
}
if (GetAsyncKeyState(VK_DOWN) & 0x8000)
{
modey--;
}
//九个动作情况
if (modex == 0 && modey == -1)
{
;
putimage_withalpha(NULL, _firedown, firex, firey);
}
if (modex == 1 && modey == 0)
{
putimage_withalpha(NULL, _fireright, firex, firey);
}
if (modex == -1 && modey == 0)
{
putimage_withalpha(NULL, _fireleft, firex, firey);
}
if (modex == 1 && modey == -1)
{
putimage_withalpha(NULL, _firerd, firex, firey);
}
if (modex == -1 && modey == -1)
{
putimage_withalpha(NULL, _fireld, firex, firey);
}
if (modex == 1 && modey == 1)
{
putimage_withalpha(NULL, _fireru, firex, firey);
}
if (modex == -1 && modey == 1)
{
putimage_withalpha(NULL, _firelu, firex, firey);
}
if (modex == 0 && modey == 1)
{
putimage_withalpha(NULL, _fireup, firex, firey);
}
if (modex == 0 && modey == 0)
{
putimage_withalpha(NULL, _firestill, firex, firey);
}
}
冰火娃动作
这一部分主要难度在于速度与加速度都是double 型,导致将来判断各种障碍物的时候不能单纯的判断相等,而是需要一个范围,如果判断相等,而速度较大的话,上一秒,还在墙的左边(不等于墙的坐标),下一秒,就在墙的右边(也不等于墙的坐标),会出现穿墙而过的情况
//冰火娃在正常地面与岩浆中的跑动速度与加速度关系
void run(double* VX, double* VY, double X, double Y)
{
if (1) //正常地面
{
if (*VX > 0)
{
if (*VX - ax_normal >= 0)
*VX -= time * ax_normal;
else *VX = 0;
}
if (*VX < 0)
{
if (*VX + ax_normal <= 0)
*VX += time * ax_normal;
else *VX = 0;
}
if ((judgefloor(X, Y, 0, *VX) == 1 && (*VY < -5) || (*VY == 0)) || (judgefloor(X, Y, 0, *VX) == 0))
{
*VY += ay * time;
}
else *VY = 0;
if ((judgeroof(X, Y, 0) == 1) && (*VY < 0))
{
*VY = 0;
}
}
}
//冰火娃在正常地面与晶体上的跑动速度与路程关系
void svrelation(double* VX, double* VY, double* X, double* Y)
{
*X += *VX * time;
*Y += *VY * time;
if (*VX != 0)*Y -= 1.5;
else *Y -= 1.0 / 6;
}
出口&&地面&&墙壁&&机关判断
原理已经介绍过,单纯数据判断,没什么难度
//判断火门
int judgefiredoor(double X, double Y)
{
for (int cnt = 0; cnt < 100; cnt++)
{
if (X + widthleft >= FIREDOORX && X + widthleft <= FIREDOORX + DOORWIDTH)
if (Y + lengthdown - 50 <= FIREDOORY + DOORHEIGHT)
return 1;
}
return 0;
}
//判断冰门
int judgeicedoor(double X, double Y)
{
for (int cnt = 0; cnt < 100; cnt++)
{
if (X + widthleft >= ICEDOORX && X + widthleft <= ICEDOORX + DOORWIDTH)
if (Y + lengthdown - 50 <= ICEDOORY + DOORHEIGHT)
return 1;
}
return 0;
}
//判断冰面
int judgeicefloor(double X, double Y)
{
if (X + widthleft <= 630 && X + widthright >= 545 && Y + lengthdown - pianyi >= 685)return 1;
return 0;
}
//判断d面
int judgepoisonfloor(double X, double Y)
{
if (X + widthleft >= 695 && X + widthright <= 815 && Y + lengthdown - pianyi >= 540 && Y + lengthdown - pianyi <= 568) return 1;
return 0;
}
int judgeswitch(double X, double Y)
{
if (X + widthleft >= 301 && X + widthright <= 337 && Y + lengthdown - pianyi >= 508 && Y + lengthdown - pianyi <= 523)return 1;
return 0;
}
//判断火面
int judgefirefloor(double X, double Y)
{
if (X + widthleft <= 864 && X + widthright >= 770 && Y + lengthdown - pianyi >= 685) return 1;
return 0;
}
//判断是否在地面或斜面上
int judgefloor(double X, double Y, int i, double V)
{
for (int cnt = 0; cnt < 50; cnt++)
{
if (X + widthleft >= floor[i][cnt].x1 && X + widthright <= floor[i][cnt].x2 && Y + lengthdown - pianyi >= floor[i][cnt].y1 && Y + lengthdown - pianyi <= floor[i][cnt].y2)
return 1;
}
if (V <= 0)
for (int cnt = 50; cnt < 75; cnt++)
{
if (X + widthleft >= floor[i][cnt].x1 && X + widthright <= floor[i][cnt].x2 && Y + lengthdown - pianyi >= floor[i][cnt].y1 && Y + lengthdown - pianyi <= floor[i][cnt].y2)
return 1;
}
if (V >= 0)
for (int cnt = 75; cnt < 100; cnt++)
{
if (X + widthleft >= floor[i][cnt].x1 && X + widthright <= floor[i][cnt].x2 && Y + lengthdown - pianyi >= floor[i][cnt].y1 && Y + lengthdown - pianyi <= floor[i][cnt].y2)
return 1;
}
return 0;
}
//判断是否会撞顶面
int judgeroof(double X, double Y, int i)
{
for (int cnt = 0; cnt < 100; cnt++)
{
if (X + widthright >= roof[i][cnt].x1 && X + widthleft <= roof[i][cnt].x2 && Y + lengthup - pianyi >= roof[i][cnt].y1 && Y + lengthup - pianyi <= roof[i][cnt].y2)
return 1;
}
return 0;
}
//判断是否撞左墙
int judegewall_left(double X, double Y, int i)
{
for (int cnt = 0; cnt < 100; cnt++)
{
if (X + widthleft - wallleft[i][cnt].x <= 10 && X + widthleft - wallleft[i][cnt].x >= -40)
if (Y + lengthup <= wallleft[i][cnt].y2 && Y + lengthdown >= wallleft[i][cnt].y1)
return 1;
}
return 0;
}
//判断是否撞右墙
int judegewall_right(double X, double Y, int i)
{
for (int cnt = 0; cnt < 100; cnt++)
{
if (wallright[i][cnt].x - (X + widthright) <= 10 && wallright[i][cnt].x - (X + widthright) >= -40)
if (Y + lengthup <= wallright[i][cnt].y2 && Y + lengthdown >= wallright[i][cnt].y1)
return 1;
}
return 0;
}
游戏界面切换
这一部分我觉得是整个大作业逻辑性最强的部分,需要理清楚图片输出的逻辑关系,虽然仅仅只有一关,我还是觉得蛮麻烦的,一个函数套一个函数
void map1()
{
msg = { 0 };
for (; is_run(); delay_fps(60))
{
cleardevice();
putimage(0, 0, _barrier1);
if (firedoormode && judgefiredoor(firex, firey) == 1)
{
if (firedoormode > 18)
putimage_withalpha(NULL, FIREDOOR3, FIREDOORX, FIREDOORY);
else if (firedoormode > 12)
putimage_withalpha(NULL, FIREDOOR2, FIREDOORX, FIREDOORY);
else if (firedoormode > 6)
putimage_withalpha(NULL, FIREDOOR1, FIREDOORX, FIREDOORY);
else
putimage_withalpha(NULL, FIREDOOR0, FIREDOORX, FIREDOORY);
if (firedoormode > 1 && judgefiredoor(firex, firey)) firedoormode--;
}
if (judgefiredoor(firex, firey) == 0) firedoormode = 24;
if (icedoormode && judgeicedoor(icex, icey) == 1)
{
if (icedoormode > 18)
putimage_withalpha(NULL, ICEDOOR3, ICEDOORX, ICEDOORY);
else if (icedoormode > 12)
putimage_withalpha(NULL, ICEDOOR2, ICEDOORX, ICEDOORY);
else if (icedoormode > 6)
putimage_withalpha(NULL, ICEDOOR1, ICEDOORX, ICEDOORY);
else
putimage_withalpha(NULL, ICEDOOR0, ICEDOORX, ICEDOORY);
if (icedoormode > 1 && judgeicedoor(icex, icey)) icedoormode--;
}
if (judgeicedoor(icex, icey) == 0) icedoormode = 24;
changepeople();
run(&firevx, &firevy, firex, firey);
run(&icevx, &icevy, icex, icey);
svrelation(&firevx, &firevy, &firex, &firey);
svrelation(&icevx, &icevy, &icex, &icey);
// xyprintf(0, 0, "X=%4d Y=%4d MSG=%4d FLAG=%4d", msg.x, msg.y, msg.msg, msg.flags);
putimage_withalpha(NULL, SWITCH, 260, 460);
putimage_withalpha(NULL, lift, 30, lifty);
if (judgeicedoor(icex, icey) && judgefiredoor(firex, firey))
{
while (1)
{
while (mousemsg())
{
msg = getmouse();
}
if (msg.msg == 16)return;
putimage(0, 0, succeeded);
datainitial();
}
}
if (judgeswitch(firex, firey) + judgeswitch(icex, icey) > 0 && lifty <= 450)
{
floor[0][15].y1++; floor[0][15].y2++; lifty++;
}
if (judgeicefloor(firex, firey) || judgepoisonfloor(firex, firey) || judgepoisonfloor(icex, icey) || judgefirefloor(icex, icey))
{
while (1)
{
while (mousemsg())
{
msg = getmouse();
}
if (msg.msg == 16)return;
putimage(0, 0, _dead);
datainitial();
}
}
//xyprintf(0, 0, "\nfirevy=%10.10lf ", firevy);
//if (msg.flags == 1)return;
}
}
//游戏主地图界面
void mapmain()
{
msg = { 0 };
while (1)
{
for (; msg.msg != 16; delay_fps(60))
{
while (mousemsg())
{
msg = getmouse();
}
putimage(0, 0, _back1);
}
map1();
msg = { 0 };
}
}
void explanation()
{
msg = { 0 };
for (; is_run(); delay_fps(60))
{
while (mousemsg())
{
msg = getmouse();
}
putimage(0, 0, _explanation);
if (msg.flags == 1) return;
}
}
//关于我们游戏界面
void about()
{
msg = { 0 };
for (; is_run(); delay_fps(60))
{
while (mousemsg())
{
msg = getmouse();
}
putimage(0, 0, _back2);
if (msg.flags == 1) return;
}
}
//加载进入界面,地图,游戏关卡背景
void welcome()
{
msg = { 0 };
for (; is_run(); delay_fps(60))
{
while (mousemsg())
{
msg = getmouse();
}
cleardevice();
putimage(0, 0, _enter);
if (msg.x >= 425 && msg.x <= 645)
{
if (msg.y >= 430 && msg.y <= 480)
{
putimage_withalpha(NULL, _start, 380, 405);
if (msg.flags == 1)
{
mapmain();
}
}
else if (msg.y >= 540 && msg.y <= 590)
{
putimage_withalpha(NULL, _explanationbt, 385, 517);
if (msg.flags == 1)
{
explanation();
//msg = { 0 };
}
}
else if (msg.y >= 650 && msg.y <= 700)
{
putimage_withalpha(NULL, _about, 380, 623);
if (msg.flags == 1)
{
about();
}
}
}
//xyprintf(0, 0, "X=%4d Y=%4d MSG=%4d FLAG=%4d", msg.x, msg.y, msg.msg, msg.flags);
}
}
//控制台函数,调节逻辑关系
void operate()
{
firex = initial_firex[0];
firey = initial_firey[0];
icex = initial_icex[0];
icey = initial_icey[0];
msg = { 0 };
for (; is_run(); delay_fps(60))
{
while (mousemsg())
{
msg = getmouse();
}
cleardevice();
welcome();
}
}
主函数
主函数就设置一下基本的窗口就好
int main()
{
initgraph(1100, 740);
setcaption("森林冰火人");
initial();
// mouse();
operate();
return 0;
}
作业呈现
源代码
#include<stdio.h>
#include<graphics.h>
#include<windows.h>
#define vx 260
#define vy 500
#define ax_normal 250
#define ax_special 150
#define ay 1200
#define time 1.0/60
#define widthleft 43
#define widthright 55
#define lengthup 30
#define lengthdown 77
#define pianyi 4
#define edgeleft 50
#define edgeright 1050
#define DOORWIDTH 60
#define DOORHEIGHT 73
#define ICEDOORX 875
#define ICEDOORY 75
#define FIREDOORX 950
#define FIREDOORY 75
PIMAGE ICEDOOR0, ICEDOOR1, ICEDOOR2, ICEDOOR3, ICEDOOR4, FIREDOOR0, FIREDOOR1, FIREDOOR2, FIREDOOR3, FIREDOOR4;
PIMAGE _enter, _back1, _back2, _barrier1, _dead, succeeded;
PIMAGE _start, _explanationbt, _about, _explanation;
PIMAGE _firestill, _fireup, _firedown, _fireleft, _fireright, _firelu, _fireld, _fireru, _firerd;
PIMAGE _icestill, _iceup, _icedown, _iceleft, _iceright, _icelu, _iceld, _iceru, _icerd;
PIMAGE SWITCH, lift;
char A, B, C, D;
int firedoormode = 24, icedoormode = 24;
int barrier = 0, lifty = 350;
double initial_firex[100] = { 100 }, initial_firey[100] = { 500 }, firex = 0, firey = 0, initial_icex[100] = { 100 }, initial_icey[600] = { 600 }, icex = 0, icey = 0;
double firevx = 0, firevy = 0, icevx = 0, icevy = 0;
mouse_msg msg = { 0 };
//地面坐标,构建一个可以容纳十关,每关可以有100个坐标的数组
typedef struct model1
{
int x1 = 0, x2 = 1100, y1 = 699, y2 = 714;//714
}model1_;
model1_ floor[10][100], roof[10][100];
typedef struct model2
{
int x = 369, y1 = 617, y2 = 621;
}model2_;
model2_ wallleft[10][100], wallright[10][100];
void datainitial()
{
firedoormode = 24, icedoormode = 24;
lifty = 350;
firex = initial_firex[0];
firey = initial_firey[0];
icex = initial_icex[0];
icey = initial_icey[0];
firevx = 0, firevy = 0, icevx = 0, icevy = 0;
floor[0][15].y1 = 368, floor[0][15].y2 = 383;
}
void initial()
{
//初始化图片
succeeded = newimage();
_explanation = newimage();
_dead = newimage();
SWITCH = newimage();
lift = newimage();
_enter = newimage();
_back1 = newimage();
_back2 = newimage();
_barrier1 = newimage();
_start = newimage();
_about = newimage();
_explanationbt = newimage();
_icestill = newimage();
_iceup = newimage();
_icedown = newimage();
_iceleft = newimage();
_iceright = newimage();
_icelu = newimage();
_iceld = newimage();
_iceru = newimage();
_icerd = newimage();
_firestill = newimage();
_fireup = newimage();
_firedown = newimage();
_fireleft = newimage();
_fireright = newimage();
_firelu = newimage();
_fireld = newimage();
_fireru = newimage();
_firerd = newimage();
FIREDOOR0 = newimage();
FIREDOOR1 = newimage();
FIREDOOR2 = newimage();
FIREDOOR3 = newimage();
FIREDOOR4 = newimage();
ICEDOOR0 = newimage();
ICEDOOR1 = newimage();
ICEDOOR2 = newimage();
ICEDOOR3 = newimage();
ICEDOOR4 = newimage();
getimage(succeeded, "res//成功.jpg");
getimage(_dead, "res//死亡.jpg");
getimage(_explanation, "res//游戏说明.jpg");
getimage(lift, "res//升降台.png");
getimage(SWITCH, "res//地面机关.png");
getimage(_enter, "res//进入界面.jpg");
getimage(_back1, "res//地图.jpg");
getimage(_barrier1, "res//游戏关卡1.png");
getimage(_back2, "res//关于我们的游戏.jpg");
getimage(_start, "res//开始按钮.png");
getimage(_explanationbt, "res//游戏说明.png");
getimage(_about, "res//关于我们.png");
getimage(_icestill, "res//冰娃静.png");
getimage(_iceup, "res//冰娃上.png");
getimage(_icedown, "res//冰娃下.png");
getimage(_iceright, "res//冰娃右.png");
getimage(_iceleft, "res//冰娃左.png");
getimage(_icelu, "res//冰娃左上.png");
getimage(_iceru, "res//冰娃右上.png");
getimage(_iceld, "res//冰娃左下.png");
getimage(_icerd, "res//冰娃右下.png");
getimage(_firestill, "res//火娃静.png");
getimage(_fireup, "res//火娃上.png");
getimage(_firedown, "res//火娃下.png");
getimage(_fireright, "res//火娃右.png");
getimage(_fireleft, "res//火娃左.png");
getimage(_firelu, "res//火娃左上.png");
getimage(_fireru, "res//火娃右上.png");
getimage(_fireld, "res//火娃左下.png");
getimage(_firerd, "res//火娃右下.png");
getimage(FIREDOOR0, "res//火门0.png");
getimage(FIREDOOR1, "res//火门1.png");
getimage(FIREDOOR2, "res//火门2.png");
getimage(FIREDOOR3, "res//火门3.png");
getimage(FIREDOOR4, "res//火门4.png");
getimage(ICEDOOR0, "res//冰门0.png");
getimage(ICEDOOR1, "res//冰门1.png");
getimage(ICEDOOR2, "res//冰门2.png");
getimage(ICEDOOR3, "res//冰门3.png");
getimage(ICEDOOR4, "res//冰门4.png");
//地板横坐标
floor[0][1].x1 = 36, floor[0][1].x2 = 369;
floor[0][2].x1 = 974, floor[0][2].x2 = 1019;
floor[0][3].x1 = 1010, floor[0][3].x2 = 1060;
floor[0][4].x1 = 36, floor[0][4].x2 = 505;
floor[0][5].x1 = 446, floor[0][5].x2 = 919;
floor[0][6].x1 = 148, floor[0][6].x2 = 575;
floor[0][7].x1 = 508, floor[0][7].x2 = 1060;
floor[0][8].x1 = 36, floor[0][8].x2 = 179;
floor[0][9].x1 = 235, floor[0][9].x2 = 949;
floor[0][10].x1 = 532, floor[0][10].x2 = 730;
floor[0][11].x1 = 277, floor[0][11].x2 = 430;
floor[0][12].x1 = 318, floor[0][12].x2 = 393;
floor[0][13].x1 = 430, floor[0][13].x2 = 1060;
floor[0][14].x1 = 0, floor[0][14].x2 = 235;
floor[0][15].x1 = 10, floor[0][15].x2 = 205;
floor[0][16].x1 = 730, floor[0][16].x2 = 810;
//地板纵坐标
floor[0][1].y1 = 605, floor[0][1].y2 = 620;
floor[0][2].y1 = 655, floor[0][2].y2 = 670;
floor[0][3].y1 = 609, floor[0][3].y2 = 624;
floor[0][4].y1 = 508, floor[0][4].y2 = 523;
floor[0][5].y1 = 553, floor[0][5].y2 = 568;
floor[0][6].y1 = 380, floor[0][6].y2 = 395;
floor[0][7].y1 = 408, floor[0][7].y2 = 423;
floor[0][8].y1 = 196, floor[0][8].y2 = 211;
floor[0][9].y1 = 284, floor[0][9].y2 = 299;
floor[0][10].y1 = 250, floor[0][10].y2 = 265;
floor[0][11].y1 = 151, floor[0][11].y2 = 166;
floor[0][12].y1 = 108, floor[0][12].y2 = 123;
floor[0][13].y1 = 151, floor[0][13].y2 = 166;
floor[0][14].y1 = 196, floor[0][14].y2 = 211;
floor[0][15].y1 = 368, floor[0][15].y2 = 383;
floor[0][16].y1 = 240, floor[0][16].y2 = 299;
//顶板横坐标
roof[0][1].x1 = 36, roof[0][1].x2 = 369;
roof[0][2].x1 = 36, roof[0][2].x2 = 505;
roof[0][3].x1 = 446, roof[0][3].x2 = 919;
roof[0][4].x1 = 148, roof[0][4].x2 = 508;
roof[0][5].x1 = 535, roof[0][5].x2 = 948;
roof[0][6].x1 = 982, roof[0][6].x2 = 1060;
roof[0][7].x1 = 36, roof[0][7].x2 = 776;
roof[0][8].x1 = 777, roof[0][8].x2 = 948;
roof[0][9].x1 = 277, roof[0][9].x2 = 433;
roof[0][10].x1 = 433, roof[0][10].x2 = 1060;
roof[0][11].x1 = 0, roof[0][11].x2 = 1060;
//顶板纵坐标
roof[0][1].y1 = 618, roof[0][1].y2 = 633;
roof[0][2].y1 = 516, roof[0][2].y2 = 534;
roof[0][3].y1 = 569, roof[0][3].y2 = 584;
roof[0][4].y1 = 393, roof[0][4].y2 = 408;
roof[0][5].y1 = 420, roof[0][5].y2 = 435;
roof[0][6].y1 = 460, roof[0][6].y2 = 475;
roof[0][7].y1 = 300, roof[0][7].y2 = 315;
roof[0][8].y1 = 310, roof[0][8].y2 = 325;
roof[0][9].y1 = 177, roof[0][9].y2 = 192;
roof[0][10].y1 = 162, roof[0][10].y2 = 177;
roof[0][11].y1 = 30, roof[0][11].y2 = 45;
//左墙壁横坐标
wallleft[0][1].x = 369; wallleft[0][2].x = 505;
wallleft[0][3].x = 919; wallleft[0][4].x = 575;
wallleft[0][5].x = 949; wallleft[0][6].x = 235;
//左墙壁纵坐标
wallleft[0][1].y1 = 617, wallleft[0][1].y2 = 621;
wallleft[0][2].y1 = 496, wallleft[0][2].y2 = 520;
wallleft[0][3].y1 = 565, wallleft[0][3].y2 = 572;
wallleft[0][4].y1 = 368, wallleft[0][4].y2 = 392;
wallleft[0][5].y1 = 297, wallleft[0][5].y2 = 313;
wallleft[0][6].y1 = 268, wallleft[0][6].y2 = 272;
//右墙壁横坐标
wallright[0][1].x = 974; wallright[0][2].x = 948;
wallright[0][3].x = 508; wallright[0][4].x = 148;
wallright[0][5].x = 532; wallright[0][6].x = 277;
//右墙壁纵坐标
wallright[0][1].y1 = 667, wallright[0][1].y2 = 687;
wallright[0][2].y1 = 447, wallright[0][2].y2 = 460;
wallright[0][3].y1 = 420, wallright[0][3].y2 = 423;
wallright[0][4].y1 = 392, wallright[0][4].y2 = 396;
wallright[0][5].y1 = 262, wallright[0][5].y2 = 272;
wallright[0][6].y1 = 163, wallright[0][6].y2 = 180;
}
//判断火门
int judgefiredoor(double X, double Y)
{
for (int cnt = 0; cnt < 100; cnt++)
{
if (X + widthleft >= FIREDOORX && X + widthleft <= FIREDOORX + DOORWIDTH)
if (Y + lengthdown - 50 <= FIREDOORY + DOORHEIGHT)
return 1;
}
return 0;
}
//判断冰门
int judgeicedoor(double X, double Y)
{
for (int cnt = 0; cnt < 100; cnt++)
{
if (X + widthleft >= ICEDOORX && X + widthleft <= ICEDOORX + DOORWIDTH)
if (Y + lengthdown - 50 <= ICEDOORY + DOORHEIGHT)
return 1;
}
return 0;
}
//判断冰面
int judgeicefloor(double X, double Y)
{
if (X + widthleft <= 630 && X + widthright >= 545 && Y + lengthdown - pianyi >= 685)return 1;
return 0;
}
//判断d面
int judgepoisonfloor(double X, double Y)
{
if (X + widthleft >= 695 && X + widthright <= 815 && Y + lengthdown - pianyi >= 540 && Y + lengthdown - pianyi <= 568) return 1;
return 0;
}
int judgeswitch(double X, double Y)
{
if (X + widthleft >= 301 && X + widthright <= 337 && Y + lengthdown - pianyi >= 508 && Y + lengthdown - pianyi <= 523)return 1;
return 0;
}
//判断火面
int judgefirefloor(double X, double Y)
{
if (X + widthleft <= 864 && X + widthright >= 770 && Y + lengthdown - pianyi >= 685) return 1;
return 0;
}
//判断是否在地面或斜面上
int judgefloor(double X, double Y, int i, double V)
{
for (int cnt = 0; cnt < 50; cnt++)
{
if (X + widthleft >= floor[i][cnt].x1 && X + widthright <= floor[i][cnt].x2 && Y + lengthdown - pianyi >= floor[i][cnt].y1 && Y + lengthdown - pianyi <= floor[i][cnt].y2)
return 1;
}
if (V <= 0)
for (int cnt = 50; cnt < 75; cnt++)
{
if (X + widthleft >= floor[i][cnt].x1 && X + widthright <= floor[i][cnt].x2 && Y + lengthdown - pianyi >= floor[i][cnt].y1 && Y + lengthdown - pianyi <= floor[i][cnt].y2)
return 1;
}
if (V >= 0)
for (int cnt = 75; cnt < 100; cnt++)
{
if (X + widthleft >= floor[i][cnt].x1 && X + widthright <= floor[i][cnt].x2 && Y + lengthdown - pianyi >= floor[i][cnt].y1 && Y + lengthdown - pianyi <= floor[i][cnt].y2)
return 1;
}
return 0;
}
//判断是否会撞顶面
int judgeroof(double X, double Y, int i)
{
for (int cnt = 0; cnt < 100; cnt++)
{
if (X + widthright >= roof[i][cnt].x1 && X + widthleft <= roof[i][cnt].x2 && Y + lengthup - pianyi >= roof[i][cnt].y1 && Y + lengthup - pianyi <= roof[i][cnt].y2)
return 1;
}
return 0;
}
//判断是否撞左墙
int judegewall_left(double X, double Y, int i)
{
for (int cnt = 0; cnt < 100; cnt++)
{
if (X + widthleft - wallleft[i][cnt].x <= 10 && X + widthleft - wallleft[i][cnt].x >= -40)
if (Y + lengthup <= wallleft[i][cnt].y2 && Y + lengthdown >= wallleft[i][cnt].y1)
return 1;
}
return 0;
}
//判断是否撞右墙
int judegewall_right(double X, double Y, int i)
{
for (int cnt = 0; cnt < 100; cnt++)
{
if (wallright[i][cnt].x - (X + widthright) <= 10 && wallright[i][cnt].x - (X + widthright) >= -40)
if (Y + lengthup <= wallright[i][cnt].y2 && Y + lengthdown >= wallright[i][cnt].y1)
return 1;
}
return 0;
}
//冰火娃在正常地面与岩浆中的跑动速度与加速度关系
void run(double* VX, double* VY, double X, double Y)
{
if (1) //正常地面
{
if (*VX > 0)
{
if (*VX - ax_normal >= 0)
*VX -= time * ax_normal;
else *VX = 0;
}
if (*VX < 0)
{
if (*VX + ax_normal <= 0)
*VX += time * ax_normal;
else *VX = 0;
}
if ((judgefloor(X, Y, 0, *VX) == 1 && (*VY < -5) || (*VY == 0)) || (judgefloor(X, Y, 0, *VX) == 0))
{
*VY += ay * time;
}
else *VY = 0;
if ((judgeroof(X, Y, 0) == 1) && (*VY < 0))
{
*VY = 0;
}
}
}
//冰火娃在正常地面与晶体上的跑动速度与路程关系
void svrelation(double* VX, double* VY, double* X, double* Y)
{
*X += *VX * time;
*Y += *VY * time;
if (*VX != 0)*Y -= 1.5;
else *Y -= 1.0 / 6;
}
//人物图片变换
void changepeople()
{
int modex = 0, modey = 0;
//冰娃图片切换,规定左 -1,右 1,上 1,下 -1
if (GetAsyncKeyState('A') & 0x8000)
{
modex--;
if (icex + widthleft >= edgeleft)
{
if (judegewall_left(icex, icey, 0) == 0)
icevx = -vx;
}
else icevx = 0;
}
if (GetAsyncKeyState('D') & 0x8000)
{
modex++;
if (icex + widthright <= edgeright)
{
if (judegewall_right(icex, icey, 0) == 0)
icevx = vx;
}
else icevx = 0;
}
if (GetAsyncKeyState('W') & 0x8000)
{
modey++;
if (judgefloor(icex, icey, barrier, icevx) == 1)
{
icevy = -vy;
}
}
if (GetAsyncKeyState('S') & 0x8000)
{
modey--;
}
//九个动作情况
if (modex == 0 && modey == -1)
{
putimage_withalpha(NULL, _icedown, int(icex), int(icey));
}
if (modex == 1 && modey == 0)
{
putimage_withalpha(NULL, _iceright, int(icex), int(icey));
}
if (modex == -1 && modey == 0)
{
putimage_withalpha(NULL, _iceleft, int(icex), int(icey));
}
if (modex == 1 && modey == -1)
{
putimage_withalpha(NULL, _icerd, int(icex), int(icey));
}
if (modex == -1 && modey == -1)
{
putimage_withalpha(NULL, _iceld, int(icex), int(icey));
}
if (modex == 1 && modey == 1)
{
putimage_withalpha(NULL, _iceru, int(icex), int(icey));
}
if (modex == -1 && modey == 1)
{
putimage_withalpha(NULL, _icelu, int(icex), int(icey));
}
if (modex == 0 && modey == 1)
{
putimage_withalpha(NULL, _iceup, int(icex), int(icey));
}
if (modex == 0 && modey == 0)
{
putimage_withalpha(NULL, _icestill, int(icex), int(icey));
}
modex = 0;
modey = 0;
//火娃图片切换,规定左 -1,右 1,上 1,下 -1
if (GetAsyncKeyState(VK_LEFT) & 0x8000)
{
modex--;
if (firex + widthleft >= edgeleft)
{
if (judegewall_left(firex, firey, 0) == 0)
firevx = -vx;
}
else firevx = 0;
}
if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
{
modex++;
if (firex + widthright <= edgeright)
{
if (judegewall_right(firex, firey, 0) == 0)
firevx = vx;
}
else firevx = 0;
}
if (GetAsyncKeyState(VK_UP) & 0x8000)
{
modey++;
if (judgefloor(firex, firey, barrier, firevx) == 1)
{
firevy = -vy;
}
}
if (GetAsyncKeyState(VK_DOWN) & 0x8000)
{
modey--;
}
//九个动作情况
if (modex == 0 && modey == -1)
{
;
putimage_withalpha(NULL, _firedown, firex, firey);
}
if (modex == 1 && modey == 0)
{
putimage_withalpha(NULL, _fireright, firex, firey);
}
if (modex == -1 && modey == 0)
{
putimage_withalpha(NULL, _fireleft, firex, firey);
}
if (modex == 1 && modey == -1)
{
putimage_withalpha(NULL, _firerd, firex, firey);
}
if (modex == -1 && modey == -1)
{
putimage_withalpha(NULL, _fireld, firex, firey);
}
if (modex == 1 && modey == 1)
{
putimage_withalpha(NULL, _fireru, firex, firey);
}
if (modex == -1 && modey == 1)
{
putimage_withalpha(NULL, _firelu, firex, firey);
}
if (modex == 0 && modey == 1)
{
putimage_withalpha(NULL, _fireup, firex, firey);
}
if (modex == 0 && modey == 0)
{
putimage_withalpha(NULL, _firestill, firex, firey);
}
}
void map1()
{
msg = { 0 };
for (; is_run(); delay_fps(60))
{
cleardevice();
putimage(0, 0, _barrier1);
if (firedoormode && judgefiredoor(firex, firey) == 1)
{
if (firedoormode > 18)
putimage_withalpha(NULL, FIREDOOR3, FIREDOORX, FIREDOORY);
else if (firedoormode > 12)
putimage_withalpha(NULL, FIREDOOR2, FIREDOORX, FIREDOORY);
else if (firedoormode > 6)
putimage_withalpha(NULL, FIREDOOR1, FIREDOORX, FIREDOORY);
else
putimage_withalpha(NULL, FIREDOOR0, FIREDOORX, FIREDOORY);
if (firedoormode > 1 && judgefiredoor(firex, firey)) firedoormode--;
}
if (judgefiredoor(firex, firey) == 0) firedoormode = 24;
if (icedoormode && judgeicedoor(icex, icey) == 1)
{
if (icedoormode > 18)
putimage_withalpha(NULL, ICEDOOR3, ICEDOORX, ICEDOORY);
else if (icedoormode > 12)
putimage_withalpha(NULL, ICEDOOR2, ICEDOORX, ICEDOORY);
else if (icedoormode > 6)
putimage_withalpha(NULL, ICEDOOR1, ICEDOORX, ICEDOORY);
else
putimage_withalpha(NULL, ICEDOOR0, ICEDOORX, ICEDOORY);
if (icedoormode > 1 && judgeicedoor(icex, icey)) icedoormode--;
}
if (judgeicedoor(icex, icey) == 0) icedoormode = 24;
changepeople();
run(&firevx, &firevy, firex, firey);
run(&icevx, &icevy, icex, icey);
svrelation(&firevx, &firevy, &firex, &firey);
svrelation(&icevx, &icevy, &icex, &icey);
// xyprintf(0, 0, "X=%4d Y=%4d MSG=%4d FLAG=%4d", msg.x, msg.y, msg.msg, msg.flags);
putimage_withalpha(NULL, SWITCH, 260, 460);
putimage_withalpha(NULL, lift, 30, lifty);
if (judgeicedoor(icex, icey) && judgefiredoor(firex, firey))
{
while (1)
{
while (mousemsg())
{
msg = getmouse();
}
if (msg.msg == 16)return;
putimage(0, 0, succeeded);
datainitial();
}
}
if (judgeswitch(firex, firey) + judgeswitch(icex, icey) > 0 && lifty <= 450)
{
floor[0][15].y1++; floor[0][15].y2++; lifty++;
}
if (judgeicefloor(firex, firey) || judgepoisonfloor(firex, firey) || judgepoisonfloor(icex, icey) || judgefirefloor(icex, icey))
{
while (1)
{
while (mousemsg())
{
msg = getmouse();
}
if (msg.msg == 16)return;
putimage(0, 0, _dead);
datainitial();
}
}
//xyprintf(0, 0, "\nfirevy=%10.10lf ", firevy);
// if (msg.flags == 1)return;
}
}
//游戏主地图界面
void mapmain()
{
msg = { 0 };
while (1)
{
for (; msg.msg != 16; delay_fps(60))
{
while (mousemsg())
{
msg = getmouse();
}
putimage(0, 0, _back1);
}
map1();
msg = { 0 };
}
}
void explanation()
{
msg = { 0 };
for (; is_run(); delay_fps(60))
{
while (mousemsg())
{
msg = getmouse();
}
putimage(0, 0, _explanation);
if (msg.flags == 1) return;
}
}
//关于我们游戏界面
void about()
{
msg = { 0 };
for (; is_run(); delay_fps(60))
{
while (mousemsg())
{
msg = getmouse();
}
putimage(0, 0, _back2);
if (msg.flags == 1) return;
}
}
//加载进入界面,地图,游戏关卡背景
void welcome()
{
msg = { 0 };
for (; is_run(); delay_fps(60))
{
while (mousemsg())
{
msg = getmouse();
}
cleardevice();
putimage(0, 0, _enter);
if (msg.x >= 425 && msg.x <= 645)
{
if (msg.y >= 430 && msg.y <= 480)
{
putimage_withalpha(NULL, _start, 380, 405);
if (msg.flags == 1)
{
mapmain();
}
}
else if (msg.y >= 540 && msg.y <= 590)
{
putimage_withalpha(NULL, _explanationbt, 385, 517);
if (msg.flags == 1)
{
explanation();
//msg = { 0 };
}
}
else if (msg.y >= 650 && msg.y <= 700)
{
putimage_withalpha(NULL, _about, 380, 623);
if (msg.flags == 1)
{
about();
}
}
}
//xyprintf(0, 0, "X=%4d Y=%4d MSG=%4d FLAG=%4d", msg.x, msg.y, msg.msg, msg.flags);
}
}
//控制台函数,调节逻辑关系
void operate()
{
firex = initial_firex[0];
firey = initial_firey[0];
icex = initial_icex[0];
icey = initial_icey[0];
msg = { 0 };
for (; is_run(); delay_fps(60))
{
while (mousemsg())
{
msg = getmouse();
}
cleardevice();
welcome();
}
}
int main()
{
initgraph(1100, 740);
setcaption("森林冰火人");
initial();
// mouse();
operate();
return 0;
}
效果
素材
其实我想把图片素材一起发上来,但好像不太会。。。以后我再研究研究。