djakdhkdhskdhsk
This commit is contained in:
commit
a493f4e5e9
617
test.c
Normal file
617
test.c
Normal file
@ -0,0 +1,617 @@
|
||||
#include <graphics.h> // 引用图形库头文件
|
||||
#include<stdlib.h>
|
||||
#include<stdio.h>
|
||||
#include"tools.h"
|
||||
#include<time.h>
|
||||
#define Wiw_width 900
|
||||
#define Wiw_heigh 600
|
||||
enum { WANDOU, XRK, JIANGUO,ZHIWU_COUNT };//枚举定义植物类型和数量
|
||||
//将卡牌数量放到枚举最后一个,即可巧妙的自动表示数组长度(即卡牌数量)
|
||||
|
||||
IMAGE imgBg;//表示背景图片
|
||||
IMAGE imgToor;//表示工具栏
|
||||
IMAGE imgCards[ZHIWU_COUNT];//植物卡牌数组
|
||||
IMAGE *imgplt[ZHIWU_COUNT][20];//每个植物有多个图片,形成动态效果
|
||||
|
||||
|
||||
int percentX, percentY;//定义全局变量,当前选中植物所在坐标
|
||||
int percent_plant;//0:没有选中 1:选中第一种
|
||||
struct plant
|
||||
{
|
||||
int type;//第几种植物,0没有植物,1第一种植物
|
||||
int frameIndex;//序列帧序号
|
||||
|
||||
};
|
||||
struct plant map[5][8];//地图上可以放五行八列的植物
|
||||
|
||||
struct sunshineBall
|
||||
{
|
||||
//阳光位置
|
||||
int x, y;//飘落过程中的坐标位置,x不变
|
||||
int frameIndex;//阳光图片帧序号
|
||||
int fixedY;//最终位置
|
||||
bool used;//是否在使用
|
||||
int timer;//计时器为了使阳光存在时间加长
|
||||
};
|
||||
//池
|
||||
/*
|
||||
|
||||
预先准备10个阳光球
|
||||
如果频繁的创建阳光球不方便管理
|
||||
|
||||
*/
|
||||
struct sunshineBall balls[10];
|
||||
|
||||
//定义一个图片数组储存阳光
|
||||
IMAGE imgSun[29];
|
||||
|
||||
int Suncount;//阳光的数量
|
||||
|
||||
|
||||
bool fileExist(const char* Zwname)
|
||||
{
|
||||
FILE* fp = fopen(Zwname, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
return false;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(fp);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void gameInit()
|
||||
{
|
||||
int j;
|
||||
//加载背景图片
|
||||
//把字符集修改为多字符集
|
||||
loadimage(&imgBg, "res\\map0.jpg");
|
||||
//加载工具栏图片
|
||||
loadimage(&imgToor, "res\\bar5.png");
|
||||
|
||||
memset(imgplt, 0, sizeof(imgplt));
|
||||
|
||||
memset(map, 0, sizeof(map));
|
||||
memset(balls, 0, sizeof(balls));
|
||||
//加载多个植物卡牌图片
|
||||
int i;
|
||||
int suni;
|
||||
//生成植物卡牌文件名
|
||||
char Zwname[1024];
|
||||
char Sunname[1024];
|
||||
for (i = 0; i < ZHIWU_COUNT; i++)
|
||||
{
|
||||
//???
|
||||
sprintf_s(Zwname, sizeof(Zwname), "res\\Cards\\card_%d.png", i + 1);
|
||||
loadimage(&imgCards[i], Zwname);
|
||||
|
||||
for (j = 0; j < 20; j++)
|
||||
{
|
||||
sprintf_s(Zwname, sizeof(Zwname), "res\\Plants\\%d\\%d.png", i,j + 1);
|
||||
//先判断文件是否存在
|
||||
//通过文件是否能打开判断是否存在
|
||||
if (fileExist(Zwname))
|
||||
{
|
||||
//开始设置的*imgplt是空指针,直接加载会崩掉
|
||||
//所以要分配内存
|
||||
imgplt[i][j] = new IMAGE;//因为这个图形库函数是c++,分配内存不能用malloc,用c++的方式来分配内存
|
||||
//上方代码是c++内容,暂时看不懂
|
||||
loadimage(imgplt[i][j], Zwname);
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
percent_plant = 0;
|
||||
|
||||
//阳光池
|
||||
//memset(balls, 0, sizeof(balls));
|
||||
for (suni = 0; suni < 29; suni++)
|
||||
{
|
||||
|
||||
sprintf_s(Sunname, sizeof(Sunname),"res\\sunshine\\%d.png", suni + 1);
|
||||
//"C:\\Users\\URL\\source\\repos\\植物大战僵尸\\植物大战僵尸\\res\\sunshine\\%d.png"
|
||||
|
||||
loadimage(&imgSun[suni], Sunname);
|
||||
|
||||
}
|
||||
//配置随机种子
|
||||
|
||||
srand(time(NULL));
|
||||
|
||||
|
||||
//创建游戏图形化窗口
|
||||
initgraph(Wiw_width, Wiw_heigh);
|
||||
Suncount = 50;//初始阳光的数值
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
//渲染函数,把图片加载出来
|
||||
void update_window()
|
||||
{
|
||||
//BeginBatchDraw函数用于启动批量绘图模式。
|
||||
//在这种模式下,所有的绘图操作都不会立即显示在屏幕上,
|
||||
//而是暂时存储在内存中,直到调用FlushBatchDraw或EndBatchDraw函数时才会一次性渲染到屏幕上。
|
||||
//这种方法可以有效减少绘图过程中的闪烁现象,
|
||||
//特别是在动画或连续移动的图形中
|
||||
BeginBatchDraw();//开始缓冲
|
||||
int i, j, line, cloumn;
|
||||
int index, planttype;
|
||||
int iS;
|
||||
int ballMax;
|
||||
putimage(0, 0, &imgBg);
|
||||
|
||||
putimagePNG(250, 0, &imgToor);
|
||||
for (i = 0; i < ZHIWU_COUNT; i++)
|
||||
{
|
||||
j = 340 + 64 * i;
|
||||
putimage(j,6, &imgCards[i]);
|
||||
|
||||
}
|
||||
|
||||
//判断是否有植物
|
||||
for (line = 0; line < 5; line++)
|
||||
{
|
||||
for (cloumn = 0; cloumn < 9; cloumn++)
|
||||
{
|
||||
if (map[line][cloumn].type > 0)
|
||||
{
|
||||
/*
|
||||
line = (msg.y - 70) / 103;//第几行
|
||||
column = (msg.x - 250) / 82;//第几列*/
|
||||
index = map[line][cloumn].frameIndex;
|
||||
planttype = map[line][cloumn].type - 1;
|
||||
//可以微调渲染位置
|
||||
putimagePNG(250 + cloumn * 82+2, 70 + line * 103+15, imgplt[planttype][index]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//为了使拖动的植物图层在最上面
|
||||
// 即拖动时被拖动植物覆盖已经种植的植物
|
||||
// 所以将拖动中渲染放到最后
|
||||
//渲染拖动中的植物
|
||||
if (percent_plant > 0)
|
||||
{
|
||||
//为了方便定义一个变量img去获取长宽,为了使鼠标指在渲染图片中央
|
||||
IMAGE* img = imgplt[percent_plant - 1][0];
|
||||
putimagePNG(percentX - img->getwidth() / 2, percentY - img->getheight() / 2, img);
|
||||
|
||||
|
||||
}
|
||||
|
||||
ballMax = sizeof(balls) / sizeof(balls[0]);
|
||||
for (iS = 0; iS < ballMax; iS++)
|
||||
{
|
||||
if (balls[iS].used)
|
||||
{
|
||||
IMAGE *img = &imgSun[balls[iS].frameIndex];
|
||||
putimagePNG(balls[iS].x, balls[iS].y,img);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
EndBatchDraw();//结束双缓冲
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void collectSun(ExMessage* msg)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sizeof(balls); i++)
|
||||
{
|
||||
|
||||
if (msg->x == balls[i].x && msg->y == balls[i].y)
|
||||
{
|
||||
Suncount += 50;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
void userClick()
|
||||
{
|
||||
//用户鼠标操作交互实现
|
||||
//判断有没有消息
|
||||
int index;
|
||||
int line;
|
||||
int column;
|
||||
ExMessage msg;
|
||||
static int status = 0;//定义静态变量,目的是确保选择后再拖动
|
||||
if (peekmessage(&msg))
|
||||
{
|
||||
if (msg.message == WM_LBUTTONDOWN)
|
||||
{
|
||||
//判断是否在卡牌区域内操作
|
||||
if (msg.x > 340 && msg.x < 340 + 64 * ZHIWU_COUNT && msg.y > 0 && msg.y < 97)
|
||||
{
|
||||
index = (msg.x - 340) / 64;
|
||||
status = 1;
|
||||
percent_plant = index + 1;
|
||||
//printf("%d\n", index);
|
||||
//验证鼠标选择植物卡牌是否准确
|
||||
}
|
||||
else
|
||||
{
|
||||
//如果不在卡牌区域内操作,执行以下代码(收集阳光,或铲子回收)
|
||||
collectSun(&msg);//可以直接传递msg,但传递一个指针程序消耗少
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
图片可视化即是渲染,即在窗口某个坐标位置
|
||||
出现图片,所以下面代码得用渲染函数处理
|
||||
*/
|
||||
else if (msg.message == WM_MOUSEMOVE && status == 1)
|
||||
{
|
||||
percentX = msg.x;
|
||||
percentY = msg.y;
|
||||
|
||||
//拖动过程显示卡牌植物,不是卡牌,进行素材补充
|
||||
|
||||
//确定哪一种植物,再次添加全局变量status
|
||||
|
||||
|
||||
}
|
||||
else if (msg.message == WM_LBUTTONUP)
|
||||
{
|
||||
|
||||
|
||||
|
||||
line = (msg.y - 70) / 103;//第几行
|
||||
column = (msg.x - 250) / 82;//第几列
|
||||
//printf("%d%d\n", line+1, column+1);验证种植坐标是否准确
|
||||
|
||||
//种植位置确定,且确保一个位置只有一个植物
|
||||
if (map[line][column].type == 0)
|
||||
{
|
||||
map[line][column].type = percent_plant;
|
||||
map[line][column].frameIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
percent_plant = 0;
|
||||
status = 0 ;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//创建阳光
|
||||
void createSun()
|
||||
{
|
||||
//控制阳光的刷新频率
|
||||
int i;
|
||||
static int count = 0;
|
||||
static int fre = 1;//400
|
||||
count++;
|
||||
//每400+帧数刷新一次阳光
|
||||
if (count >= 4)
|
||||
{
|
||||
count = 0;
|
||||
fre = 120 + rand() % 200;
|
||||
//从阳光池中取一个可以使用的
|
||||
|
||||
int ballMax = sizeof(balls) / sizeof(balls[0]);
|
||||
//找到一个可以使用的阳光球的帧
|
||||
for (i = 0; (i <= ballMax) && balls[i].used; i++);
|
||||
if (i >= ballMax)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
balls[i].used = true;
|
||||
balls[i].frameIndex = 0;
|
||||
//阳光降落x范围260-930
|
||||
balls[i].x = rand() % (900 - 260) + 260;
|
||||
|
||||
|
||||
|
||||
//以下代码实现第一个阳光球的x坐标小于345
|
||||
static int test = 0;
|
||||
if (test == 0)
|
||||
{
|
||||
balls[i].x = 852;//256
|
||||
|
||||
test = 1;
|
||||
}
|
||||
|
||||
|
||||
//经过以上测试,只要第一个阳光球生成的x坐标<=345,就可以运行下去
|
||||
|
||||
|
||||
//balls[i].x = 345;
|
||||
/*
|
||||
|
||||
经过找错找出
|
||||
x坐标大于345出现报错问题
|
||||
|
||||
|
||||
|
||||
有阳光会不断在第一个x坐标位置下落一小段距离消失,
|
||||
若将x的值小于等于0的阳光会正常下落,但当落下来消失的那一刻会出现报错问题
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
问题在第一个阳光上
|
||||
1.坐标范围会导致内存冲突什么的
|
||||
2.第一个阳光会一直存在不消失
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
balls[i].y = 60;//阳光的初始位置
|
||||
|
||||
//阳光的固定落点
|
||||
balls[i].fixedY = 200 + (rand() % 4) * 90;
|
||||
//balls[i].fixedY = rand() % (560 - 190) + 190;
|
||||
balls[i].timer = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
//阳光位置在竖直向下移动,同时旋转
|
||||
void moveSun()
|
||||
{
|
||||
int i;
|
||||
int ballMax = sizeof(balls) / sizeof(balls[0]);
|
||||
|
||||
for (i = 0; i < ballMax; i++)
|
||||
{
|
||||
if (balls[i].used)
|
||||
{
|
||||
//%取余是防止阳光球帧数超出图片数
|
||||
balls[i].frameIndex = (balls[i].frameIndex + 1) % 29;
|
||||
for (int i = 0; i < ballMax; i++) {
|
||||
if (balls[i].used == true) {
|
||||
balls[i].frameIndex = (balls[i].frameIndex + 1) % 29;//防止阳光球帧数超过图片数
|
||||
if (balls[i].timer == 0) {
|
||||
balls[i].y += 4;
|
||||
}
|
||||
if (balls[i].y >= balls[i].fixedY)
|
||||
{
|
||||
balls[i].timer++;
|
||||
if (balls[i].timer >= 100)
|
||||
{
|
||||
balls[i].used = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (balls[i].y >= balls[i].fixedY)
|
||||
{
|
||||
balls[i].timer++;
|
||||
//balls[i].used = false;
|
||||
if (balls[i].timer >= 100)
|
||||
{
|
||||
balls[i].used = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void updateGame()
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
int k;
|
||||
int planttype;
|
||||
int index;
|
||||
/*for (k = 0; k< 100000000; k++)
|
||||
{
|
||||
;
|
||||
}*/
|
||||
//实现植物摇晃
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
for (j = 0; j < 9; j++)
|
||||
{
|
||||
|
||||
if (map[i][j].type > 0)
|
||||
{
|
||||
map[i][j].frameIndex++;
|
||||
planttype = map[i][j].type - 1;
|
||||
index = map[i][j].frameIndex;
|
||||
|
||||
if (imgplt[planttype][index] == NULL)
|
||||
{
|
||||
map[i][j].frameIndex = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//修改游戏数据,即是更新阳光球数据
|
||||
|
||||
createSun();
|
||||
moveSun();
|
||||
|
||||
|
||||
/*
|
||||
以上两个函数内容有问题
|
||||
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
//初始菜单
|
||||
void startUI()
|
||||
{
|
||||
IMAGE imgSTART,Menu1,Menu2;
|
||||
loadimage(&imgSTART, "res\\menu.png");
|
||||
loadimage(&Menu1, "res\\menu1.png");
|
||||
loadimage(&Menu2, "res\\menu2.png");
|
||||
|
||||
|
||||
//状态变量
|
||||
int flag = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
BeginBatchDraw();
|
||||
putimage(0, 0, &imgSTART);
|
||||
putimagePNG(460, 120, flag ? &Menu1 : &Menu2);
|
||||
|
||||
|
||||
ExMessage msg;
|
||||
if (peekmessage(&msg))
|
||||
{
|
||||
if (msg.message == WM_LBUTTONDOWN )
|
||||
{
|
||||
|
||||
if (msg.x > 460 && msg.x < 460 + 300 && msg.y>75 && msg.y < 250)
|
||||
{
|
||||
flag = 1;
|
||||
|
||||
}
|
||||
}
|
||||
else if (msg.message == WM_LBUTTONUP&&flag==1)
|
||||
{
|
||||
//鼠标抬起后进入游戏
|
||||
return;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
EndBatchDraw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
int main()
|
||||
{
|
||||
|
||||
gameInit();
|
||||
startUI();
|
||||
int timer = 0;
|
||||
bool flag = true;
|
||||
while (1)
|
||||
{
|
||||
|
||||
userClick();
|
||||
//植物摇摆太快,直接用Sleep();会导致用户点击延迟
|
||||
//getDelay();是工具包里的函数,返回值是距离上一次调用的时间差
|
||||
//通过以下判断,当时间差大于20ms再进行渲染
|
||||
/*下面是实现延迟调用函数的方法
|
||||
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;
|
||||
}
|
||||
}
|
||||
*/
|
||||
timer += getDelay();
|
||||
if (timer > 60)
|
||||
{
|
||||
flag = true;
|
||||
timer = 0;
|
||||
|
||||
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
flag = false;
|
||||
update_window();
|
||||
updateGame();
|
||||
}
|
||||
|
||||
|
||||
//每运行一次改变游戏内的相关数据,即改变植物图片形成动态效果
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//system("pause");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
问题
|
||||
调试时点击进入游戏之后直接运行结束
|
||||
第311行代码&& balls[i].used删掉后问题解决
|
||||
即是执行313以下代码导致
|
||||
|
||||
moveSun();
|
||||
|
||||
*/
|
Loading…
x
Reference in New Issue
Block a user