植物大战僵尸源码1.0版

基本上是rock老师讲的代码复现,有部分改动,较大改动文末附~

【程序员Rock】C语言项目:完整版植物大战僵尸!可能是B站最好的植物大战僵尸教程了!零基础手把手游戏开发_哔哩哔哩_bilibili

  小蒟蒻一枚~如有佬指正,不胜感激!

#include <stdio.h>
#include <conio.h>
#include <graphics.h> //easyx
#include <iostream> //c++
#include <time.h> //rand()
#include <mmsystem.h> //play music
#include <math.h> //贝塞尔函数
#include "vector2.h" 

#pragma comment(lib, "winmm.lib")
#define WIN_WIDTH 900
#define WIN_HEIGHT 600
#define ZM_MAX 10

using namespace std;

enum {wan_dou, xiang_ri_kui, zhi_wu_count};

enum {GOING, WIN, FAIL};
int killed_zm_count;
int zm_appear_count;
int game_status;

IMAGE img_bg;
IMAGE img_bar;
IMAGE img_cards[zhi_wu_count];
IMAGE* img_plants[zhi_wu_count][32];

int curplant; // 0:没有选中;1:选择第一种植物
int curx, cury;

typedef struct plant {
	int type;  // 0:没有植物;1:第一种植物
	int frame_index;  //序列帧的序号
	bool catched;
	int deadtime;
	int x, y;
	int timer;
	int shoot_time;
}plant;

plant map[9][10];

typedef struct sunshineball {
	int x, y;
	int frame_index;
	int dest_y;
	bool used;
	int timer;

	float xoff;
	float yoff;

	float t;//贝塞尔曲线时间
	vector2 p1, p2, p3, p4;
	vector2 pcur;//当前阳光位置
	float speed;
	int status;
}sunshineball;

sunshineball balls[10];
IMAGE img_sunshineball[30];
int sunshine;
enum {sunshine_down, sunshine_ground, sunshine_collect, sunshine_product};

typedef struct zm{
	int x, y;
	int frame_index;
	bool used;
	int speed;
	int row;
	int blood;
	bool dead;
	bool eating;
}zm;
zm zms[10];

IMAGE img_zm[22];
IMAGE img_zm_dead1[10];
IMAGE img_zm_dead2[10];
IMAGE img_zm_eat[21];
IMAGE img_zm_stand[11];

typedef struct bullet {
	int x, y;
	bool used;
	int speed;
	int row;
	bool blast; //是否爆炸
	int frame_index;
}bullet;

bullet bullets[50];
IMAGE img_bullet_normal;
IMAGE img_bullet_blast[4];

IMAGE img_fail;
IMAGE img_win;

#pragma comment( lib, "MSIMG32.LIB")

void TransparentImage(IMAGE* dstimg, int x, int y, IMAGE* srcimg) //新版png
{
	HDC dstDC = GetImageHDC(dstimg);
	HDC srcDC = GetImageHDC(srcimg);
	int w = srcimg->getwidth();
	int h = srcimg->getheight();
	BLENDFUNCTION bf = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
	AlphaBlend(dstDC, x, y, w, h, srcDC, 0, 0, w, h, bf);
}

bool FileExist(const char* name) {
	FILE* fp = fopen(name, "r");
	if (fp == NULL) {
		return false;
	}
	else {
		fclose(fp);
		return true;
	}
}

