C语言游戏实战(12):植物大战僵尸(坤版)

慈云数据 2024-05-28 技术支持 25 0

植物大战僵尸

前言:

本游戏使用C语言和easyx图形库编写,通过这个项目我们可以深度的掌握C语言的各种语言特性和高级开发技巧,以及锻炼我们独立的项目开发能力,

在开始编写代码之前,我们需要先了解一下游戏的基本规则和功能:

游戏界面:游戏界面是一个矩形区域,玩家可以在区域内进行植物的放置和铲除等操作

僵尸:僵尸会从游戏界面的右侧向左测移动,靠近植物后会停下来吃植物。

植物:不同的植物有不同的功能,在这里我们可以将植物分为三大类:

1. 生产型植物(如太阳花):这种植物的特点是在一定的时间生产出太阳,以增加太阳的产量。

2.发射型植物(如豌豆射手):这种植物的特点是发射相应类型的子弹,对僵尸产生伤害和特定的效果。

3. 爆炸性植物(火爆辣椒):这种植物的特点是对一定区域的所有僵尸产生高额伤害。(一次性植物)

接下来,我们将通过以下几个步骤来实现这个游戏:

初始化游戏界面。

实现僵尸的创建、僵尸的更新、僵尸吃植物的检测。

实现的植物的放置。

实现植物的功能:

对于生产型植物我们需要写出阳光的生产,以及阳光的收集操作。

对于发射型植物我们需要判断植物是否发射子弹,发射子弹后还需更新子弹、检测子弹与僵尸的碰撞。

对于爆炸型植物,我们需要判断僵尸是否在爆炸范围内,然后杀死在爆炸范围内的僵尸。

1. 初始化游戏界面

我们需要先将游戏地图、卡牌和卡牌槽绘制出来。可以利用Windows自带的画图工具测出游戏地图的位置,从而将这些卡牌和卡牌槽放置到合适的位置。

