c语言弹奏起风了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#include <iostream>
#include <Windows.h>
#pragma comment(lib,"winmm.lib")
using namespace std;
enum Scale
{
Rest = 0, C8 = 108, B7 = 107, A7s = 106, A7 = 105, G7s = 104, G7 = 103, F7s = 102, F7 = 101, E7 = 100,

D7s = 99, D7 = 98, C7s = 97, C7 = 96, B6 = 95, A6s = 94, A6 = 93, G6s = 92, G6 = 91, F6s = 90, F6 = 89,

E6 = 88, D6s = 87, D6 = 86, C6s = 85, C6 = 84, B5 = 83, A5s = 82, A5 = 81, G5s = 80, G5 = 79, F5s = 78,

F5 = 77, E5 = 76, D5s = 75, D5 = 74, C5s = 73, C5 = 72, B4 = 71, A4s = 70, A4 = 69, G4s = 68, G4 = 67,

F4s = 66, F4 = 65, E4 = 64, D4s = 63, D4 = 62, C4s = 61, C4 = 60, B3 = 59, A3s = 58, A3 = 57, G3s = 56,

G3 = 55, F3s = 54, F3 = 53, E3 = 52, D3s = 51, D3 = 50, C3s = 49, C3 = 48, B2 = 47, A2s = 46, A2 = 45,

G2s = 44, G2 = 43, F2s = 42, F2 = 41, E2 = 40, D2s = 39, D2 = 38, C2s = 37, C2 = 36, B1 = 35, A1s = 34,

A1 = 33, G1s = 32, G1 = 31, F1s = 30, F1 = 29, E1 = 28, D1s = 27, D1 = 26, C1s = 25, C1 = 24, B0 = 23,

A0s = 22, A0 = 21

};
enum Voice

{

X1 = C2, X2 = D2, X3 = E2, X4 = F2, X5 = G2, X6 = A2, X7 = B2,

L1 = C3, L2 = D3, L3 = E3, L4 = F3, L5 = G3, L6 = A3, L7 = B3,

M1 = C4, M2 = D4, M3 = E4, M4 = F4, M5 = G4, M6 = A4, M7 = B4,

H1 = C5, H2 = D5, H3 = E5, H4 = F5, H5 = G5, H6 = A5, H7 = B5,

LOW_SPEED = 500, MIDDLE_SPEED = 400, HIGH_SPEED = 300,

_ = 0XFF

};

void Wind()