void GameInit() {
	memset(img_plants, '\0', sizeof(img_plants));
	memset(map, '\0', sizeof map);

	killed_zm_count = 0;
	zm_appear_count = 0;
	game_status = GOING;

	curplant = 0;
	sunshine = 50;

	srand(time(NULL));

	initgraph(WIN_WIDTH, WIN_HEIGHT);

	loadimage(&img_bg, "res/map/map0.jpg");
	loadimage(&img_bar, "res/bar/bar5.png");
	
	char name[64];
	for (int i = 0; i < zhi_wu_count; i++) {
		sprintf_s(name, sizeof(name), "res/cards/card_%d.png", i + 1);
		loadimage(&img_cards[i], name);

		for (int j = 0; j < 20; j++) {
			sprintf_s(name, sizeof(name), "res/zhiwu/%d/%d.png", i + 1, j + 1);
			if (FileExist(name) == true) {//文件打开成功-->文件存在
				img_plants[i][j] =  new IMAGE;
				loadimage(img_plants[i][j], name);
			}
			else {
				break;
			}
		}
	}

	memset(balls, '\0', sizeof(balls));
	
	for (int i = 1; i < 30; i++) {
		sprintf_s(name, sizeof(name), "res/sunshine/%d.png", i);
		if (FileExist(name) == true) {
			loadimage(&img_sunshineball[i - 1], name);
		}
	}
	
	LOGFONT f;
	gettextstyle(&f);
	f.lfHeight = 30;
	f.lfWeight = 15;
	strcpy(f.lfFaceName, "Segoe UI Black");
	f.lfQuality = ANTIALIASED_QUALITY;
	settextstyle(&f);
	setbkmode(TRANSPARENT);
	setcolor(BLACK);

	memset(zms, '\0', sizeof(zms));
	for (int i = 0; i < 22; i++) {
		sprintf_s(name, sizeof(name), "res/zm/%d.png", i + 1);
		loadimage(&img_zm[i], name);
	}

	loadimage(&img_bullet_normal, "res/bullets/bullet_normal.png");
	loadimage(&img_bullet_blast[3], "res/bullets/bullet_blast.png");
	for (int i = 0; i < 3; i++) {
		float k = 0.2 * i + 0.2;
		loadimage(&img_bullet_blast[i], "res/bullets/bullet_blast.png", 
			img_bullet_blast[3].getwidth() * k, img_bullet_blast[3].getheight() * k, true);
	}
	memset(bullets, '\0', sizeof(bullets));

	for (int i = 0; i < 10; i++) {
		sprintf_s(name, "res/zm头掉了/%d.png", i + 1);
		loadimage(&img_zm_dead1[i], name);
		sprintf_s(name, "res/zm倒地/%d.png", i + 1);
		loadimage(&img_zm_dead2[i], name);
	}

	for (int i = 0; i < 21; i++) {
		sprintf_s(name, "res/zm_eat/%d.png", i + 1);
		loadimage(&img_zm_eat[i], name);
	}

	mciSendString("open res/sunshine.mp3", 0, 0, 0);

	for (int i = 0; i < 11; i++) {
		sprintf_s(name, "res/zm_stand/%d.png", i + 1);
		loadimage(&img_zm_stand[i], name);
	}

	loadimage(&img_fail, "res/fail2.png");
	loadimage(&img_win, "res/win2.png");
}

void DrawZm() {
	int zm_max = sizeof(zms) / sizeof(zms[0]);
	for (int i = 0; i < zm_max; i++) {

		if (zms[i].dead && zms[i].used) {
			IMAGE* img1 = &img_zm_dead1[zms[i].frame_index];
			IMAGE* img2 = &img_zm_dead2[zms[i].frame_index];
			TransparentImage(NULL, zms[i].x + 45, zms[i].y + 5, img1);
			TransparentImage(NULL, zms[i].x - 16, zms[i].y - 5, img2);
		}
		else if (zms[i].eating) {
			IMAGE* img = &img_zm_eat[zms[i].frame_index];
			TransparentImage(NULL, zms[i].x, zms[i].y, img);
		}
		else if (zms[i].used) {
			IMAGE* img = &img_zm[zms[i].frame_index];
			TransparentImage(NULL, zms[i].x, zms[i].y, img);
		} 
	}
}

void DrawSunshineBall() {
	int ballmax = sizeof(balls) / sizeof(balls[0]);
	for (int i = 0; i < ballmax; i++) {
		if (balls[i].used ) {
			IMAGE img = img_sunshineball[balls[i].frame_index];
			TransparentImage(NULL, balls[i].pcur.x, balls[i].pcur.y, &img);
		}
	}
}

void DrawShoot() {
	int count_max = sizeof(bullets) / sizeof(bullets[0]);
	for (int i = 0; i < count_max; i++) {
		if (bullets[i].blast) {
			IMAGE* img = &img_bullet_blast[bullets[i].frame_index];
			TransparentImage(NULL, bullets[i].x, bullets[i].y, img);
		} else if (bullets[i].used) {
			TransparentImage(NULL, bullets[i].x, bullets[i].y, &img_bullet_normal);
		}
	}
}

void DrawCards() {
	for (int i = 0; i < zhi_wu_count; i++) {
		int x = 338 + i * 65;
		int y = 6;
		TransparentImage(NULL, x, y, &img_cards[i]);
	}
}

