前言
植物对抗僵尸是一款经典小游戏,初学者可以从零开始开发自己的版本,这将是一次令人期待的经历!它可以作为课程设计的一部分,也可以用来快速提升项目开发技能。
视频教程+素材资源
点击进入B站:(视频教程+素材资源)
说明:项目演示视频,在上面链接里的第一个视频,下面只展示项目截图..
项目准备
-
安装Visual Studio的任意版本(推荐VS2019社区版、VS2022社区版)
-
安装easyx图形库(官网下载地址)
-
领取项目素材(回复“植物大战僵尸”,即可领取)
创建项目
使用VS创建项目,使用空项目模板:
导入素材 :
在项目目录下,创建res文件夹,把解压后的素材拷贝到res目录下。
实现游戏初始场景
代码如下(需要逐行代码视频讲解,可回复“代码讲解“)。
#include <stdio.h>
#include <graphics.h>
#include "tools.h"
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")
#define WIN_WIDTH 900
#define WIN_HEIGHT 600
enum { WAN_DOU, XIANG_RI_KUI, ZHI_WU_COUT };
IMAGE imgBg;
IMAGE imgBar;
IMAGE imgCards[ZHI_WU_COUT];
IMAGE* imgZhiWu[ZHI_WU_COUT][20];
int curZhiWu;
int curX, curY; //当前选中植物在移动过程中的坐标
struct zhiWu {
int type; // >=1 0:没有植物
int frameIndex;
};
struct zhiWu map[3][9];
int sunshine;
int sunshineTable[ZHI_WU_COUT] = { 100, 50 };
void gameInit() {
loadimage(&imgBg, "res/bg.jpg");
loadimage(&imgBar, "res/bar.png");
sunshine = 150;
curZhiWu = 0;
memset(imgZhiWu, 0, sizeof(imgZhiWu));
memset(map, 0, sizeof(map));
char name[64];
for (int i = 0; i < ZHI_WU_COUT; i++) {
sprintf_s(name, sizeof(name), "res/Cards/card_%d.png", i + 1);
loadimage(&imgCards[i], name);
for (int j = 0; j < 20; j++) {
sprintf_s(name, sizeof(name), "res/zhiwu/%d/%d.png", i, j + 1);
imgZhiWu[i][j] = new IMAGE;
loadimage(imgZhiWu[i][j], name);
if (imgZhiWu[i][j]->getwidth() == 0) {
delete imgZhiWu[i][j];
imgZhiWu[i][j] = NULL;
}
}
}
initgraph(WIN_WIDTH, WIN_HEIGHT, 1);
// 设置字体:
LOGFONT f;
gettextstyle(&f); // 获取当前字体设置
f.lfHeight = 30; // 设置字体高度为 48
f.lfWidth = 15;
strcpy(f.lfFaceName, "Segoe UI Black");
f.lfQuality = ANTIALIASED_QUALITY; // 设置输出效果为抗锯齿
settextstyle(&f); // 设置字体样式
setbkmode(TRANSPARENT);
setcolor(BLACK);
mciSendString("play res/bg.mp3 repeat", 0, 0, 0);
}
void updateWindow() {
BeginBatchDraw();
putimage(0, 0, &imgBg);
putimagePNG(250, 0, &imgBar);
for (int i = 0; i < ZHI_WU_COUT; i++) {
int x = 338 + i * 64;
int y = 6;
putimage(x, y, &imgCards[i]);
}
if (curZhiWu > 0) { // 绘制正在移动的植物
IMAGE* img = imgZhiWu[curZhiWu - 1][0];
putimagePNG(curX - img->getwidth() * 0.5, curY - img->getheight() * 0.5, img);
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 9; j++) {
if (map[i][j].type > 0) {
int x = 260 + j * 81.6; // (msg.x - 260) / 81.6;
int y = 180 + i * 103.6 + 14; // (msg.y - 210) / 103.6;
int zhiWuIndex = map[i][j].type;
int frameIndex = map[i][j].frameIndex;
putimagePNG(x, y, imgZhiWu[zhiWuIndex - 1][frameIndex]);
}
}
}
char scoreText[8];
sprintf_s(scoreText, sizeof(scoreText), "%d", sunshine);
outtextxy(282 - 10 + 4, 50 + 15 + 2, scoreText);
EndBatchDraw();
}
void userClick() {
ExMessage msg;
static int status = 0;
if (peekmessage(&msg)) {
if (msg.message == WM_LBUTTONDOWN) {
if (msg.x > 338 && msg.x < 338 + 64 * ZHI_WU_COUT && msg.y>6 && msg.y < 96) {
int index = (msg.x - 338) / 64;
printf("%d\n", index);
status = 1;
curZhiWu = index + 1; // 1, 2
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 && status == 1) {
printf("up\n");
if (msg.x > 260 && msg.y < 995 && msg.y > 180 && msg.y < 491) {
if (sunshine >= sunshineTabl