//地图
putimage(-150, 0, &img);
//卡牌槽
putimagePNG(80, -10, &imgBar);	
//植物卡牌
	for (int i = 0; i  

2.  放置植物

因为需要在这个9*5的草地区域内放置植物,所以我们得计算出每个草方块的位置。我利用画图软件测出每个草方块大约是长81、宽100个像素点。 第一个草方块距离游戏窗口大约101个像素点。

这样就可以得出每个草方块的位置:256 - 150 + col * 81;100 + row * 100 - 15; 

每个植物都有相似的特性,所以我们需要写一个放置植物信息的结构体。然后创建一个5*9的结构体数组,用来表示每个草方块上的植物。

enum {
	WAN_DOU, TAI_YANG, LA_JIAO, KUN_KUN, JIAN_GUO,
	HAN_BING_WAN_DOU, YING_TAO, SAN_TOU_WAN_DOU, PLANT_COUNT
};
struct plant
{
	int type;//植物类型
	int frameIndex;//植物动作帧
	//bool catched;//是否被吃
	int blood;//血量
	int shootTime;//植物子弹的射速
	int timer;//阳光生产的时间
	int x, y;//植物坐标
	bool shoot;//判断植物是否处于发射状态
};
struct plant map[5][9];

 在 Windows 编程中,我们可以利用下面的变量获取鼠标信息。

ExMessage msg;
msg.message
ExMessage msg;
static int status = 0;
if (peekmessage(&msg))//判断有没有消息
{
	if (msg.message == WM_LBUTTONDOWN)//左键按下
	{
        //鼠标是否在卡牌的位置按下
		if (msg.x > 163 && msg.x = 100)
			{
				curPlant = index + 1;
				status = 1;
				curX = msg.x;
				curY = msg.y;
				sunshine -= 100;
			}*/
			curPlant = index + 1;
			status = 1;
			curX = msg.x;
			curY = msg.y;
		}
	}
	else if (msg.message == WM_MOUSEMOVE && status == 1)//鼠标移动
	{
		curX = msg.x;
		curY = msg.y;
	}
	else if (msg.message == WM_LBUTTONUP)//鼠标放下
	{
		if (msg.x > 256 - 150 && msg.x  100 && msg.y  

3. 僵尸

 3.1 创建僵尸

僵尸也是和植物一样需要创建一个结构体存放信息。然后创建一个结构体数组,作为一个僵尸池,当需要创建一个僵尸时,我们就从这个池里取一个未被使用的僵尸。

struct zm
{
	int x, y;//僵尸的坐标
	int frameIndex;//僵尸动作帧
	bool used;//僵尸是否被使用
	int speed;//僵尸每一次移动的位移
	int row;//僵尸所在行
	int blood;//僵尸血量
	bool dead;//僵尸是否死亡
	bool eating;//僵尸是否在吃植物
	bool boom;//僵尸是否被炸死
	int zmSpeed;//僵尸的移动快慢
};
struct zm zms[ZM_MAX];
//找一个可用的僵尸
int i;
for (i = 0; i  

到一定的时间就创建一个僵尸。

void createZM()
{
	if (zmCount >= zmCount_max)
		return;
	static int zmFre = 500;
	static int count = 0;
	
    //控制僵尸的生成快慢
	count++;
	if (count > zmFre)
	{
		count = 0;
		zmFre = 200;
		int i = 0;
		int zmMax = sizeof(zms) / sizeof(zms[0]);
		for (i = 0; i  

3. 2 检测僵尸对植物的伤害检测

僵尸靠近植物就将僵尸置为吃东西的状态,减植物的血量,当植物的血量小于等于0时,就去除植物。

void checkZM2Zhiwu()
{
	char name[64];
	int zCount = sizeof(zms) / sizeof(zms[0]);
	for (int i = 0; i = x1 && x3 100)
		{
			lines[zms[i].row] = 1;
		}
	}
	for (int i = 0; i  20)
				{
					map[i][j].shootTime = 0;
                    //子弹池
					int k;
					for (k = 0; k getwidth() - 10;
						bullets[k].y = zwY + 5;
					}
				}
			}
			
		}
	}
}

4. 2  更新子弹

不断的改变加子弹的横坐标,当子弹出游戏界面时,子弹就被置为未被使用。

以坤坤为例:

void updateBullets_kunkun()
{
	int countMax = sizeof(bullets) / sizeof(bullets[0]);
	for (int i = 0; i  Wide)
			{
				bullets[i].used = false;
			}
		}
	}
}

 4.3 检测子弹对僵尸的伤害

当子弹靠近僵尸时减去僵尸的一定量血量,然后对僵尸造成一定的效果(例如,坤坤子弹的效果是击退僵尸,那么我们只需要更改僵尸的横坐标即可。),最后将子弹置为未被使用。

以坤坤为例:

void checkBullet2Zm_kunkun()
{
	int bCount = sizeof(bullets) / sizeof(bullets[0]);
	int zCount = sizeof(zms) / sizeof(zms[0]);
	for (int i = 0; i  x1 && x  14)
					{
						map[i][j].type = 0;
						map[i][j].frameIndex = 0;
					}
				}
			}
		}
	}
}

6. 小推车

 创建存放小车信息的结构体数组,小推车一条路一辆共5辆,所以我们只需写一个大小为5的结构体数组即可。

//小推车
struct car
{
	bool move;//是否处于移动状态
	int x, y;//位置
	bool used;//是否被使用
};
struct car cars[5];

放置小推车 

	for (int i = 0; i  

检测小推车对小车的伤害 

当僵尸的横坐标小于等于小推车最左端的坐标时,小车置为移动状态,处于小推车左边的僵尸死亡。

void checkcars2Zm()
{
	for (int i = 0; i  zmX && cars[i].used)
				{
					if (cars[i].move == false)
						cars[i].move = true;
					else
					{
						killCount++;
						zms[j].dead = true;
						zms[j].speed = 0;
						zms[j].frameIndex = 0;
					}
				}
			}
		}
	}
}

更新小推车的位置

当小车被置为移动时,小推车开始移动。

void updatecar()
{
	for (int i = 0; i  Wide)
		{
			cars[i].move = false;
			cars[i].used = false;
		}
	}
}

源码:

test.cpp文件: 