void DrawCurPlant() {
	if (curplant) {
		IMAGE* img = img_plants[curplant - 1][0];
		int x = curx - img->getwidth() / 2;
		int y = cury - img->getheight() / 2;
		TransparentImage(NULL, x, y, img);
	}
}

void DrawMap() {
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 9; j++) {
			if (map[i][j].type != 0) {
				int index = map[i][j].frame_index;
				TransparentImage(NULL, map[i][j].x, map[i][j].y, img_plants[map[i][j].type - 1][index]);
			}
		}
	}
}

void DrawSunScore() {
	char score_text[8];
	sprintf_s(score_text, sizeof(score_text), "%d", sunshine);
	outtextxy(276, 67, score_text);
}

void UpdateWindow() {
	BeginBatchDraw();
	putimage(-112, 0, &img_bg);
	TransparentImage(NULL, 250, 0, &img_bar);   

	DrawCards();

	DrawCurPlant();
	
	DrawMap();

	DrawSunshineBall();

	DrawSunScore();

	DrawZm();

	DrawShoot();

	EndBatchDraw();
}

void CollectSunshine(ExMessage* msg) {
	int count = sizeof(balls) / sizeof(balls[0]);
	int w = img_sunshineball[0].getwidth();
	int h = img_sunshineball[0].getheight();
	for (int i = 0; i < count; i++) {
		if (balls[i].used) {
			int x = balls[i].pcur.x;
			int y = balls[i].pcur.y;
			if (msg->x > x && msg->x < x + w && msg->y >y && msg->y < y + h) {
				//balls[i].used = false;
				//mciSendString("play res/sunshine.mp3", 0, 0, 0);
				balls[i].status = sunshine_collect;
				//通过角度控制阳光轨迹(*记笔记)
				/*float desty = 0;
				float destx = 262;
				float angle = atan((y - desty) / (x - destx));
				balls[i].xoff = 20 * cos(angle);
				balls[i].yoff = 20 * sin(angle);*/

				//贝塞尔曲线
				balls[i].p1 = balls[i].pcur;
				balls[i].p4 = vector2(262, 0);
				float distance = dis(balls[i].p1 - balls[i].p4);
				float off = 16;
				balls[i].speed = 1.0 / (distance / off);
				balls[i].t = 0;
				//总距离(distance) / 每次移动的像素(off)= 需要移动的次数

				break;//收集阳光不能一箭双雕
			}
		}
	}
}