{

HMIDIOUT handle;

midiOutOpen(&handle, 0, 0, 0, CALLBACK_NULL);

midiOutShortMsg(handle, 34 << 8 | 0xC0);

int volume = 0x7f;

int voice = 0x0;

int sleep = 1000;

int wind[] =

{

400,0,L7,M1,M2,M3,300,L3,0,M5,M3,300,L2,L5,2,_,0,L7,M1,M2,M3,300,L2,0,M5,M3,M2,M3,M1,M2,L7,M1,300,L5,0,L7,M1,M2,M3,300,L3,0,M5,M3,300,L2,L5,2,_,0,L7,M1,M2,M3,300,L2,0,M5,M3,M2,M3,M1,M2,L7,M1,300,L5,

0,L7,M1,M2,M3,300,L3,0,M5,M3,300,L2,L5,2,_,0,L7,M1,M2,M3,300,L2,0,M5,M3,M2,M3,M1,M2,L7,M1,300,L5,0,L7,M1,M2,M3,300,L3,0,M5,M3,300,L2,L5,2,_,

0,M6,M3,M2,L6,M3,L6,M2,M3,L6,_,_,_,

M2,700,0,M1,300,M2,700,0,M1,300,M2,M3,M5,0,M3,700,300,M2,700,0,M1,300,M2,700,0,M1,M2,M3,M2,M1,300,L5,_,

M2,700,0,M1,300,M2,700,0,M1,300,M2,M3,M5,0,M3,700,300,M2,700,0,M3,300,M2,0,M1,700,300,M2,_,_,_,

M2,700,0,M1,300,M2,700,0,M1,300,M2,M3,M5,0,M3,700,300,M2,700,0,M3,300,M2,0,M1,700,300,L6,_,

0,M3,M2,M1,M2,300,M1,_,0,M3,M2,M1,M2,300,M1,700,0,L5,M3,M2,M1,M2,300,M1,_,_,_,

M1,M2,M3,M1,M6,0,M5,M6,300,_,700,0,M1,300,M7,0,M6,M7,300,_,_,M7,0,M6,M7,300,_,M3,0,H1,H2,H1,M7,300,M6,M5,M6,0,M5,M6,_,M5,M6,M5,300,M6,0,M5,M2,300,_,0,M5,700,300,M3,_,_,_,

M1,M2,M3,M1,M6,0,M5,M6,300,_,700,0,M1,300,M7,0,M6,M7,300,_,_,M7,0,M6,M7,300,_,M3,0,H1,H2,H1,M7,300,M6,M5,M6,0,H3,H3,300,_,M5,M6,0,H3,H3,300,_,0,M5,700,300,M6,_,_,_,_,_,

H1,H2,H3,0,H6,H5,300,_,0,H6,H5,300,_,0,H6,H5,300,_,0,H2,H3,300,H3,0,H6,H5,300,_,0,H6,H5,300,_,0,H6,H5,300,_,0,H2,H3,300,H2,0,H1,M6,300,_,0,H1,H1,300,H2,0,H1,300,M6,700,0,_,300,H1,700,H3,_,0,H3,H4,H3,H2,H3,300,H2,700,

H1,H2,H3,0,H6,H5,_,H6,H5,_,H6,H5,300,_,H3,H3,0,H6,H5,_,H6,H5,_,H6,H5,700,300,H3,700,H2,0,H1,M6,700,300,

H3,700,H2,0,H1,300,M6,700,H1,H1,_,_,_,_,_,

0,M6,300,H3,700,H2,0,H1,M6,700,300,H3,H2,700,300,0,H1,M6,300,700,H1,H1,_,_,

0,L7,M1,M2,M3,300,L3,0,M5,M3,300,L2,L5,2,_,0,L7,M1,M2,M3,300,L2,0,M5,M3,M2,M3,M1,M2,L7,M1,300,L5,0,L7,M1,M2,M3,300,L3,0,M5,M3,300,L2,L5,2,_,

0,M6,M3,M2,L6,M3,L6,M2,M3,L6,_,_,_,



M2,700,0,M1,300,M2,700,0,M1,300,M2,M3,M5,0,M3,700,300,M2,700,0,M1,300,M2,700,0,M1,M2,M3,M2,M1,300,L5,_,

M2,700,0,M1,300,M2,700,0,M1,300,M2,M3,M5,0,M3,700,300,M2,700,0,M3,300,M2,0,M1,700,300,M2,_,_,_,

M2,700,0,M1,300,M2,700,0,M1,300,M2,M3,M5,0,M3,700,300,M2,700,0,M3,300,M2,0,M1,700,300,L6,_,

0,M3,M2,M1,M2,300,M1,_,0,M3,M2,M1,M2,300,M1,700,0,L5,M3,M2,M1,M2,300,M1,_,_,_,

M1,M2,M3,M1,M6,0,M5,M6,300,_,700,0,M1,300,M7,0,M6,M7,300,_,_,M7,0,M6,M7,300,_,M3,0,H1,H2,H1,M7,300,M6,M5,M6,0,M5,M6,_,M5,M6,M5,300,M6,0,M5,M2,300,_,0,M5,700,300,M3,_,_,_,

M1,M2,M3,M1,M6,0,M5,M6,300,_,700,0,M1,300,M7,0,M6,M7,300,_,_,M7,0,M6,M7,300,_,M3,0,H1,H2,H1,M7,300,M6,M5,M6,0,H3,H3,300,_,M5,M6,0,H3,H3,300,_,0,M5,700,300,M6,_,_,_,_,_,



H1,H2,H3,0,H6,H5,300,_,0,H6,H5,300,_,0,H6,H5,300,_,0,H2,H3,300,H3,0,H6,H5,300,_,0,H6,H5,300,_,0,H6,H5,300,_,0,H2,H3,300,H2,0,H1,M6,300,_,0,H1,H1,300,H2,0,H1,300,M6,700,0,_,300,H1,700,H3,_,0,H3,H4,H3,H2,H3,300,H2,700,

H1,H2,H3,0,H6,H5,_,H6,H5,_,H6,H5,300,_,H3,H3,0,H6,H5,_,H6,H5,_,H6,H5,700,300,H3,700,H2,0,H1,M6,700,300,

H3,700,H2,0,H1,300,M6,700,H1,H1,_,_,_,_,_,



H1,H2,H3,0,H6,H5,300,_,0,H6,H5,300,_,0,H6,H5,300,_,0,H2,H3,300,H3,0,H6,H5,300,_,0,H6,H5,300,_,0,H6,H5,300,_,0,H2,H3,300,H2,0,H1,M6,300,_,0,H1,H1,300,H2,0,H1,300,M6,700,0,_,300,H1,700,H3,_,0,H3,H4,H3,H2,H3,300,H2,700,

H1,H2,H3,0,H6,H5,_,H6,H5,_,H6,H5,300,_,H3,H3,0,H6,H5,_,H6,H5,_,H6,H5,700,300,H3,700,H2,0,H1,M6,700,300,

H3,700,H2,0,H1,300,M6,700,H1,H1,_,_,_,_,_,



H1,H2,H3,0,H6,H5,300,_,0,H6,H5,300,_,0,H6,H5,300,_,0,H2,H3,300,H3,0,H6,H5,300,_,0,H6,H5,300,_,0,H6,H5,300,_,0,H2,H3,300,H2,0,H1,M6,300,_,0,H1,H1,300,H2,0,H1,300,M6,700,0,_,300,H1,700,H3,_,0,H3,H4,H3,H2,H3,300,H2,700,

H1,H2,H3,0,H6,H5,_,H6,H5,_,H6,H5,300,_,H3,H3,0,H6,H5,_,H6,H5,_,H6,H5,700,300,H3,700,H2,0,H1,M6,700,300,

H3,700,H2,0,H1,300,M6,700,H1,H1,_,_,_,_,_,



0,M6,300,H3,700,H2,0,H1,M6,700,300,H3,H2,700,300,0,H1,M6,300,700,H1,H1,_,_,_,_,_,_,_,

};

for (auto i : wind) {

if (i == LOW_SPEED || i == HIGH_SPEED || i == MIDDLE_SPEED) {

sleep = i;//Sleep(i/2);

continue;

}

if (i == 0) { sleep = 175; continue; }

if (i == 700) { Sleep(175); continue; }

if (i == _) {

Sleep(500);

continue;

}

// if (i == 900) volume += 100;

voice = (volume << 16) + ((i) << 8) + 0x90;





midiOutShortMsg(handle, voice);

cout << voice << endl;

Sleep(sleep);

}

midiOutClose(handle);

}