#include"game.h"
//判断文件是否存在
bool fileExist(const char* name)
{
	FILE* pf = fopen(name, "r");
	if (pf == NULL)
	{
		return false;
	}
	else
	{
		fclose(pf);
		return true;
	}
}
//初始化豌豆子弹的帧图片数组
void bulletsInit()
{
	//坤坤篮球
	loadimage(&imgBulletNormal, "res/bullets/basketball.png", 40, 40);
	memset(bullets, 0, sizeof(bullets));
	//初始化豌豆子弹的帧图片数组
	loadimage(&imgBallBlast[3], "res/bullets/PeaNormalExplode/PeaNormalExplode_0.png");
	for (int i = 0; i getheight(), img);
		}
	}
}
void drawSunshine()
{
	int ballMax = sizeof(balls) / sizeof(balls[0]);
	for (int i = 0; i frameIndex];
			//putimagePNG(balls[i].x, balls[i].y, img);
			putimagePNG(balls[i].pCur.x, balls[i].pCur.y, img);
		}
	}
}
void drawBullets_kunkun()
{
	int bulletsMax = sizeof(bullets) / sizeof(bullets[0]);
	for (int i = 0; i  0)
			{
				/*int x = 256 - 150 + j * 81;
				int y = 100 + i * 100 - 15;*/
				int PlantType = map[i][j].type - 1;
				int index = map[i][j].frameIndex;
				if (map[i][j].type != 4 && map[i][j].type != YING_TAO + 1 && map[i][j].type != LA_JIAO + 1)
				{
					putimagePNG(map[i][j].x, map[i][j].y, imgPlant[PlantType][index]);
				}
				else if (map[i][j].type == YING_TAO + 1)
				{
					if (index == 8)
						putimagePNG(map[i][j].x - 75, map[i][j].y-35, imgPlant[PlantType][index]);
					else
						putimagePNG(map[i][j].x - 22, map[i][j].y, imgPlant[PlantType][index]);
				}
				else if (map[i][j].type == LA_JIAO + 1)
				{
					if (index > 7)
						putimagePNG(100, map[i][j].y - 35, imgPlant[PlantType][index]);
					else
						putimagePNG(map[i][j].x, map[i][j].y, imgPlant[PlantType][index]);
				}
				else
				{
					putimagePNG(map[i][j].x + 5, map[i][j].y - 20, imgPlant[PlantType][index]);
				}
			}
		}
	}
	//渲染子弹
	drawBullets();
	//铲子
	if (curPlant != PLANT_COUNT + 1)
	{
		IMAGE* img = imgPlant[8][0];
		putimagePNG(163 + 8 * 65 + 8, 0, img);
	}
	//僵尸
	drawZm();
	//渲染拖动中的植物
	if (curPlant > 0)
	{
		IMAGE* img = imgPlant[curPlant - 1][0];
		putimagePNG(curX - img->getwidth() / 2, curY - img->getheight() / 2, img);
	}
	//渲染阳光
	drawSunshine();
	EndBatchDraw();
}
void collectSunshine(ExMessage* msg)
{
	int count = sizeof(balls) / sizeof(balls[0]);
	int w = imgSunshineBall[0].getwidth();
	int h = imgSunshineBall[0].getheight();
	for (int i = 0; i x > x && msg->xy>y && msg->y  163 && msg.x = 100)
				{
					curPlant = index + 1;
					status = 1;
					curX = msg.x;
					curY = msg.y;
					sunshine -= 100;
				}*/
				curPlant = index + 1;
				status = 1;
				curX = msg.x;
				curY = msg.y;
			}
			else
			{
				collectSunshine(&msg);
			}
		}
		else if (msg.message == WM_MOUSEMOVE && status == 1)//鼠标移动
		{
			curX = msg.x;
			curY = msg.y;
		}
		else if (msg.message == WM_LBUTTONUP)//鼠标放下
		{
			if (msg.x > 256 - 150 && msg.x  100 && msg.y = ZM_MAX)
						return;
					int i = 0;
					int zmMax = sizeof(zms) / sizeof(zms[0]);
					for (i = 0; i = fre)
	{
		fre = 200 + rand() % 200;
		count = 0;
		//从阳光池取一个可以使用的
		int ballMax = sizeof(balls) / sizeof(balls[0]);
		int i;
		for (i = 0; i = ballMax)return;
			balls[i].used = true;
			balls[i].frameIndex = 0;
		/*	balls[i].x = 160 + rand() % 600;
			balls[i].y = 60;
			balls[i].destY = (rand() % 4) * 90 + 160;*/
			balls[i].timer = 0;
		/*	balls[i].xoff = 0;
			balls[i].yoff = 0;*/
			balls[i].status = SUNSHINE_DOWN;
			balls[i].t = 0;
			balls[i].p1 = vector2(160 + rand() % 600, 60);
			balls[i].p4 = vector2(balls[i].p1.x, (rand() % 4) * 90 + 160);
			int off = 2;
			float distance = balls[i].p4.y - balls[i].p1.y;
			balls[i].speed = 1.0 / (distance / off);
	}
	int ballMax = sizeof(balls) / sizeof(balls[0]);
	//向日葵生产阳光
	for (int i = 0; i  100)
				{
					map[i][j].timer = 0;
					int k;
					for (k = 0; k = ballMax)return;
					balls[k].used = true;
					balls[k].p1 = vector2(map[i][j].x, map[i][j].y);
					int w = (40 + rand() % 50) * (rand() % 2 ? 1 : -1);
					balls[k].p4 = vector2(map[i][j].x + w,
						map[i][j].y + imgPlant[TAI_YANG][0]->getheight() - imgSunshineBall[0].getheight());
					balls[k].p2 = vector2(balls[k].p1.x + w * 0.3, balls[k].p1.y - 100);
					balls[k].p3 = vector2(balls[k].p1.x + w * 0.7, balls[k].p1.y - 100);
					balls[k].status = SUNSHINE_RPODUCT;
					balls[k].speed = 0.05;
					balls[k].t = 0;
				}
			}
		}
	}
}
void updatSunshine()
{
	int ballMax = sizeof(balls) / sizeof(balls[0]);
	for (int i = 0; i t += sun->speed;
				sun->pCur = sun->p1 + sun->t * (sun->p4 - sun->p1);
				if (sun->t >= 1)
				{
					sun->status = SUNSHINE_GROUND;
					sun->timer = 0;
				}
			}
			else if (balls[i].status == SUNSHINE_GROUND)
			{
				balls[i].timer++;
				if (balls[i].timer > 100)
				{
					balls[i].used = false;
					balls[i].timer = 0;
				}
			}
			else if (balls[i].status == SUNSHINE_COLLECT)
			{
				struct sunshineBall* sun = &balls[i];
				sun->t += sun->speed;
				sun->pCur = sun->p1 + sun->t * (sun->p4 - sun->p1);
				if (sun->t > 1)
				{
					sun->used = false;
					sunshine += 25;
				}
			}
			else if (balls[i].status == SUNSHINE_RPODUCT)
			{
				struct sunshineBall* sun = &balls[i];
				sun->t += sun->speed;
				sun->pCur = calcBezierPoint(sun->t,sun->p1, sun->p2, sun->p3, sun->p4);
				if (sun->t > 1)
				{
					sun->status = SUNSHINE_GROUND;
					sun->timer = 0;
				}
			}
		}
	}
}
int mciZmTime = 0;
void createZM()
{
	if (zmCount >= zmCount_max)
		return;
	static int zmFre = 5000000;
	static int count = 0;
	
	count++;
	if (count > zmFre)
	{
		if (mciZmTime == 0)
		{
			mciSendString("play res/audio/awooga.mp3", 0, 0, 0);
			mciZmTime++;
		}
		count = 0;
		zmFre = 202 - 20 * wava_count;
		int i = 0;
		int zmMax = sizeof(zms) / sizeof(zms[0]);
		for (i = 0; i = (gameStatus == GOING ? zms[i].zmSpeed : zmSpeed))
		{
			//printf("%d ", (gameStatus == GOING ? zms[i].zmSpeed : zmSpeed));
			count[i] = 0;
			if (zms[i].used)
			{
				if (zms[i].dead)
				{
					zms[i].frameIndex++;
					if (zms[i].boom == true)
					{
						if (zms[i].frameIndex >= 20)
						{
							//printf("%d ", killCount);
							zms[i].used = false;
							zms[i].row = 0;
							//killCount++;
							if (killCount >= ZM_MAX)
								gameStatus = WIN;
							else if (killCount >= zmCount_max)
							{
								wava_count++;
								zmCount_max *= 2;
								killCount = 0;
								zmCount = 0;
							}
						}
					}
					else
					{
						if (zms[i].frameIndex >= 38)
						{
							//printf("%d ", killCount);
							zms[i].used = false;
							zms[i].row = 0;
							
							if (killCount >= ZM_MAX)
								gameStatus = WIN;
							else if (killCount >= zmCount_max)
							{
								wava_count++;
								zmCount_max *= 2;
								killCount = 0;
								zmCount = 0;
							}
						}
					}
				}
				else if (zms[i].eating)
				{
					//mciSendString("play res/audio/chomp.mp3", 0, 0, 0);
					//mciSendString("play res/audio/chompsoft.mp3", 0, 0, 0);
					zms[i].frameIndex = (zms[i].frameIndex + 1) % 21;
				}
				else
				{
					zms[i].frameIndex++;
					if (zms[i].frameIndex >= 22)
					{
						zms[i].frameIndex = 0;
					}
				}
				zms[i].x -= zms[i].speed;
				if (zms[i].x 100)
		{
			lines[zms[i].row] = 1;
		}
	}
	for (int i = 0; i  20)
				{
					map[i][j].shootTime = 0;
					int k;
					for (k = 0; k getwidth() - 10;
						bullets[k].y = zwY + 5;
					}
				}
			}
			//豌豆
			else if (map[i][j].type == WAN_DOU + 1 && lines[i])
			{
				map[i][j].shootTime++;
				if (map[i][j].shootTime > 35)
				{
					map[i][j].shootTime = 0;
					int k;
					for (k = 0; k  1)
						map[i][j].frameIndex = 2;
						bullets_wandou[k].used = true;
						bullets_wandou[k].row = i;
						bullets_wandou[k].speed = 8;
						bullets_wandou[k].blast = false;
						bullets_wandou[k].frameIndex = 0;
						int zwX = 256 - 150 + j * 81;
						int zwY = 100 + i * 100 - 15;
						bullets_wandou[k].x = zwX + imgPlant[map[i][j].type - 1][0]->getwidth() - 10;
						bullets_wandou[k].y = zwY + 5;
					}
				}
			}
			//寒冰豌豆
			else if (map[i][j].type == HAN_BING_WAN_DOU + 1 && lines[i])
			{
				map[i][j].shootTime++;
				if (map[i][j].shootTime > 35)
				{
					map[i][j].shootTime = 0;
					int k;
					for (k = 0; k  1)
						map[i][j].frameIndex = 4;
						bullets_hanbing[k].used = true;
						bullets_hanbing[k].row = i;
						bullets_hanbing[k].speed = 10;
						bullets_hanbing[k].blast = false;
						bullets_hanbing[k].frameIndex = 0;
						int zwX = 256 - 150 + j * 81;
						int zwY = 100 + i * 100 - 15;
						bullets_hanbing[k].x = zwX + imgPlant[map[i][j].type - 1][0]->getwidth() - 10;
						bullets_hanbing[k].y = zwY + 5;
					}
				}
			}
			//三头豌豆
			else if (map[i][j].type == SAN_TOU_WAN_DOU + 1 && lines[i])
			{
				map[i][j].shootTime++;
				if (map[i][j].shootTime > 35)
				{
					map[i][j].shootTime = 0;
					int k;
					for (int b = 0; b  1)
							//map[i][j].frameIndex = 2;
							bullets_santou[k].used = true;
							bullets_santou[k].row = i;
							bullets_santou[k].speed = 8;
							bullets_santou[k].blast = false;
							bullets_santou[k].frameIndex = 0;
							int zwX = 256 - 150 + j * 81;
							int zwY = 100 + i * 100 - 15;
							bullets_santou[k].x = zwX + imgPlant[map[i][j].type - 1][0]->getwidth() - 30;
							bullets_santou[k].y = zwY + 16;
							direction_santou[k] = b;
							row_santou[k] = i;
						}
					}
				}
			}
		}
	}
}
void updateBullets_kunkun()
{
	int countMax = sizeof(bullets) / sizeof(bullets[0]);
	for (int i = 0; i  Wide)
			{
				bullets[i].used = false;
			}
			//待完善
			if (bullets[i].blast)
			{
				bullets[i].frameIndex++;
				if (bullets[i].frameIndex >= 4)
				{
					bullets[i].used = false;
				}
			}
		}
	}
}
void updateBullets_wandou()
{
	int countMax_wandou = sizeof(bullets_wandou) / sizeof(bullets_wandou[0]);
	for (int i = 0; i  Wide)
			{
				bullets_wandou[i].used = false;
			}
			//待完善
			if (bullets_wandou[i].blast)
			{
				bullets_wandou[i].frameIndex++;
				if (bullets_wandou[i].frameIndex >= 4)
				{
					bullets_wandou[i].used = false;
				}
			}
		}
	}
}
void updateBullets_hanbing()
{
	int countMax_hanbing = sizeof(bullets_hanbing) / sizeof(bullets_hanbing[0]);
	for (int i = 0; i  Wide)
			{
				bullets_hanbing[i].used = false;
			}
			//待完善
			if (bullets_hanbing[i].blast)
			{
				bullets_hanbing[i].frameIndex++;
				if (bullets_hanbing[i].frameIndex >= 4)
				{
					bullets_hanbing[i].used = false;
				}
			}
		}
	}
}
void updateBullets_santou()
{
	int countMax_santou = sizeof(bullets_santou) / sizeof(bullets_santou[0]);
	for (int i = 0; i  Wide)
				{
					bullets_santou[i].used = false;
				}	
			}
			else if (direction_santou[i] == UP)
			{
				int destY = 85 + (row_santou[i] - 1) * 100;
				//int zwX = 256 - 150 + j * 81;
				float angle = atan(0.6);
				bullets_santou[i].x += bullets_santou[i].speed;
				bullets_santou[i].y -= bullets_santou[i].speed * tan(angle);
				//printf("%d\n", row_santou[i]);
				//printf("destY = %d\n", destY);
				//printf("bullets[i].y = %lf\n", bullets[i].y);
				if (bullets_santou[i].y = destY + 16)
				{
					direction_santou[i] = MIDDLE;
				}
			}
			//待完善
			if (bullets_santou[i].blast)
			{
				bullets_santou[i].frameIndex++;
				if (bullets_santou[i].frameIndex >= 4)
				{
					bullets_santou[i].used = false;
				}
			}
		}
	}
}
void updateBullets()
{
	//坤坤
	updateBullets_kunkun();
	//豌豆射手
	updateBullets_wandou();
	//寒冰豌豆
	updateBullets_hanbing();
	//三头豌豆
	updateBullets_santou();
}
void checkBullet2Zm_kunkun()
{
	int bCount = sizeof(bullets) / sizeof(bullets[0]);
	int zCount = sizeof(zms) / sizeof(zms[0]);
	for (int i = 0; i  x1 && x = y1 && zmY  7)
				{
					if (map[i][j].frameIndex == 8)
						PlaySound("res/audio/firepea.wav", NULL, SND_FILENAME | SND_ASYNC);
					for (int k = 0; k  14)
					{
						map[i][j].type = 0;
						map[i][j].frameIndex = 0;
					}
				}
			}
		}
	}
}
void checkZM2Zhiwu()
{
	int chomp = 0;
	//mciSendString("play ZM_BGM repeat", NULL, NULL, NULL);
	char name[64];
	int bCount = sizeof(bullets) / sizeof(bullets[0]);
	int zCount = sizeof(zms) / sizeof(zms[0]);
	for (int i = 0; i = x1 && x3 20)
	{
		chomp_time = 0;
		PlaySound("res/audio/chomp.wav", NULL, SND_FILENAME | SND_ASYNC);
		//mciSendString("play ZM_BGM", NULL, NULL, NULL);
		//printf("1 ");
	}
}
void checkcars2Zm()
{
	for (int i = 0; i  zmX && cars[i].used)
				{
					if (cars[i].move == false)
						cars[i].move = true;
					else
					{
						killCount++;
						zms[j].dead = true;
						zms[j].speed = 0;
						zms[j].frameIndex = 0;
					}
				}
			}
		}
	}
}
void collistionCheck()
{
	//子弹对僵尸的检测
	checkBullet2Zm();
	//僵尸对植物的检测
	checkZM2Zhiwu();
	//爆炸对植物的检测
	checkBoom2Zm();
	//小推车对僵尸的检测
	checkcars2Zm();
}
void updatecar()
{
	for (int i = 0; i  Wide)
		{
			cars[i].move = false;
			cars[i].used = false;
		}
	}
}
void updateGame()
{
	srand((unsigned)time(NULL));
	static int count = 0;
	count++;
	if (count > 4)
	{
		count = 0;
		for (int i = 0; i  0)
				{
					map[i][j].frameIndex++;
					int PlantType = map[i][j].type - 1;
					int index = map[i][j].frameIndex;
					if (map[i][j].shoot)
					{
						if (map[i][j].frameIndex > 1)
						{
							map[i][j].shoot = false;
						}
					}
					else
					{
						if (imgPlant[PlantType][index] == NULL)
						{
							map[i][j].frameIndex = 0;
						}
					}
				}
			}
		}
	}
	createSunshine();//创建阳光
	updatSunshine();//更新阳光状态
	createZM();//创建僵尸
	updateZM();//更新僵尸状态
	shoot();//发射豌豆子弹
	updateBullets();//更新子弹
	collistionCheck();//实现豌豆子弹的碰撞检测
	updatecar();//更新小推车
}
void menu()
{
	mciSendString("play BGM", NULL, NULL, NULL);
	IMAGE imgBg, imgMenu1, imgMenu2;
	loadimage(&imgBg, "res/menu.png");
	loadimage(&imgMenu1, "res/menu2.png");
	loadimage(&imgMenu2, "res/menu1.png");
	int flag = 0;
	while (1)
	{
		BeginBatchDraw();
		putimage(0, 0, &imgBg);
		putimagePNG(474, 75, flag ? &imgMenu1 : &imgMenu2);
		ExMessage msg;
		if (peekmessage(&msg))
		{
			if (msg.message == WM_LBUTTONDOWN &&
				msg.x > 474 && msg.x 75 && msg.y = -500; i-=3)
	{
		BeginBatchDraw();
		putimage(i, 0, &img);
		count++;
		for (int k = 0; k = 10)
			{
				index[k] = (index[k] + 1) % 11;
			} 
		}
		if (count >= 10)count = 0;
		EndBatchDraw();
		Sleep(10);
	}
	
	for (int i = 0; i = 10) count = 0;
		}
		EndBatchDraw();
		Sleep(10);
	}
}
void barsDown()
{
	int height = imgBar.getheight();
	for (int y = -height; y getwidth(); //获取picture的宽度,EASYX自带
	int picture_height = picture->getheight(); //获取picture的高度,EASYX自带
	int graphWidth = getwidth();       //获取绘图区的宽度,EASYX自带
	int graphHeight = getheight();     //获取绘图区的高度,EASYX自带
	int dstX = 0;    //在显存里像素的角标
	// 实现透明贴图 公式: Cp=αp*FP+(1-αp)*BP , 贝叶斯定理来进行点颜色的概率计算
	for (int iy = 0; iy > 24); //0xAArrggbb;AA是透明度
			int sr = ((src[srcX] & 0xff0000) >> 16); //获取RGB里的R
			int sg = ((src[srcX] & 0xff00) >> 8);   //G
			int sb = src[srcX] & 0xff;              //B
			if (ix >= 0 && ix = 0 && iy  16);
				int dg = ((dst[dstX] & 0xff00) >> 8);
				int db = dst[dstX] & 0xff;
				draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) = getwidth()) {
		return;
	}
	else if (y + picture->getheight() > winHeight) {
		SetWorkingImage(picture);
		getimage(&imgTmp, x, y, picture->getwidth(), winHeight - y);
		SetWorkingImage();
		picture = &imgTmp;
	}
	if (x 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;
	}
	_putimagePNG(x, y, picture);
}
int getDelay() {
	static unsigned long long lastTime = 0;
	unsigned long long currentTime = GetTickCount();
	if (lastTime == 0) {
		lastTime = currentTime;
		return 0;
	}
	else {
		int ret = currentTime - lastTime;
		lastTime = currentTime;
		return ret;
	}
}

tools.h文件 

#pragma once
#include 
void putimagePNG(int  picture_x, int picture_y, IMAGE* picture);
int getDelay();
微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon