这个小游戏设计起来不难,之所以做他的目的是,一天老师给我了个他很早以前写的2D库,让我去使用这个库完成一个小游戏,这个过程的意义再去让我一个以前从未用过别人手写库的学生,了解到了库的设计结构,和如果好的使用别人的库去完成任务,虽然编程难度不大,但是意义深刻,至少知道了以后遇见别人的库是怎么使用,而不会手忙脚乱。
同时让我了解了游戏制作时的一些小方法如掩码的使用,和图像渲染的步骤,分层渲染的意义以及当有多函数具有同样功能和机构时,我们需要尽可能的去合并函数,这里指的就是上下左右的移动,因为观察到很多网上的博客里面都是四个方向每一个方向一个函数,所以我觉得我这里展示出来还有有一点意义的(一点点)。好了接下来就是代码显示了,请各位看官多多雅正
哦对了,在这我把我老师的2D库github放出来,有需要的话可以自取,我的老师也很欢迎大家共同学习,网站上有各个api的试例,很简单上手—》2D库链接
还有一件事就是,应为代码比较短,我懒得划分文件了,我写在了同一个文件中(这是不对的做法,切勿学习),但是虽然我在一个文件中写的,但是我写的方式还是按照划分模块的方式去完成,通过调用各个接口完成任务,没有直接放在全局变量里,还有一点就是有一些函数可能会毫无作用,甚至莫名其妙,这个当时是为了日后改进预留的接口,例如使用文件去存储每个关卡的地图信息等,但是因为有一些别的任务,所以一直耽搁了,在这我就先不完成了,麻烦原谅。所以目前是一个单关卡地图的推箱子
代码中需要注意的地方就是,比如图片和文字资源你需要自己上网下载,在这我就不一一上传了,谢谢。其中如地图的设计方法,就是我根据游戏画面的多层渲染的方式,结合自己的理解设计的,并没有直接放箱子和果实以及人的信息直接存放到map数组中,这只是我自己理解的一种设计方式,至于对不对就仁者见仁了。
#include
#include
#include
#include
#include
#include "GLMXSDK/ZYFEasy2D.h"
#define grass 0
#define wall 1
#define way 2
#define target 3
#define box 4
#define man 5
struct Pos
{
int x, y;
};
struct Position
{
Pos pos[8][8];
};
struct Target
{
int x, y;
bool is_occupy;
};
struct Box
{
int x, y;
};
struct Man
{
bool game_over;
int x, y;
};
struct Position postion;
Target *tar = NULL;
Box *boxs = NULL;
Man *m = NULL;
int map[8][8] =
{
{grass,grass,grass,grass,grass,grass,grass,grass},
{grass,wall,wall,wall,wall,wall,grass,grass},
{wall,wall,way,way,way,wall,wall,grass},
{wall,way,way,way,way,way,wall,grass},
{wall,way,way,way,way,way,wall,grass},
{wall,way,way,way,way,way,wall,grass},
{wall,wall,way,way,way,wall,wall,grass},
{grass,wall,wall,wall,wall,wall,grass,grass},
};
void init_map()
{
int x = 0;
int y = 0;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
postion.pos[i][j].x = x;
postion.pos[i][j].y = y;
x += 64;
}
x = 0;
y += 64;
}
}
int get_target_num();
void init_info()
{
int target_num = 3;
int box_num = target_num;
tar = (Target*)malloc(sizeof(Target)*target_num);
boxs = (Box*)malloc(sizeof(Box)*box_num);
m = (Man*)malloc(sizeof(Man));
tar[0].x = 3;
tar[0].y = 3;
tar[1].x = 4;
tar[1].y = 2;
tar[2].x = 4;
tar[2].y = 3;
for (int i = 0; i < get_target_num(); i++)
tar[i].is_occupy = false;
boxs[0].x = 3;
boxs[0].y = 4;
boxs[1].x = 5;
boxs[1].y = 2;
boxs[2].x = 5;
boxs[2].y = 4;
m->x = 5;
m->y = 3;
m->game_over = false;
}
int get_target_num()
{
return 3;
}
int get_box_num()
{
return 3;
}
struct Target* get_Target(int index)
{
return &tar[index];
}
struct Box* get_Box(int index)
{
return &boxs[index];
}
struct Man* get_man()
{
return m;
}
void release()
{
free(tar);
free(boxs);
free(m);
}
uint32 WALL = 0;
uint32 WAY = 0;
uint32 GRASS = 0;
uint32 MAN = 0;
uint32 BOX = 0;
uint32 TARGET = 0;
uint32 LANGUAGE = 0;
void renderScene()
{
if (get_man()->game_over == true)
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
int x = postion.pos[i][j].x;
int y = postion.pos[i][j].y;
ZYFDrawImage(WALL, x, y);
}
}
ZYFRect rect = { 0, 0, 512, 512 };
ZYFColor color = { 0x00FFFF00 };
ZYFDrawText(LANGUAGE, "game over", rect, color, ZYF_ALIGN_VCENTER | ZYF_ALIGN_CENTER);
}
else
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
int x = postion.pos[i][j].x;
int y = postion.pos[i][j].y;
switch (map[i][j])
{
case grass:ZYFDrawImage(GRASS, x, y); break;
case wall:ZYFDrawImage(WALL, x, y); break;
case way:ZYFDrawImage(WAY, x, y); break;
}
}
}
for (int i = 0; i < get_target_num(); i++)
{
Target *p = get_Target(i);
int x = postion.pos[p->x][p->y].x;
int y = postion.pos[p->x][p->y].y;
ZYFDrawImage(TARGET, x + 16, y + 16);
}
for (int i = 0; i < get_box_num(); i++)
{
Box *p = get_Box(i);
int x = postion.pos[p->x][p->y].x;
int y = postion.pos[p->x][p->y].y;
ZYFDrawImage(BOX, x, y);
}
Man *p = get_man();
int x = postion.pos[p->x][p->y].x;
int y = postion.pos[p->x][p->y].y;
ZYFDrawImage(MAN, x + 13, y);
}
}
void Move(ZYFScancode movedir)
{
int x = get_man()->x;
int y = get_man()->y;
if (movedir == ZYF_SCANCODE_RIGHT) y += 1;
else if (movedir == ZYF_SCANCODE_LEFT) y -= 1;
else if (movedir == ZYF_SCANCODE_DOWN) x += 1;
else if (movedir == ZYF_SCANCODE_UP) x -= 1;
int xx = x;
int yy = y;
Man *m = get_man();
Box *b = NULL;
if (map[x][y] != wall)
{
int how_many_box = 0;
for (int i = 0; i < get_box_num(); i++)
{
Box *q = get_Box(i);
if (x == q->x && y == q->y)
{
b = q;
how_many_box += 1;
if (movedir == ZYF_SCANCODE_RIGHT) yy += 1;
else if (movedir == ZYF_SCANCODE_LEFT) yy -= 1;
else if (movedir == ZYF_SCANCODE_DOWN) xx += 1;
else if (movedir == ZYF_SCANCODE_UP) xx -= 1;
if (map[xx][yy] != wall)
{
for (int j = 0; j < get_box_num(); j++)
{
Box *qq = get_Box(j);
if (xx == qq->x && yy == qq->y)
{
how_many_box += 1;
break;
}
}
}
else
{
how_many_box = 3;
break;
}
}
}
switch (how_many_box)
{
case 0:
m->x = x;
m->y = y; break;
case 1:
b->x = xx;
b->y = yy;
m->x = x;
m->y = y; break;
}
}
}
void keyboard(ZYFKeyEvent event, ZYFScancode sc)
{
Man *p = get_man();
Box *b = NULL;
if (event == ZYF_KEYDOWN)
{
switch (sc)
{
case ZYF_SCANCODE_RIGHT:Move(ZYF_SCANCODE_RIGHT);
break;
case ZYF_SCANCODE_LEFT:Move(ZYF_SCANCODE_LEFT);
break;
case ZYF_SCANCODE_DOWN:Move(ZYF_SCANCODE_DOWN);
break;
case ZYF_SCANCODE_UP:Move(ZYF_SCANCODE_UP);
break;
case ZYF_SCANCODE_SPACE:
init_map();
init_info(); break;
}
}
int complete_num = 0;
for (int i = 0; i < get_target_num(); i++)
{
Target *t = get_Target(i);
for (int j = 0; j < get_box_num(); j++)
{
Box *q = get_Box(i);
if (t->x == q->x && t->y == q->y)
{
complete_num += 1;
break;
}
}
}
if (complete_num == get_target_num())
{
m->game_over = true;
}
}
int main()
{
if (ZYFInit("ZYFEasy2D - Keyboard", 512, 512))
{
GRASS = ZYFLoadImage("./images/grass.png");
WALL = ZYFLoadImage("./images/wall.png");
WAY = ZYFLoadImage("./images/way.png");
BOX = ZYFLoadImage("./images/box.png");
MAN = ZYFLoadImage("./images/man.png");
TARGET = ZYFLoadImage("./images/target.png");
LANGUAGE = ZYFLoadFont("msyhbd.ttc", 55);
assert(WALL != 0);
assert(WAY != 0);
assert(GRASS != 0);
assert(MAN != 0);
assert(BOX != 0);
assert(TARGET != 0);
assert(LANGUAGE != 0);
init_map();
init_info();
ZYFRenderFunc(renderScene);
ZYFKeyboardFunc(keyboard);
ZYFRun();
release();
ZYFRelease();
}
return 0;
}