int main()

{



Wind();

return 0;

}































植物大战僵尸

加载背景图片

1
2
3
#include"tools.h"
#include<graphics.h> //easyx图形库的头文件```
#include<stdio.h>

首先啊我们对我们初学者最感兴趣的

就是那个游戏的背景是吧

游戏背景加载游戏背景图片

背景图片的话有两种加载方式

第一种是把背景图片

直接打印到我们窗口里面来

但这种方式会它会比较慢

我经常调的会比较慢

第二种方式的话

我就定义一个全局变量

它用来表示背景图片的

所以我们要加载啊

就从硬盘的那个背景图片

把它加载到我们这边里面来

怎样价值呢

1
2
loadimage(&background1, "res/bg.jpg")
initgraph(weight,height);

注意啊

加载的时候这里要加个取地址符号

后面是我们这个啊路径呢

哎好像我们素材的路径打开所在文件夹

就是我们的res目录吧

目录下面的这个bg.jpg啊

这是我们的背景图片

好像也是这个不建议用绝对路径

有同学喜欢用这个啊

绝对路径很长很长的

这个方不方便

而且项目改变位置你就失效了

必须点接笔记好

加上之后它这里有个错误提示啊

老鸟的话就知道了啊

这是很多解决办法

根本原因是字符集的原因造成的

所以我们这里只需要什么呢

最简单的方式是需要改变它的项属性

右键单击项目名称

选择属性

弹出属性窗口啊

这里选择高级好这个字符集

把它改成多字节字符集

这样的话我们背景的图片就已经加载好了

但是这个时候的话他是不会啊

不会显示了

跑起来特别显示的啊

因为它放在内存变量里面是吧

所以我们要把它显示出来的话

还要额外实现它显示出来怎么办呢

诶那我们肯定要什么要先创建这个什么

创建这个游戏窗口

显示到窗口里面来吧

mod的话还是控制台呀

创建一个游戏的图形窗口

1
initgraph(weight,height);

啊这个是一直插图形库的结构

很多初学者的话

这个啊担心记不住啊

没关系啊

有个印象就行了

然后查下笔记

看下我的笔记就可以了

它有两个参数啊

第一个窗口的宽度

还有窗户的高度

穿过好多宽多高呢