void UserClick() {
	ExMessage msg;
	static int status = 0;
	if (peekmessage(&msg)) {
		if (msg.message == WM_LBUTTONDOWN) {
			if (status == 1) {
				status = 0;
				if (msg.y > 75 && msg.x < 1000 && msg.x > 256 - 112) {
					int row = (msg.y - 75) / 102;  //x
					int col = (msg.x - 256 + 112) / 81;  //y
					if (map[row][col].type == 0) {
						map[row][col].x = 256 - 112 + col * 81;
						map[row][col].y = 90 + row * 102;
						map[row][col].type = curplant;
						map[row][col].frame_index = 0;
						map[row][col].shoot_time = 0;
					}
				}
				
				curplant = 0;
			}
			if (msg.x > 338 && msg.x < 338 + 65 * zhi_wu_count && msg.y < 96) {
				if (status == 0) {
					int index = (msg.x - 338) / 65;
					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;
		}
	}
}

void CreateSunshine() {
	int ball_max = sizeof(balls) / sizeof(balls[0]);
	static int count = 0;
	static int fre = 0;
	count++;
	if (count >= fre) {
		fre = rand() % 300 + 200;
		count = 0;

		int i;
		for (i = 0; i < ball_max && balls[i].used; i++);
		if (i >= ball_max) return;

		//原计算
		balls[i].used = true;
		balls[i].frame_index = 0;
		/*balls[i].x = rand() % (900 - 260 - img_sunshineball->getwidth()) + 260;
		balls[i].dest_y = (rand() % 6) * 90 + 100 + img_sunshineball->getheight();
		balls[i].y = 20;*/
		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(260 - 112 + rand() % (900 - 260 + 112), 60);
		balls[i].p4 = vector2(balls[i].p1.x, 200 + (rand() % 4) * 90);
		int off = 2;
		float distance = balls[i].p4.y - balls[i].p1.y;
		balls[i].speed = 1.0 / (distance / off);
	}

	//向日葵生产阳光
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 9; j++) {
			if (map[i][j].type == xiang_ri_kui + 1) { //当初初始化的不好,如果==xiang_ri_kui实际是豌豆生产的太阳
				map[i][j].timer++;
				if (map[i][j].timer > 200) {
					map[i][j].timer = 0;

					int k;
					for (k = 0; k < ball_max && balls[k].used; k++);
					if (k >= ball_max) return;

					balls[k].used = true;
					balls[k].p1 = vector2(map[i][j].x, map[i][j].y);//起点就是向日葵的位置
					int w = 75;
					balls[k].p4 = vector2(map[i][j].x + w,
						map[i][j].y + img_plants[xiang_ri_kui][0]->getheight() - img_sunshineball[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_product;
					balls[k].speed = 0.05;
					balls[k].t = 0;
				}
			}
		}
	}
}

void UpdateSunshine() {
	int ballmax = sizeof(balls) / sizeof(balls[0]);
	for (int i = 0; i < ballmax; i++) {
		if (balls[i].used) {
			balls[i].frame_index = (balls[i].frame_index + 1) % 29;
			
			if (balls[i].status == sunshine_down) {
				sunshineball* sun = &balls[i];
				sun->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) {
				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_product) {
				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;
				}
			}

			/*if (balls[i].timer == 0) {
				balls[i].y += 2;
			}

			if (balls[i].y >= balls[i].dest_y) {
				balls[i].timer++;
				if (balls[i].timer > 100) {
					balls[i].used = false;
				}
			}*/
		}
		/*else if (balls[i].xoff) {
			float desty = 0;
			float destx = 262;
			float angle = atan((balls[i].y - desty) / (balls[i].x - destx));
			balls[i].xoff = 20 * cos(angle);
			balls[i].yoff = 20 * sin(angle);
			balls[i].x -= balls[i].xoff;
			balls[i].y -= balls[i].yoff;
			if (balls[i].y < 0 || balls[i].x < 262) {
				balls[i].xoff = 0;
				balls[i].yoff = 0;
			}
		}*/
	}
}

void CreatZm() {
	static int zm_fre = 600;
	static int count = 0;
	count++;
	if (count > zm_fre && zm_appear_count <= ZM_MAX) {
		zm_appear_count++;
		count = 0;
		zm_fre = rand() % 200 + 300;

		int i;
		int zm_max = sizeof(zms) / sizeof(zms[0]);
		for (i = 0; i < zm_max && zms[i].used; i++);
		if (i < zm_max) {
			zms[i].eating = false;
			zms[i].used = true;
			zms[i].dead = false;
			zms[i].x = WIN_WIDTH;
			zms[i].speed = 1 ;
			zms[i].row = rand() % 5;
			zms[i].y = 35 + zms[i].row * 100;
			zms[i].blood = 5;
		}
	}
}

void UpdateZm() {
	int zm_max = sizeof(zms) / sizeof(zms[0]);

	for (int i = 0; i < zm_max; i++) {
		if (zms[i].used) {
			zms[i].x -= zms[i].speed ;
			if (zms[i].x < 56) {
				game_status = FAIL;
			}
		}
	}

	static int count = 0;
	count++;
	if (count > 4) {
		count = 0;
		for (int i = 0; i < zm_max; i++) {
			if (zms[i].dead && zms[i].used) {
				zms[i].frame_index++;
				if (zms[i].frame_index > 9) {
					zms[i].used = false;
					cout << i << ' ' << zms[i].frame_index << endl;
					if (killed_zm_count == ZM_MAX) {
						game_status = WIN;
					}
				}
			}
			else if (zms[i].eating == true) {
				zms[i].frame_index = (zms[i].frame_index + 1) % 21;
			}
			else if (zms[i].used) {
				zms[i].frame_index = (zms[i].frame_index + 1) % 22;
			}
		}
	}
}

void Shoot() {
	bool line_zm[5];
	memset(line_zm, false, sizeof(line_zm)); //如果第一行(line[0])没有僵尸,就是false
	int zm_count = sizeof(zms) / sizeof(zms[0]);
	int danger_x = WIN_WIDTH - img_zm[0].getwidth();
	int bullet_max = sizeof(bullets) / sizeof(bullets[0]);
	for (int i = 0; i < zm_count; i++) {
		if (zms[i].used && zms[i].x < danger_x) {
			line_zm[zms[i].row] = true;
		}
	}
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 9; j++) {
			if (map[i][j].type == wan_dou + 1 && line_zm[i]) {
				map[i][j].shoot_time++;
				if (map[i][j].shoot_time > 40) {
					map[i][j].shoot_time = 0;
					
					int k;
					for (k = 0; k < bullet_max && bullets[k].used; k++);

					if (k < bullet_max) {
						bullets[k].used = true;
						bullets[k].row = i;
						bullets[k].speed = 4;

						bullets[k].blast = false;
						bullets[k].frame_index = 0;

						int plant_x = 256 - 112 + j * 81;
						int plant_y = 90 + i * 102;
						bullets[k].x = plant_x + img_plants[map[i][j].type - 1][0]->getwidth() - 10;
						bullets[k].y = plant_y + 5;
					}
				}
			}
		}
	}
}

