c语言项目
c语言弹奏起风了
1 |
|
植物大战僵尸
加载背景图片
1 | #include"tools.h" |
首先啊我们对我们初学者最感兴趣的
就是那个游戏的背景是吧
游戏背景加载游戏背景图片
背景图片的话有两种加载方式
第一种是把背景图片
直接打印到我们窗口里面来
但这种方式会它会比较慢
我经常调的会比较慢
第二种方式的话
我就定义一个全局变量
它用来表示背景图片的
所以我们要加载啊
就从硬盘的那个背景图片
把它加载到我们这边里面来
怎样价值呢
1 | loadimage(&background1, "res/bg.jpg") |
注意啊
加载的时候这里要加个取地址符号
后面是我们这个啊路径呢
哎好像我们素材的路径打开所在文件夹
就是我们的res目录吧
目录下面的这个bg.jpg啊
这是我们的背景图片
好像也是这个不建议用绝对路径
有同学喜欢用这个啊
绝对路径很长很长的
这个方不方便
而且项目改变位置你就失效了
必须点接笔记好
加上之后它这里有个错误提示啊
老鸟的话就知道了啊
这是很多解决办法
根本原因是字符集的原因造成的
所以我们这里只需要什么呢
啊最简单的方式是需要改变它的项属性啊
右键单击项目名称
选择属性
弹出属性窗口啊
这里选择高级好这个字符集
把它改成多字节字符集
这样的话我们背景的图片就已经加载好了
但是这个时候的话他是不会啊
不会显示了
跑起来特别显示的啊
因为它放在内存变量里面是吧
所以我们要把它显示出来的话
还要额外实现它显示出来怎么办呢
诶那我们肯定要什么要先创建这个什么
创建这个游戏窗口
显示到窗口里面来吧
mod的话还是控制台呀
创建一个游戏的图形窗口
1 | initgraph(weight,height); |
啊这个是一直插图形库的结构
很多初学者的话
这个啊担心记不住啊
没关系啊
有个印象就行了
然后查下笔记
看下我的笔记就可以了
它有两个参数啊
第一个窗口的宽度
还有窗户的高度
穿过好多宽多高呢
啊这个游啊这个相机里哈哈他来算啊
这个游戏要多宽多高好看啊
我们这里来啊
直接复刻的那个经典的总大战僵尸啊
按照他的比例的话
我选择这个宽度900x600
900x9也可以这样写
900 600
但这样写就不专业啊是吧
万一以后更改了
所以我们可以把它定义成一个红或者
cos变量都行
我们这里定义成一个红
这c语言的基本的语法是吧
1 |
初始化加载图片
1 | void gameinit() { |
这样的话我们最简单的初始化就做好了
你看被图片已经加载到我们的变量里面来了
窗口也已经创建好了
好咱们可以跑起来了
哈哈这时候跑的话肯定是一片黑是吧
大家也可以先试一下啊
再加个暂停
因为你不加暂停的话
程序直接gg啊
窗户都来不及
1 | system("pause"); |
你看窗户已经出来了
我这个时候都出不来的话
那说明这个环境没有搭配好啊
要重新重新装一下
这个一直插图形库
好然后我们在你你窗口
但是我们是黑的吧
啊我们没有看到我们最关心的这个游戏背景
怎么显示呢
啊
这种啊也可以了解分享开那个专业的开发方式
单一的功能啊
我们要什么一定要封装成一个函数
所以我们也给它封装一个更新
update
问那个更新窗口
这是表示更新啊
这个游戏窗口的update问的
但你有其他的名字也是没问题的
再买定
更新窗口
更新窗口的话就是把我们的背景图片打开
打出来写出来
用反应组叫渲染bot image
他就是专门把一个图片渲染出来显示出来的
它有呃多个参数
第一个参数其实这是什么意思
我先先写吧
等一下把调查说明image pg好
void updatewindow() { putimage(0, 0, &background1);}
我们在打印一个窗图片的时候
啊啊我们要确定它的一个坐标
几乎所有的图形库它都是这种坐标概念
哈哈哈哈哈啊
我们的游戏
植物大战僵尸的最初始的界面就已经出来了
不过啊还非常简陋
很多要素都没有
比如说我们的这个啊全面
他在上面的有个类似一个背包内的一个啊
有一个啊按钮啊
有个按钮可以选择我们各种植物的啊
没有出来
还僵尸也没跑过来
好这些
我们看来下一步再做好
这里的话
这就非常简单啊
主要是开发环境的一个设置
一个开环境要使用这个vs
建议vs用其他开环境也可以啊
但是比较麻烦一下要绕左
为了配置另外装一直插图形库
好把素材导进来啊
我们就可以直接看到我们的这个
最初始的界面了
下一节我们就来做我们的坠子上面啊
上面这个啊这个啊
工具栏
我们把这个背景这么做下来
我们做工具栏的话其实不是一样的吗
啊只是在不同的位置啊
把一个图片把它做显示出来就可以了
那中间呢它本质上也是一张图片
所以的话呢我们在这里定义一个啊图片变量
好接下来我们要相同的背景
相同背景处理方式
相同的背景要加
要初始化吗
我们这里也是初始化啊
把这个啊
这个硬盘里的这个图片加载到我们的内存面
1 | loadimage(&wupinlan, "res/bar.png"); |
好这样的话
我们的这个
工具栏就有了
但是还没有什么呢
一个没有阳光值
这有阳光值
再一个的话
他这里应该有放放置很多植物的啊
我可以我在我这里称作植物卡牌
有很多植物的
然后我们选这么一个植物啊
就可以拖放到下面进行种植
所以呢这里要放置各种植物卡牌啊
那现在呢啊所以现在我们来做写下
a实现这个游戏
工具栏是吧
好你说了哎
实现这个诶工具栏
中的植物卡牌
植物卡牌有很多
一种植物的话就意思一种卡牌
这里最多有有可以考七种
那么相同的方式啊
要先定义一个内存变量来表示我们的植物卡牌
但是你大家发现没有
这植物卡片很多建有多个变量
那么而且它是相同性质
那我就想到了我们c语言的数组
定一个图片
数组image
image这个
其他名字啊log有起名纠结症
植物卡牌卡牌
看看有多有几种呢
1357是吧对
1 | IMAGE zhiwu[zhiwucount]; |
所以我们最好也可以用一次吗
用枚举的方式来定义数量(与宏比较)
1 | enum { wandou, xiangrikui, jianguoqiang, hanbingsheshou, tudoulei, zhiwucount }; |
加载植物卡片图片
1 | char name[32]; |
ok好
我们的卡牌就全部就加载好了
加载好之后
进行渲染
这位置怎么确定啊
这个比较简单
你看只要确定这个起始位置啊
按照每每个是它的一个距离啊
我们用最简单的一个数学运算
我们就可以把它算出来啊
这确定这个边界就可以了
int x = 189;
for (int i = 0; i < zhiwucount; i++) {
putimage(x, 5, &zhiwu[i]);
x = x + 70;}
这样的话我们的植物卡牌诶就已经诶写的好了
下一步的话我们就要嗯做拖放啊
种植植物拖放
我们准备来实现我们这个植物的一个种植
也就是好看一下我们之前的效果
也就是我们这种鼠标选中啊一个卡牌
先优化一下代码
1 | int main(){ |
这里呢哎我们就首先要进行个什么
等待用户的处理
用户的点击
那么定义一个user click
用户单击
此时页面会不停进行闪动,要加入双缓冲
双缓冲
所谓双缓冲啊
就是在嗯你看原来的逻辑是先打印背景啊
再打印这个工具栏啊
好在打印卡牌啊
一步一步打印的
那在肯定会它打印的过程中啊
画面就会有闪烁
怎么办呢
我们就先使用双缓冲
就啊先怎么写好
先写出来
所谓双缓冲就是先不直接打印到屏幕啊
这里开始缓冲
先打印在一块特殊内内存里面啊
不打印到屏幕
然后把全部都打印完之后
到内存里面准备好之后
再一次性的夸夸刷出去
再打印出来
结束啊
双缓冲就是正式啊
把它打印到这个嗯
窗口卖的话就不会抖动了哈
1 | void updatewindow() { |
我们再跑起来看一下就没有问题了
信息事件(鼠标点击等)
但是我们现在的问题是要做什么啊
做这个嗯
就做这个用户单击用户点击操作种植植物
种植植物的话要先选中一个植物
然后再拖放啊
这样一个动作啊
让我们来处理一下啊
先选中鼠标
左键单击选中
那我就要先判断他有没有这个有没有消息啊
用这个来判断有没有鼠标
鼠标消息
1 | void userclick() { |
他的判断当前有没有消息
你鼠标移动鼠标点击鼠标抬起来啊
按键按下去
这都会产生一个消息
为什么不直接读鼠标信息
直接getmessage
你直接读消息的话
如果当时没有消息呢
那就会卡住啊
程序卡住
所以来个什么peekmessage
它就是一个判断有没有消息
有消息
那就返回为真
没有消息就反馈一下它
程序不会阻塞它
参数的话是一个啊消息类型message
啊消息好把他地址带进来
如果有消息的话
那消息的具体的啊值啊
就保存在这个message里面
那我就做个判断
如果if如果有消息有消息的话
结构为增
如果有消息啊
然后还判断它是鼠标左键按下去是吧
但如果消息的message message啊
没消息的类型是左键l l8 n按下去l8 n down
左键按下
如果是左键按下
我们就怎么怎么样怎么样是吧
其实还有很多
还有如果是这个
等一下植物种植的时候
还会鼠标拖动是吧
因为在鼠标移动过程中啊
我们要啊在移动过程中
他那个跟随鼠标
它跟着闪动啊
他这种效果
我在选中它
鼠标在移动的时候啊
在鼠标移到哪里
他的鼠标周围它就跟着一个植物在在拖动啊
还有抬起来
鼠标按键抬起来
那就把植物就正式粽子下去
嗯再看一下啊
我们先做你鼠标左键按下去
按下去的话
我们要判定他按的位置
其他位置按下去
它是不应该有反应的
所以我们要判断它单击的位置
对不对啊
检测位置是否正确
1 | void userclick() { |
判定他是先选择之后再做拖动
定义一个状态变量
1 | void userclick() { |
我怎么知道在哪个位置呢 不知道的 那怎么办唉 用c语言的方式的话
最简单的方式就定一个全局变量
显示拖动位置
1 | int curx,cury; |
但拖动时不能显示卡牌 应该是卡牌那个背景去掉之后 他 我们应该显示这个植物 不是显示这个卡牌本身
通过实现一个不停的播放 让它达到一个动画的效果
1 | IMAGE* imgzhiwu[zhiwucount][20];//在刚开始定义植物动画二维数组指针 |
在加载植物卡牌后加入一个for循环
1 | for (int i = 0; i < zhiwucount; i++) { |
各种植物动画所需要的图片数量不同,需要写一个函数进行判断
1 | bool isexist(const char* name) { |
既然将内存设置为0,则需要同时创建出图片大小的内存区域
1 | imgzhiwu[i][j] = new IMAGE;//分配内存 |
确定拖动植物种类
1 | int curzhiwu;//判断选择的植物种类,全局变量,选中为>0,不选中为0 |
鼠标松开后
1 | else if (msg.message == WM_LBUTTONUP && status == 1) { |
放置植物
先定义结构体
1 | struct zhiwu{ |
给结构体开辟内存
1 | memset(map,0,sizeof(map)); |
种植物
1 | int row=(msg.y-179)/102;表示种的是那一行 |
此时可优化一下,种在边界时不发生反应
1 | if(msg.x>256&&msg.y>179&&msg.y<489){} |
若种植位置正确
1 | if (map[row][col].type == 0) { |
渲染图片
1 | for (int i = 0; i < 3; i++) { |