啊这个游啊这个相机里哈哈他来算啊

这个游戏要多宽多高好看啊

我们这里来啊

直接复刻的那个经典的总大战僵尸啊

按照他的比例的话

我选择这个宽度900x600

900x9也可以这样写

900 600

但这样写就不专业啊是吧

万一以后更改了

所以我们可以把它定义成一个红或者

cos变量都行

我们这里定义成一个红

这c语言的基本的语法是吧

1
2
#define height 600
#define weight 900

初始化加载图片

1
2
void gameinit() {
loadimage(&background1, "res/bg.jpg");}

这样的话我们最简单的初始化就做好了

你看被图片已经加载到我们的变量里面来了

窗口也已经创建好了

好咱们可以跑起来了

哈哈这时候跑的话肯定是一片黑是吧

大家也可以先试一下啊

再加个暂停

因为你不加暂停的话

程序直接gg啊

窗户都来不及

1
2
system("pause");
return 0;

你看窗户已经出来了

我这个时候都出不来的话

那说明这个环境没有搭配好啊

要重新重新装一下

这个一直插图形库

好然后我们在你你窗口

但是我们是黑的吧

啊我们没有看到我们最关心的这个游戏背景

怎么显示呢

这种啊也可以了解分享开那个专业的开发方式

单一的功能啊

我们要什么一定要封装成一个函数

所以我们也给它封装一个更新

update

问那个更新窗口

这是表示更新啊

这个游戏窗口的update问的

但你有其他的名字也是没问题的

再买定

更新窗口

更新窗口的话就是把我们的背景图片打开

打出来写出来

用反应组叫渲染bot image

他就是专门把一个图片渲染出来显示出来的

它有呃多个参数

第一个参数其实这是什么意思

我先先写吧

等一下把调查说明image pg好

void updatewindow() {	putimage(0, 0, &background1);}

我们在打印一个窗图片的时候

啊啊我们要确定它的一个坐标

几乎所有的图形库它都是这种坐标概念

哈哈哈哈哈啊

我们的游戏

植物大战僵尸的最初始的界面就已经出来了

不过啊还非常简陋

很多要素都没有

比如说我们的这个啊全面

他在上面的有个类似一个背包内的一个啊

有一个啊按钮啊

有个按钮可以选择我们各种植物的啊

没有出来

还僵尸也没跑过来

好这些

我们看来下一步再做好

这里的话

这就非常简单啊

主要是开发环境的一个设置

一个开环境要使用这个vs

建议vs用其他开环境也可以啊

但是比较麻烦一下要绕左

为了配置另外装一直插图形库

好把素材导进来啊

我们就可以直接看到我们的这个

最初始的界面了

下一节我们就来做我们的坠子上面啊

上面这个啊这个啊

工具栏

我们把这个背景这么做下来

我们做工具栏的话其实不是一样的吗

啊只是在不同的位置啊

把一个图片把它做显示出来就可以了

那中间呢它本质上也是一张图片

所以的话呢我们在这里定义一个啊图片变量

好接下来我们要相同的背景

相同背景处理方式

相同的背景要加

要初始化吗

我们这里也是初始化啊

把这个啊

这个硬盘里的这个图片加载到我们的内存面

1
2
loadimage(&wupinlan, "res/bar.png");
putimage(100, 0, &wupinlan);

好这样的话

我们的这个

工具栏就有了

但是还没有什么呢

一个没有阳光值

这有阳光值

再一个的话

他这里应该有放放置很多植物的啊

我可以我在我这里称作植物卡牌

有很多植物的

然后我们选这么一个植物啊

就可以拖放到下面进行种植

所以呢这里要放置各种植物卡牌啊

那现在呢啊所以现在我们来做写下

a实现这个游戏

工具栏是吧

好你说了哎

实现这个诶工具栏

中的植物卡牌

植物卡牌有很多

一种植物的话就意思一种卡牌

这里最多有有可以考七种

那么相同的方式啊

要先定义一个内存变量来表示我们的植物卡牌

但是你大家发现没有

这植物卡片很多建有多个变量

那么而且它是相同性质

那我就想到了我们c语言的数组

定一个图片

数组image

image这个

其他名字啊log有起名纠结症

植物卡牌卡牌

看看有多有几种呢

1357是吧对

1
IMAGE zhiwu[zhiwucount];

所以我们最好也可以用一次吗

用枚举的方式来定义数量(与宏比较)