void UpdateShoot() {
	int count_max = sizeof(bullets) / sizeof(bullets[0]);
	for (int i = 0; i < count_max; i++) {
		if (bullets[i].used) {
			bullets[i].x += bullets[i].speed;
			if (bullets[i].x > WIN_WIDTH) bullets[i].used = false;
		}

		if (bullets[i].blast) {
			bullets[i].frame_index++;
			if (bullets[i].frame_index >= 4) {
				bullets[i].used = false;
				bullets[i].blast = false;
			}
		}
	}
}

void Check_Plant_to_Zm() {
	int bullet_max = sizeof(bullets) / sizeof(bullets[0]);
	int zm_max = sizeof(zms) / sizeof(zms[0]);

	for (int i = 0; i < bullet_max; i++) {
		if (bullets[i].used == false || bullets[i].blast) continue;
		for (int j = 0; j < zm_max; j++) {
			if (zms[j].used == false) continue;
			int x1 = zms[j].x + 80;
			int x2 = zms[j].x + 110;
			int x = bullets[i].x;
			if (x > x1 && x < x2 && bullets[i].row == zms[j].row && zms[j].dead != true) {
				zms[j].blood--;
				bullets[i].blast = true;
				bullets[i].speed = 0;
				if (zms[j].blood <= 0) {
					zms[j].dead = true;
					zms[j].speed = 0;
					zms[j].frame_index = 0;			
				}

				break;	//不能一箭双雕
			}
		}

	}
}

void Check_Zm_to_Plant() {
	int zm_max = sizeof(zms) / sizeof(zms[0]);
	for (int i = 0; i < zm_max; i++) {
		if (zms[i].used == false) continue;
		int row = zms[i].row;
		for (int j = 0; j < 9; j++) {
			if (map[row][j].type == 0) continue;
			int plant_x = 256 - 112 + j * 81;
			int x1 = plant_x + 10;
			int x2 = plant_x + 60;
			int x3 = zms[i].x + 80;
			int x4 = zms[i].x + 150;
			if ((x1 < x3 && x4 < x2) || (x3 < x1 && x1 < x4) || (x3 < x2 && x2 < x4)) {
				if (map[row][j].catched) {
					map[row][j].deadtime++;
			
					if (map[row][j].deadtime >= 100) {
						map[row][j].deadtime = 0;
						map[row][j].type = 0;
						zms[i].eating = false;
						zms[i].frame_index = 0;
						zms[i].speed = 1;
					}
				}
				else {
					map[row][j].catched = true;
					map[row][j].deadtime = 0;
					zms[i].eating = true;
					zms[i].speed = 0;
					zms[i].frame_index = 0;
				}
			}
		}
	}
}

void CollisionCheck() {
	Check_Zm_to_Plant();
	Check_Plant_to_Zm();
}

void UpdateMap() {
	for (int i = 0; i < 5; i++) {
		for (int j = 0; j < 9; j++) {
			if (map[i][j].type != 0) {
				map[i][j].frame_index++;
				int plant_type = map[i][j].type - 1;
				int index = map[i][j].frame_index;
				if (img_plants[plant_type][index] == NULL) map[i][j].frame_index = 0;
			}
		}
	}
}

void UpdateGame() {
	UpdateMap();

	CreateSunshine();
	UpdateSunshine();

	CreatZm();
	UpdateZm();

	Shoot();
	UpdateShoot();

	CollisionCheck();
}

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;
	}
}

