2.数据结构说明和通用函数设计

HJ Lv2

开始

在开始之前,我先放上我的数据结构设计以及通用函数的定义,在将来方便查找。每个内容我都有注释,当然,如果暂时不知道什么意思没有关系,在以后的的文章中我会在涉及到的地方进行介绍.


此外,我们还要做一些visual studio的设置:
1.点击菜单栏的项目->属性->高级->字符集,将字符集改为使用多字节字符集;
2.项目->属性->C/C++->SDL检查,改为否。

数据设计

常量设计

首先定义常量数据

1
2
3
4
5
6
7
8
9
10
11
12
#define MAX_INPUT_LENGTH 12	//用户名密码最大输入长度
#define BUTTON_HEIGHT 39 //按钮高度
#define BUTTON_WEIDTH 166 //按钮宽度
#define WIN_WEIDTH 800 //窗口高度
#define WIN_HEIGHT 600 //窗口宽度
#define cur_Height 100 //草坪高度
#define cur_Width 81 //草坪宽度
#define Pea_offset 90 //豌豆发射x坐标到单元格左边的长度
#define cur_x 37 //背景左偏移
#define cur_y 84 //背景上偏移
#define zombiepngedge 64 //僵尸图片左空白
#define zombiewidth 78 //僵尸宽度

以上是本程序设计所需的常量定义

结构体设计

注意,如无特殊说明,以下内容hp均代表当前血量,x,y均代表坐标值(单位:像素),gx,gy均代表单元格坐标,indexnum(of…)代表渲染动画时图片总张数,nowpic(of…)代表当前的位于第几张图片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
typedef struct ListNode {			//用户信息链表
char username[30];
char password[30];
struct ListNode* next;
} ListNode;

typedef struct peas { //豌豆
int status; //状态,1正在飞行,0已经消失
int x,y;
int gx,gy;
struct peas* next;
} peas;

typedef struct zombie { //僵尸
int status = 1; //1为正在走路,2为正在吃植物,0为死亡
int hp;
int type; //1普通僵尸,2路障僵尸,3铁桶僵尸
int x,y;
int gx,gy;
int indexnumofwalk=21;
int indexnumofattack=20;
int nowpicofwalk = 1;
int nowpicofattack = 1;
int speed; //僵尸移动速度
int zombieattack; //僵尸攻击力
} zombie;

typedef struct plants { //植物
int type; //植物种类,1向日葵,2豌豆射手
int x,y;
int gx,gy;
int hp = 80;
int indexnum = 14;
int nowpic = 1;
} plants;

变量设计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//登录相关
ListNode* user; //用户信息链表
int type = 3; //登录时用的判断点击是用户名输入区域还是密码输入区域
CHAR username[MAX_INPUT_LENGTH + 1] = ""; //用户名输入信息
CHAR password[MAX_INPUT_LENGTH + 1] = ""; //密码输入的信息
int text_lengthuser = 0; //当前用户名长度
int text_lengthpass = 0; //当前密码长度

//图片相关
IMAGE picgroup[20]; //图片
IMAGE peashooterz[13]; //豌豆射手图片组
IMAGE sunflowerz[18]; //太阳花图片组
IMAGE zombiez[22]; //僵尸走路时图片组
IMAGE attackz[21]; //僵尸攻击时的图片组

//游戏相关
int credit = 300; //初始积分
int stime = 60; //游戏时间
bool ispause = false; //是否暂停游戏

//信息
Plants newplant[16]; //每个植物的信息
int zb[10][5] = { 0 }; //存放植物信息,0无植物,1向日葵,2豌豆射手
int planthp[3] = { 0,80,80 }; //不同植物的血量
int peashooterattack = 5; //豌豆攻击力
zombie* zombielist; //僵尸信息
peas* peaslist; //豌豆链表

通用函数设计

在游戏的设计中,我们会频繁使用文字的绘制以及绘制透明图片,对于前者,如果每次绘制文字都设置文字样式会显得代码稍微繁琐,那么我们就可能需要一个通用的文字绘制函数来集成文字绘制的各种功能。对于后者,没有现成的函数可用,这就需要我们自定义函数实现透明图的绘制。

文字的绘制

1
2
3
4
5
6
7
8
9
10
11
void PutL(int x, int y, const char font[], int size, COLORREF color, const char content[]) {
LOGFONT f;
gettextstyle(&f);
f.lfHeight = size;
_tcscpy(f.lfFaceName, font);
f.lfQuality = ANTIALIASED_QUALITY;
settextstyle(&f);
setbkmode(TRANSPARENT);
settextcolor(color);
outtextxy(x, y, content);
}

对于以上函数
x,y表示文字绘制的xy坐标。
font表示需要绘制的文字字体。
size表示文字大小。
color表示文字颜色。
content表示文字内容。

PNG透明图的绘制

用到两个自定义函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
void drawAlpha(int  picture_x, int picture_y, IMAGE* picture) 
{
DWORD* dst = GetImageBuffer();
DWORD* draw = GetImageBuffer();
DWORD* src = GetImageBuffer(picture);
int picture_width = picture->getwidth();
int picture_height = picture->getheight();
int graphWidth = getwidth();
int graphHeight = getheight();
int dstX = 0;

for (int iy = 0; iy < picture_height; iy++)
{
for (int ix = 0; ix < picture_width; ix++)
{
int srcX = ix + iy * picture_width;
int sa = ((src[srcX] & 0xff000000) >> 24);
int sr = ((src[srcX] & 0xff0000) >> 16);
int sg = ((src[srcX] & 0xff00) >> 8);
int sb = src[srcX] & 0xff;
if (ix >= 0 && ix <= graphWidth && iy >= 0 && iy <= graphHeight && dstX <= graphWidth * graphHeight)
{
dstX = (ix + picture_x) + (iy + picture_y) * graphWidth;
int dr = ((dst[dstX] & 0xff0000) >> 16);
int dg = ((dst[dstX] & 0xff00) >> 8);
int db = dst[dstX] & 0xff;
draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16)
| ((sg * sa / 255 + dg * (255 - sa) / 255) << 8)
| (sb * sa / 255 + db * (255 - sa) / 255);
}
}
}
}

这个函数表示绘制png图片,其中:
picture_x,picture_y表示绘制的坐标。
picture表示图片资源(在后续文章会讲到)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void putimagePNG(int x, int y, IMAGE* picture) {
IMAGE imgTmp, imgTmp2, imgTmp3;
int winWidth = getwidth();
int winHeight = getheight();
if (y < 0) {
SetWorkingImage(picture);
getimage(&imgTmp, 0, -y,
picture->getwidth(), picture->getheight() + y);
SetWorkingImage();
y = 0;
picture = &imgTmp;
}
else if (y >= getheight() || x >= getwidth()) {
return;
}
else if (y + picture->getheight() > winHeight) {
SetWorkingImage(picture);
getimage(&imgTmp, x, y, picture->getwidth(), winHeight - y);
SetWorkingImage();
picture = &imgTmp;
}
if (x < 0) {
SetWorkingImage(picture);
getimage(&imgTmp2, -x, 0, picture->getwidth() + x, picture->getheight());
SetWorkingImage();
x = 0;
picture = &imgTmp2;
}
if (x > winWidth - picture->getwidth()) {
SetWorkingImage(picture);
getimage(&imgTmp3, 0, 0, winWidth - x, picture->getheight());
SetWorkingImage();
picture = &imgTmp3;
}
drawAlpha(x, y, picture);
}

这个函数用于处理图片越界问题,参数同上。