1
enum { wandou, xiangrikui, jianguoqiang, hanbingsheshou, tudoulei, zhiwucount };

加载植物卡片图片

1
2
3
4
5
6
7
8
9
char name[32];

for (int i = 0; i < zhiwucount; i++) {

loadimage(&zhiwu[i], "res/");
sprintf_s(name, sizeof(name),"res/Cards/card_%d.png",i+1);重点记忆,此时植物卡片资源命名格式相同
loadimage(&zhiwu[i], name);
}

ok好

我们的卡牌就全部就加载好了

加载好之后

进行渲染

这位置怎么确定啊

这个比较简单

你看只要确定这个起始位置啊

按照每每个是它的一个距离啊

我们用最简单的一个数学运算

我们就可以把它算出来啊

这确定这个边界就可以了

int x = 189;
 for (int i = 0; i < zhiwucount; i++) {
	putimage(x, 5, &zhiwu[i]);
	x = x + 70;}

这样的话我们的植物卡牌诶就已经诶写的好了

下一步的话我们就要嗯做拖放啊

种植植物拖放

我们准备来实现我们这个植物的一个种植

也就是好看一下我们之前的效果

也就是我们这种鼠标选中啊一个卡牌

先优化一下代码

1
2
3
4
5
6
7
8
9
10
int main(){
gameinit();
while (1) {
userclick();
updatewindow();
}新加入了while循环,直到用户做了退出操作 或者直接关掉好
system("pause");
return 0;

}

这里呢哎我们就首先要进行个什么

等待用户的处理

用户的点击

那么定义一个user click

用户单击

此时页面会不停进行闪动,要加入双缓冲

双缓冲

所谓双缓冲啊

就是在嗯你看原来的逻辑是先打印背景啊

再打印这个工具栏啊

好在打印卡牌啊

一步一步打印的

那在肯定会它打印的过程中啊

画面就会有闪烁

怎么办呢

我们就先使用双缓冲

就啊先怎么写好

先写出来

所谓双缓冲就是先不直接打印到屏幕啊

这里开始缓冲

先打印在一块特殊内内存里面啊

不打印到屏幕

然后把全部都打印完之后

到内存里面准备好之后

再一次性的夸夸刷出去

再打印出来


结束啊

双缓冲就是正式啊

把它打印到这个嗯

窗口卖的话就不会抖动了哈

1
2
3
4
5
6
7
8
9
10
11
12
13
void updatewindow() {
BeginBatchDraw();双缓冲开始
putimage(0, 0, &background1); putimagePNG(100, 0, &wupinlan);
int x = 189;

for (int i = 0; i < zhiwucount; i++) {
putimage(x, 5, &zhiwu[i]);
x = x + 70;
确定卡片放置位置

}
EndBatchDraw();双缓冲结束
}

我们再跑起来看一下就没有问题了

信息事件(鼠标点击等)

但是我们现在的问题是要做什么啊

做这个嗯

就做这个用户单击用户点击操作种植植物

种植植物的话要先选中一个植物

然后再拖放啊

这样一个动作啊

让我们来处理一下啊

先选中鼠标

左键单击选中

那我就要先判断他有没有这个有没有消息啊

用这个来判断有没有鼠标

鼠标消息