void StartUI() {
	IMAGE img_bg, img_m1, img_m2;
	loadimage(&img_bg, "res/menu.png");
	loadimage(&img_m1, "res/menu1.png");
	loadimage(&img_m2, "res/menu2.png");
	int flag = 0;
	while (1) {
		BeginBatchDraw();
		TransparentImage(NULL, 0, 0, &img_bg);
		TransparentImage(NULL, 474, 75, flag ? &img_m1 : &img_m2);

		ExMessage msg;
		if (peekmessage(&msg)) {
			if (msg.message == WM_LBUTTONDOWN && msg.x > 474 && msg.x < 474 + 300 && msg.y > 75 && msg.y < 75 + 140) {
				flag = 1;
			}
			else if (msg.message == WM_LBUTTONUP && msg.x > 474 && msg.x < 474 + 300 && msg.y > 75 && msg.y < 75 + 140) {
				EndBatchDraw();
				break;
			}
		}
		EndBatchDraw();
	}
	
}

void ViewScence() {
	int xmin = WIN_WIDTH - img_bg.getwidth();
	vector2 points[9] = {
		{550, 80}, {530, 160}, {630, 170}, {530, 200}, {515, 270},
		{565, 370}, {605, 340}, {705, 280}, {690, 340}
	};
	int index[9];
	for (int i = 0; i < 9; i++) {
		index[i] = rand() % 11;
	}

	int count = 0;
	for (int x = 0; x >= xmin; x -= 2) {
		BeginBatchDraw();
		putimage(x, 0, &img_bg);
		count++;

		for (int k = 0; k < 9; k++) {
			TransparentImage(NULL, points[k].x - xmin + x, points[k].y, &img_zm_stand[index[k]]);
			if (count > 10) {
				index[k] = (index[k] + 1) % 11;
			}
		}
		if (count > 10) count = 0;

		EndBatchDraw();
		Sleep(5);
	}

	//停留1s左右
	for (int i = 0; i < 100; i++) {
		BeginBatchDraw();

		putimage(xmin, 0, &img_bg);
		for (int k = 0; k < 9; k++) {
			TransparentImage(NULL, points[k].x, points[k].y, &img_zm_stand[index[k]]);
			index[k] = (index[k] + 1) % 11;
		}
		EndBatchDraw();
		Sleep(30);
	}

	count = 0;
	for (int x = xmin; x <= -112; x += 2) {
		BeginBatchDraw();
		putimage(x, 0, &img_bg);
		count++;

		for (int k = 0; k < 9; k++) {
			TransparentImage(NULL, points[k].x + x - xmin, points[k].y, &img_zm_stand[index[k]]);
			if (count > 10) {
				index[k] = (index[k] + 1) % 11;
			}
		}
		if (count > 10) count = 0;

		EndBatchDraw();
		Sleep(5);
	}
}

void BarDown() {
	int height = img_bar.getheight();
	for (int y = -height; y <= 0; y++) {
		BeginBatchDraw();
		putimage(-112, 0, &img_bg);
		TransparentImage(NULL, 250, y, &img_bar);

		for (int i = 0; i < zhi_wu_count; i++) {
			int x = 338 + i * 65;
			TransparentImage(NULL, x, 6 + y, &img_cards[i]);
		}

		EndBatchDraw();
		Sleep(5);
	}
}

int CheckStatus() {
	if (game_status == FAIL) {
		Sleep(2000);
		putimage(0, 0, &img_fail);
		return -1;
	}
	else if (game_status == WIN) {
		Sleep(2000);
		putimage(0, 0, &img_win);
		return 1;
	}
	return 0;
}

int main() {
	GameInit();

	StartUI();

	ViewScence();

	BarDown();

	int timer = 0;
	bool time_flag = true;
	while (1) {
		UserClick();

		timer += GetDelay();

		if (timer > 40) {
			time_flag = true;
			timer = 0;
		}

		if (time_flag) {
			time_flag = false;
			
			UpdateGame();
			UpdateWindow();

			if (CheckStatus() != 0) goto P;
		}

	}

	P:
	Sleep(80);
	system("pause");
}

与rock老师不同列表:
1.僵尸死亡图片(黑沙)
2.透明贴图
3.僵尸吃植物的碰撞检测,根据弹幕改,增加x4判断