6.游戏前的准备

HJ Lv2

6.游戏前的准备

以下是主函数代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main() {
initgraph(WIN_WEIDTH, WIN_HEIGHT);
loadPicGroup();
logIn();
//以上内容前面已经介绍
zombielist = creatZombielist();
peaslist = creatPeasList();
putPlant();
//这篇内容介绍以上三个部分

gameStart();
compearScore(credit);

closegraph();
}

在正式游戏开始之前,我们需要初始化一些数据,例如随机放置植物,僵尸的创建,豌豆链表的创建等。

6.1随机放置植物

我们都知道,植物大战僵尸拥有五行单元格,根据游戏规则和为了加强游戏可玩性,我们需要在每行放置至少一个豌豆射手。
先给出我的代码

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
void addPlant(int cellx, int celly, int type, int x, int y) {
zb[cellx][celly] = type;
newplant[cellx * 5 + celly].gx = cellx + 1;
newplant[cellx * 5 + celly].gy = celly + 1;
newplant[cellx * 5 + celly].type = type;
newplant[cellx * 5 + celly].indexnum = indexnum[type];
newplant[cellx * 5 + celly].hp = planthp[type];
newplant[cellx * 5 + celly].x = x;
newplant[cellx * 5 + celly].y = y;
newplant[cellx * 5 + celly].nowpic = 1;
}
void putPlant() {
srand(time(NULL));
int sunflowerCount = 0;
for (int j = 0; j < 5; j++) {
// 为每一列分配一个豌豆射手
int peashooterRow = rand() % 3;
addPlant(peashooterRow, j, 2, cur_x + cur_Width * peashooterRow, cur_y + cur_Height * j);
for (int i = 0; i < 3; i++) {
if (i != peashooterRow) {
if (sunflowerCount < 9 && (sunflowerCount < 5 || rand() % 2 == 1)) {
addPlant(i, j, 1, cur_x + cur_Width * i, cur_y + cur_Height * j);
sunflowerCount++;
}
else {
addPlant(i, j, 2, cur_x + cur_Width * i, cur_y + cur_Height * j);
}
}
}
}
}

我们主要看putPlant这个函数
这个函数的作用是随机放置植物,具体来说,是在在一个3行5列的网格中随机放置植物。每行放置一个豌豆射手在随机选择的列。其他列按照一定规则随机选择放置向日葵或豌豆射手,直到向日葵数量达到9个。下面是代码的详细解释和功能分析。
这段代码首先初始化随机数生成器。srand 函数用系统当前时间作为种子,确保每次运行程序时产生的随机数序列不同。
其次声明一个整型变量 sunflowerCount 来计数已经放置的向日葵数量。
随后

1
for (int j = 0; j < 5; j++) 

开始一个循环,对于5行中的每一行进行操作。

1
int peashooterRow = rand() % 3;

随机选择一个列(0到2之间)来放置豌豆射手。
随后使用

1
addPlant(peashooterRow, j, 2, cur_x + cur_Width * peashooterRow, cur_y + cur_Height * j);

在选定的行和当前列放置一个豌豆射手。addPlant 函数的参数依次表示行、列、植物类型(2代表豌豆射手),以及植物应放置的坐标。

1
for (int i = 0; i < 3; i++) {

遍历每行的每一列:

1
if (i != peashooterRow) {

如果当前列不是豌豆射手所在的列。

1
2
3
              if (sunflowerCount < 9 && (sunflowerCount < 5 || rand() % 2 == 1)) {
addPlant(i, j, 1, cur_x + cur_Width * i, cur_y + cur_Height * j);
sunflowerCount++;

如果已放置的向日葵少于9个,并且随机计数是向日葵或者向日葵少于5个,则在当前行列放置一个向日葵(类型1)。增加已放置向日葵的计数。这里保证了向日葵数量最少是5个

如果不放置向日葵,则在当前行列放置另一个豌豆射手。

1
addPlant(i, j, 2, cur_x + cur_Width * i, cur_y + cur_Height * j);

6.2僵尸的创建,豌豆链表的创建

游戏开始之前,我们需要创建豌豆节点,以便在游戏时进行豌豆的发射。此外,我们还需要创建僵尸结构体变量。
对于

1
2
zombielist = creatZombielist();
peaslist = creatPeasList();

我们在前面已经说过zombielist和peaslist都为结构体指针类型的数据,
具体请移步2.主函数的设计
下面是具体的代码实现部分

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
zombie* creatZombielist() {
zombielist = (zombie*)malloc(sizeof(zombie));//每次游戏开始前创建僵尸和豌豆链表
zombielist->status = 1;//初始为走路状态
zombielist->hp = 150;//初始血量150
zombielist->x = 330;
zombielist->y = 230;
zombielist->gx = 9;//要求在第九列第三行的位置初始放置一个僵尸
zombielist->gy = 3;
zombielist->indexnumofwalk = 21;
zombielist->indexnumofattack = 20;
zombielist->nowpicofwalk = 1;
zombielist->nowpicofattack = 1;
zombielist->speed = 2;
zombielist->zombieattack = 2;
return zombielist;
}

peas* creatPeasList() {
peas* head = (peas*)malloc(sizeof(peas));
if (head == NULL) {
// 处理内存分配失败的情况
return NULL;
}
head->x = 0;
head->y = 0;
head->gx = 0;
head->gy = 0;
head->next = NULL;
head->status = -100; //头结点初设值设为-100,表示为头结点无数据,以后会用到
return head;
}

以上具体参数在前面文章均有详细说明,在此不做过多赘述。
这样我们就创建了僵尸和豌豆数据。