1
2
3
void userclick() {
ExMessage msg;定义信息事件
peekmessage(&msg);检测信息是否发生

他的判断当前有没有消息

你鼠标移动鼠标点击鼠标抬起来啊

按键按下去

这都会产生一个消息

为什么不直接读鼠标信息

直接getmessage

你直接读消息的话

如果当时没有消息呢

那就会卡住啊

程序卡住

所以来个什么peekmessage

它就是一个判断有没有消息

有消息

那就返回为真

没有消息就反馈一下它

程序不会阻塞它

参数的话是一个啊消息类型message

啊消息好把他地址带进来

如果有消息的话

那消息的具体的啊值啊

就保存在这个message里面

那我就做个判断

如果if如果有消息有消息的话

结构为增

如果有消息啊

然后还判断它是鼠标左键按下去是吧

但如果消息的message message啊

没消息的类型是左键l l8 n按下去l8 n down

左键按下

如果是左键按下

我们就怎么怎么样怎么样是吧

其实还有很多

还有如果是这个

等一下植物种植的时候

还会鼠标拖动是吧

因为在鼠标移动过程中啊

我们要啊在移动过程中

他那个跟随鼠标

它跟着闪动啊

他这种效果

我在选中它

鼠标在移动的时候啊

在鼠标移到哪里

他的鼠标周围它就跟着一个植物在在拖动啊

还有抬起来

鼠标按键抬起来

那就把植物就正式粽子下去

嗯再看一下啊

我们先做你鼠标左键按下去

按下去的话

我们要判定他按的位置

其他位置按下去

它是不应该有反应的

所以我们要判断它单击的位置

对不对啊

检测位置是否正确

1
2
3
4
5
6
7
8
void userclick() {
ExMessage msg;
if(peekmessage(&msg)){
if(msg.message=WM_LBUTTONDOWN){if(msg.x>189&&msg.x<189+zhiwucount*70&&msg.y>0&&msg.y<100){
}判断位置
else if(msg.message=WM_MOUSEMOVE){}
else if(msg.message=WM_LBUTTONUP){}
}

判定他是先选择之后再做拖动

定义一个状态变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void userclick() {
ExMessage msg;
static int status = 0;//定义状态
if(peekmessage(&msg)){
if(msg.message=WM_LBUTTONDOWN){if(msg.x>189&&msg.x<189+zhiwucount*70&&msg.y>0&&msg.y<100)
{
int index = (msg.x - 189) / 70;
printf("%d\n",index);
status = 1;//若按下则为1
}
else if(msg.message=WM_MOUSEMOVE && status==1){}//增加判断条件
else if(msg.message=WM_LBUTTONUP){}
}

我怎么知道在哪个位置呢 不知道的 那怎么办唉 用c语言的方式的话

最简单的方式就定一个全局变量

显示拖动位置

1
2
3
4
int curx,cury;
else if(msg.message=WM_MOUSEMOVE && status==1){
msg.x = curx; msg.y = cury;
}

但拖动时不能显示卡牌 应该是卡牌那个背景去掉之后 他 我们应该显示这个植物 不是显示这个卡牌本身

通过实现一个不停的播放 让它达到一个动画的效果

1
2
3
IMAGE* imgzhiwu[zhiwucount][20];//在刚开始定义植物动画二维数组指针

memset(imgzhiwu, 0, sizeof(imgzhiwu));//清零内存

在加载植物卡牌后加入一个for循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for (int i = 0; i < zhiwucount; i++) {
//加载植物
loadimage(&zhiwu[i], "res/");
sprintf_s(name, sizeof(name), "res/Cards/card_%d.png", i + 1);
loadimage(&zhiwu[i], name);
for (int j = 0; j < 20; j++) {
//植物动画

sprintf_s(name, sizeof(name), "res/zhiwu/%d/%d.png", i, j + 1);
//判断文件是否存在
if (isexist(name)) {
loadimage(imgzhiwu[i][j], name);
}
else { break; }
}
}

各种植物动画所需要的图片数量不同,需要写一个函数进行判断

1
2
3
4
5
6
7
8
9
10
bool isexist(const char* name) {
FILE* fp = fopen(name, "r");
if (fp == NULL) {
return false;
}
else {
fclose(fp);
return true;
}
}

既然将内存设置为0,则需要同时创建出图片大小的内存区域

1
imgzhiwu[i][j] = new IMAGE;//分配内存

确定拖动植物种类

1
2
3
int curzhiwu;//判断选择的植物种类,全局变量,选中为>0,不选中为0
curzhiwu=index+1;

鼠标松开后

1
2
else if (msg.message == WM_LBUTTONUP && status == 1) {
status=0;}

放置植物

先定义结构体

1
2
3
4
5
struct zhiwu{
int type;//0:没有植物 1:第一种植物
int frameindex;//动画序列帧的序号
}
struct zhiwu[3][9]有三行九列的植物

给结构体开辟内存

1
memset(map,0,sizeof(map));

种植物

1
2
3
4
int row=(msg.y-179)/102;表示种的是那一行
int col=(msg.x-256)/81;列
printf("%d,%d\n",row,col);//可打印一下结果

此时可优化一下,种在边界时不发生反应

1
if(msg.x>256&&msg.y>179&&msg.y<489){}

若种植位置正确

1
2
3
if (map[row][col].type == 0) {
map[row][col].type = curZhiWu;
map[row][col].frameIndex = 0; }

渲染图片

1
2
3
4
5
6
7
8
9
10
11
12
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-1;
int frameIndex = map[i][j].frameIndex;
putimagePNG(x, y, imgZhiWu[zhiWuIndex - 1][frameIndex]);
}
}
}

植物随风摇摆的动画效果