当前位置:   article > 正文

C语言实现植物大战僵尸(完整版)_植物大战僵尸c语言源代码

植物大战僵尸c语言源代码

实现这个游戏需要Easy_X

这个在我前面一篇C++之番外篇爱心代码有程序教你怎么下载,大家可自行查看

然后就是需要植物大战僵尸的素材和音乐,需要的可以私信

0106173ffe234c87b4de39947f7b4498.png

首先是main.cpp

  1. //开发日志
  2. //1导入素材
  3. //2实现最开始的游戏场景
  4. //3实现游戏顶部的工具栏
  5. //4实现工具栏里面的游戏卡牌
  6. #define WIN_WIDTH 900
  7. #define WIN_HEIGHT 600
  8. //定义植物类型
  9. enum { WAN_DOU, XIANG_RI_KUI, ZHI_WU_COUNT };
  10. #include<stdio.h>
  11. #include<graphics.h>//easyx图形库的头文件
  12. #include"tools.h"
  13. #include"vector2.h"//向量引用
  14. #include<time.h>
  15. #include<math.h>
  16. #include<mmsystem.h>//导入音乐收集阳光的时候
  17. //导入一个库
  18. #include<Windows.h>
  19. #pragma comment(lib,"winmm.lib")
  20. IMAGE imgBg;//全局变量表示背景图片
  21. IMAGE imgBar;//工具栏
  22. IMAGE imgCards[ZHI_WU_COUNT];
  23. IMAGE* imgZhiwu[ZHI_WU_COUNT][20];
  24. int curX, curY;//当前选中的植物,在拖动过程中的位置
  25. int curZhiwu;//0没有选中。 1选中了第一种植物
  26. struct zhiwu
  27. {
  28. int type;//植物种类 0:表示没有植物 1:第一种植物
  29. int frameIndex;//序列帧的序号
  30. bool catched;//是否被僵尸捕获
  31. int deadTime;//死亡倒计时
  32. int x, y;
  33. int timer;
  34. };
  35. struct zhiwu map[3][9];
  36. //定义一个阳光结构体
  37. enum { SUNSHINE_DOWN, SUNSHINE_GROUND, SUNSHINE_COLLECT, SUNSHINE_RPODUCT };
  38. struct sunshineBall
  39. {
  40. int x, y;//阳光球飘落位置的坐标(x不变)
  41. int frameIndex;//当前图片显示帧的序号
  42. //阳光有一个落点设置
  43. int destY;//飘落位置的Y坐标
  44. bool used;//判断是否在使用
  45. //计时器
  46. int timer;
  47. float xoff;
  48. float yoff;
  49. float t;//贝塞尔曲线时间点0..1
  50. vector2 p1, p2, p3,p4;//分别对应起点终点控制点
  51. vector2 pCur;//当前时刻阳光球的位置
  52. float speed;
  53. int status;//阳光状态
  54. };
  55. struct sunshineBall balls[10];//设置10个阳光池
  56. IMAGE imgSunshineBall[29];//加载阳光图片,一共29放入数组中
  57. int sunshine;
  58. struct zm
  59. {
  60. int x, y;
  61. int row;
  62. int frameIndex;
  63. bool used;
  64. int speed;
  65. int blood;//僵尸血条
  66. bool dead;
  67. bool eating;//正在吃植物
  68. };
  69. struct zm zms[10];
  70. IMAGE imgZM[22];
  71. IMAGE imgZMDead[20];
  72. IMAGE imgZMEat[21];
  73. //子弹的数据类型
  74. struct bullet
  75. {
  76. int x, y;
  77. int row;
  78. bool used;
  79. int speed;
  80. bool blast;//定义豌豆射出的子弹是否发生爆炸
  81. int frameIndex;//帧序号
  82. };
  83. struct bullet bullets[30];
  84. IMAGE imgBulletNormal;
  85. IMAGE imgBallBlast[4];
  86. bool fileExist(const char* name)
  87. {
  88. FILE* fp = fopen(name, "r");//r表示文件的读取
  89. if (fp == NULL)
  90. {
  91. return false;
  92. }
  93. else
  94. {
  95. fclose(fp);
  96. return true;
  97. }
  98. }
  99. void gameInit()
  100. {
  101. //加载游戏背景图片
  102. //把字符集修改成多字符字符集
  103. loadimage(&imgBg,"res/bg.jpg");
  104. loadimage(&imgBar,"res/bar5.png");
  105. memset(imgZhiwu, 0, sizeof(imgZhiwu));
  106. //初始化植物卡牌
  107. memset(map, 0, sizeof(map));
  108. char name[64];
  109. for (int i = 0; i < ZHI_WU_COUNT; i++)
  110. {
  111. //生成植物卡牌的文件名
  112. sprintf_s(name,sizeof(name),"res/Cards/card_%d.png",i+1);//加植物向枚举类型中加
  113. loadimage(&imgCards[i], name);
  114. for (int j = 0; j < 20; j++)
  115. {
  116. sprintf_s(name, sizeof(name), "res/zhiwu/%d/%d.png", i ,j+1);
  117. //先判断这个文件是否存在
  118. //定义一个接口
  119. if (fileExist(name))
  120. {
  121. imgZhiwu[i][j] = new IMAGE;
  122. //.....加载
  123. loadimage(imgZhiwu[i][j],name);
  124. }
  125. else
  126. {
  127. break;
  128. }
  129. }
  130. }
  131. curZhiwu = 0;
  132. sunshine = 50;
  133. memset(balls, 0, sizeof(balls));
  134. for (int i = 0; i < 29; i++)
  135. {
  136. sprintf_s(name, sizeof(name), "res/sunshine/%d.png",i+1);
  137. loadimage(&imgSunshineBall[i], name);
  138. }
  139. //配置随机种子,让阳光真正的随机
  140. srand((unsigned)time(NULL));
  141. //创建游戏的图形窗口
  142. initgraph(WIN_WIDTH, WIN_HEIGHT,1);
  143. //设置字体
  144. LOGFONT f;
  145. gettextstyle(&f);
  146. f.lfHeight = 30;
  147. f.lfWeight = 15;
  148. strcpy(f.lfFaceName, "Segoe UI Black");
  149. //抗锯齿
  150. f.lfQuality = ANTIALIASED_QUALITY;
  151. settextstyle(&f);
  152. setbkmode(TRANSPARENT);
  153. setcolor(BLACK);
  154. //初始化僵尸数据
  155. memset(zms, 0, sizeof(zms));
  156. int i = 0;
  157. for (i = 0; i < 22; i++)
  158. {
  159. sprintf_s(name,sizeof(name),"res/zm/%d.png",i+1);
  160. loadimage(&imgZM[i],name);
  161. }
  162. loadimage(&imgBulletNormal,"res/bullets/bullet_normal.png");
  163. memset(bullets,0,sizeof(bullets));
  164. //初始化豌豆子弹的帧图片数组
  165. loadimage(&imgBallBlast[3],"res/bullets/bullet_blast.png");
  166. for (int i = 0; i < 3; i++)
  167. {
  168. float k = (i + 1) * 0.2;
  169. loadimage(&imgBallBlast[i],"res/bullets/bullet_blast.png",
  170. imgBallBlast[3].getwidth()*k,
  171. imgBallBlast[3].getheight()*k,true);
  172. }
  173. for (int i = 0; i < 20; i++)
  174. {
  175. sprintf_s(name,sizeof(name),"res/zm.dead/%d.png",i+1);
  176. loadimage(&imgZMDead[i],name);
  177. }
  178. for (int i = 0; i < 21; i++)
  179. {
  180. sprintf_s(name,"res/zm_eat/%d.png",i+1);
  181. loadimage(&imgZMEat[i],name);
  182. }
  183. }
  184. void drawZM()
  185. {
  186. int zmCount = sizeof(zms) / sizeof(zms[0]);
  187. for (int i = 0; i < zmCount; i++)
  188. {
  189. if (zms[i].used)
  190. {
  191. //IMAGE* img = &imgZM[zms[i].frameIndex];
  192. //IMAGE* img = (zms[i].dead) ? imgZMDead : imgZM;
  193. IMAGE* img = NULL;
  194. if (zms[i].dead) img = imgZMDead;
  195. else if (zms[i].dead) img = imgZMEat;
  196. else img = imgZM;
  197. img += zms[i].frameIndex;
  198. putimagePNG(
  199. zms[i].x,
  200. zms[i].y-img->getheight(),
  201. img);
  202. }
  203. }
  204. }
  205. void drawSunshines()
  206. {
  207. int ballMax = sizeof(balls) / sizeof(balls[0]);
  208. for (int i = 0; i < ballMax; i++)
  209. {
  210. if (balls[i].used || balls[i].xoff)
  211. {
  212. IMAGE* img = &imgSunshineBall[balls[i].frameIndex];
  213. //putimagePNG(balls[i].x, balls[i].y, img);
  214. putimagePNG(balls[i].pCur.x, balls[i].pCur.y, img);
  215. }
  216. }
  217. }
  218. void updateWindow()
  219. {
  220. BeginBatchDraw();//开始缓冲
  221. putimage(0, 0, &imgBg);
  222. //putimage(250, 0, &imgBar);
  223. putimagePNG(250, 0, &imgBar);
  224. for (int i = 0; i < ZHI_WU_COUNT; i++)
  225. {
  226. int x = 338 + i * 65;
  227. int y = 6;
  228. putimage(x, y, &imgCards[i]);
  229. }
  230. for (int i = 0; i < 3; i++)
  231. {
  232. for (int j = 0; j < 9; j++)
  233. {
  234. if (map[i][j].type > 0)
  235. {
  236. //int x = 256 + j * 81;
  237. //int y = 179 + i*102+14;
  238. int Zhiwutype = map[i][j].type - 1;
  239. int index = map[i][j].frameIndex;
  240. //putimagePNG(x, y, imgZhiwu[Zhiwutype][index]);
  241. putimagePNG(map[i][j].x, map[i][j].y,imgZhiwu[Zhiwutype][index]);
  242. }
  243. }
  244. }
  245. //渲染拖动过程中的植物
  246. if (curZhiwu)
  247. {
  248. IMAGE* img = imgZhiwu[curZhiwu - 1][0];
  249. putimagePNG(curX - img->getwidth()/2, curY - img->getheight()/2, img);
  250. }
  251. drawSunshines();//绘制阳光
  252. char scoreText[8];
  253. sprintf_s(scoreText, sizeof(scoreText),"%d",sunshine);
  254. outtextxy(276,67,scoreText);//输出阳光分数
  255. drawZM();//渲染僵尸
  256. //渲染阳光
  257. int bulletMax = sizeof(bullets) / sizeof(bullets[0]);
  258. for (int i = 0; i < bulletMax; i++)
  259. {
  260. if (bullets[i].used)
  261. {
  262. if (bullets[i].blast)
  263. {
  264. IMAGE* img = &imgBallBlast[bullets[i].frameIndex];
  265. putimagePNG(bullets[i].x, bullets[i].y, img);
  266. }
  267. else
  268. {
  269. putimagePNG(bullets[i].x, bullets[i].y, &imgBulletNormal);
  270. }
  271. }
  272. }
  273. EndBatchDraw();//结束双缓冲
  274. }
  275. void collectSunshine(ExMessage* msg)
  276. {
  277. int count = sizeof(balls) / sizeof(balls[0]);
  278. int w = imgSunshineBall[0].getwidth();
  279. int h = imgSunshineBall[0].getheight();
  280. for (int i = 0; i < count; i++)
  281. {
  282. if (balls[i].used)
  283. {
  284. /*int x = balls[i].x;
  285. int y = balls[i].y;*/
  286. int x = balls[i].pCur.x;
  287. int y = balls[i].pCur.y;
  288. if (msg->x > x && msg->x<x + w && msg->y>y && msg->y < y + h)
  289. {
  290. balls[i].used = false;
  291. balls[i].status = SUNSHINE_COLLECT;
  292. sunshine += 25;
  293. mciSendString("play res/sunshine.mp3",0,0,0);//加载音乐文件
  294. //设置阳光球的偏移量
  295. balls[i].p1 = balls[i].pCur;
  296. balls[i].p4 = vector2(262, 0);
  297. balls[i].t = 0;
  298. float distance = dis(balls[i].p1 - balls[i].p4);
  299. float off = 8.0;
  300. balls[i].speed = 1.0/(distance/off);
  301. }
  302. }
  303. }
  304. }
  305. void userClick()
  306. {
  307. ExMessage msg;//参数是消息类型
  308. static int status = 0;
  309. //如果消息有值则保存在peekmessage函数中,即为真
  310. if (peekmessage(&msg))
  311. {
  312. if (msg.message == WM_LBUTTONDOWN)//WM_LBUTTONDOWN左键按下去的意思
  313. {
  314. if (msg.x > 338 && msg.x < 338 + 65*ZHI_WU_COUNT && msg.y < 96)//定义坐标判断点击的是否为植物
  315. {
  316. int index = (msg.x - 338) / 65;
  317. status = 1;
  318. curZhiwu = index + 1;
  319. }
  320. else
  321. {
  322. collectSunshine(&msg);
  323. }
  324. }
  325. else if (msg.message == WM_MOUSEMOVE&&status==1)//WM_MOUSEMOVE鼠标移动
  326. {
  327. //记录当前位置
  328. curX = msg.x;
  329. curY = msg.y;
  330. }
  331. //鼠标抬动植物就种下去
  332. else if (msg.message == WM_LBUTTONUP)
  333. {
  334. if (msg.x > 256 && msg.y > 179 && msg.y < 489)
  335. {
  336. int row = (msg.y - 179) / 102;
  337. int col = (msg.x - 256) / 81;
  338. if (map[row][col].type == 0)
  339. {
  340. map[row][col].type = curZhiwu;
  341. map[row][col].frameIndex = 0;
  342. //int x = 256 + j * 81;
  343. //int y = 179 + i*102+14;
  344. map[row][col].x = 256 + col * 81;
  345. map[row][col].y = 179 + row * 102+14;
  346. }
  347. }
  348. curZhiwu = 0;
  349. status = 0;
  350. }
  351. }
  352. }
  353. void creatSunshine()
  354. {
  355. static int count = 0;
  356. static int fre = 400;
  357. count++;
  358. if (count >= fre )
  359. {
  360. fre = 200 + rand() % 200;
  361. count = 0;//满了计数器清0
  362. //从阳光池中去一个可以使用的
  363. int ballMax = sizeof(balls) / sizeof(balls[0]);
  364. int i = 0;
  365. for (i = 0; i < ballMax && balls[i].used; i++);
  366. if (i >= ballMax) return;//阳光池满了
  367. balls[i].used = true;
  368. balls[i].frameIndex = 0;
  369. //balls[i].x = 260 + rand() % (900 - 260);
  370. //balls[i].y = 60;
  371. //balls[i].destY = 200 + (rand() % 4) * 90;
  372. balls[i].timer = 0;
  373. //balls[i].xoff = 0;
  374. //balls[i].yoff = 0;
  375. balls[i].status = SUNSHINE_DOWN;
  376. balls[i].p1 = vector2(260 + rand() % (900 - 260), 60);
  377. balls[i].p4 = vector2(balls[i].p1.x, 200 + (rand() % 4) * 90);
  378. int off = 2;
  379. float distance = balls[i].p4.y - balls[i].p1.y;
  380. balls[i].speed = 1.0 / (distance / off);
  381. }
  382. //向日葵生产阳光
  383. int ballMax = sizeof(balls) / sizeof(balls[0]);
  384. for (int i = 0; i < 3; i++)
  385. {
  386. for (int j = 0; j < 9; j++)
  387. {
  388. if (map[i][j].type == XIANG_RI_KUI + 1)
  389. {
  390. map[i][j].timer++;
  391. }
  392. if (map[i][j].timer > 200)
  393. {
  394. map[i][j].timer = 0;
  395. int k = 0;
  396. for (k = 0; k < ballMax && balls[k].used; k++);
  397. if (k >= ballMax) return;
  398. balls[k].used = true;
  399. balls[k].p1 = vector2(map[i][j].x, map[i][j].y);
  400. int w = (100 + rand() % 50) * (rand() % 2 ? 1 : -1);
  401. balls[k].p4 = vector2(map[i][j].x+w,
  402. map[i][j].y+imgZhiwu[XIANG_RI_KUI][0]->getheight()-
  403. imgSunshineBall[0].getheight());
  404. balls[k].p2 = vector2(balls[k].p1.x+w*0.3,balls[k].p1.y-100);
  405. balls[k].p3 = vector2(balls[k].p1.x + w * 0.7, balls[k].p1.y + 100);
  406. balls[k].status = SUNSHINE_RPODUCT;
  407. balls[k].speed = 0.05;
  408. balls[k].t = 0;
  409. }
  410. }
  411. }
  412. }
  413. void updateSunshine()//更新阳光
  414. {
  415. int ballMax = sizeof(balls) / sizeof(balls[0]);
  416. for (int i = 0; i < ballMax; i++)
  417. {
  418. if (balls[i].used)
  419. {
  420. balls[i].frameIndex = (balls[i].frameIndex + 1) % 29;
  421. if (balls[i].status = SUNSHINE_DOWN)
  422. {
  423. struct sunshineBall* sun = &balls[i];
  424. sun->status = SUNSHINE_GROUND;
  425. sun->timer = 0;
  426. }
  427. else if (balls[i].status == SUNSHINE_GROUND)
  428. {
  429. balls[i].timer++;
  430. if (balls[i].timer > 100)
  431. {
  432. balls[i].used = false;
  433. balls[i].timer = 0;
  434. }
  435. }
  436. else if (balls[i].status == SUNSHINE_COLLECT)
  437. {
  438. struct sunshineBall* sun = &balls[i];
  439. sun->t+=sun->speed;
  440. sun->pCur = sun->p1 + sun->t * (sun->p4 - sun->p1);
  441. if (sun->t > 1)
  442. {
  443. sun->used = false;
  444. sunshine += 25;
  445. }
  446. }
  447. else if (balls[i].status == SUNSHINE_RPODUCT)
  448. {
  449. struct sunshineBall* sun = &balls[i];
  450. sun->t += sun->speed;
  451. sun->pCur = calcBezierPoint(sun->t, sun->p1, sun->p2, sun->p3, sun->p4);
  452. if (sun->t > 1)
  453. {
  454. sun->status = SUNSHINE_GROUND;
  455. sun->timer = 0;
  456. }
  457. }
  458. balls[i].frameIndex=(balls[i].frameIndex+1)%29;
  459. if (balls[i].timer == 0)
  460. {
  461. balls[i].y += 2;
  462. }
  463. if (balls[i].y >= balls[i].destY)
  464. {
  465. //balls[i].used = false;
  466. balls[i].timer++;
  467. if (balls[i].timer > 100)
  468. {
  469. balls[i].used = false;
  470. }
  471. }
  472. }
  473. }
  474. }
  475. void creatZM()
  476. {
  477. static int zmFre = 500;
  478. static int count = 0;
  479. count++;
  480. if (count > zmFre)
  481. {
  482. count = 0;
  483. zmFre = rand() % 200 + 300;
  484. }
  485. int i=0;
  486. int zmMax=sizeof(zms)/sizeof(zms[0]);
  487. for (i = 0; i < zmMax && zms[i].used; i++);
  488. if (i < zmMax)
  489. {
  490. memset(&zms[i],0,sizeof(zms[i]));
  491. zms[i].used = true;
  492. zms[i].x = WIN_WIDTH;
  493. zms[i].row = rand() % 3;
  494. zms[i].y = 172 + (1 + zms[i].row) * 100;
  495. zms[i].speed = 1;
  496. zms[i].blood = 100;
  497. zms[i].dead = false;
  498. }
  499. }
  500. void updataZM()
  501. {
  502. int zmMax = sizeof(zms) / sizeof(zms[0]);
  503. static int count = 0;
  504. count++;
  505. if (count > 2)
  506. {
  507. count = 0;
  508. //更新僵尸的位置
  509. for (int i = 0; i < zmMax; i++)
  510. {
  511. if (zms[i].used)
  512. {
  513. zms[i].x -= zms[i].speed;
  514. if (zms[i].x < 170)
  515. {
  516. printf("GAME OVER\n");
  517. MessageBox(NULL, "over", "over", 0);//待优化
  518. exit(0);
  519. }
  520. }
  521. }
  522. }
  523. static int count2 = 0;
  524. count2++;
  525. if (count2 > 4)
  526. {
  527. count2 = 0;
  528. for (int i = 0; i < zmMax; i++)
  529. {
  530. if (zms[i].used)
  531. {
  532. if (zms[i].dead)
  533. {
  534. zms[i].frameIndex++;
  535. if (zms[i].frameIndex >= 20)
  536. {
  537. zms[i].used = false;
  538. }
  539. }
  540. else if (zms[i].eating)
  541. {
  542. zms[i].frameIndex= (zms[i].frameIndex + 1) % 21;
  543. }
  544. else
  545. {
  546. zms[i].frameIndex = (zms[i].frameIndex + 1) % 22;
  547. }
  548. }
  549. }
  550. }
  551. }
  552. void shoot()
  553. {
  554. int lines[3] = { 0 };
  555. int zmCount = sizeof(zms) / sizeof(zms[0]);
  556. int bulletMax = sizeof(bullets) / sizeof(bullets[0]);
  557. int dangerX = WIN_WIDTH - imgZM[0].getwidth();
  558. for (int i = 0; i < zmCount; i++)
  559. {
  560. if (zms[i].used && zms[i].x < dangerX)
  561. {
  562. lines[zms[i].row] = 1;
  563. }
  564. }
  565. for (int i = 0; i < 3; i++)
  566. {
  567. for (int j = 0; j < 9; j++)
  568. {
  569. if (map[i][j].type == WAN_DOU + 1&&lines[i])
  570. {
  571. static int count = 0;
  572. count++;
  573. if (count > 20)
  574. {
  575. count = 0;
  576. int k = 0;
  577. for (k = 0; k < bulletMax && bullets[k].used; k++);
  578. if (k < bulletMax)
  579. {
  580. bullets[k].used = true;
  581. bullets[k].row = i;
  582. bullets[k].speed = 6;
  583. bullets[k].blast = false;
  584. bullets[k].frameIndex = 0;
  585. int zwX = 256 + j * 81;
  586. int zwY = 179 + i * 102 + 14;
  587. bullets[k].x = zwX + imgZhiwu[map[i][j].type - 1][0]->getwidth() - 10;
  588. bullets[k].y = zwY+5;
  589. }
  590. }
  591. }
  592. }
  593. }
  594. }
  595. void updataBullets()
  596. {
  597. int countMax = sizeof(bullets) / sizeof(bullets[0]);
  598. for (int i = 0; i < countMax; i++)
  599. {
  600. if (bullets[i].used)
  601. {
  602. bullets[i].x += bullets[i].speed;
  603. if (bullets[i].x > WIN_WIDTH)
  604. {
  605. bullets[i].used = false;
  606. }
  607. //子弹的碰撞爆炸
  608. if (bullets[i].blast)
  609. {
  610. bullets[i].frameIndex++;
  611. if (bullets[i].frameIndex >= 4)
  612. {
  613. bullets[i].used = false;
  614. }
  615. }
  616. }
  617. }
  618. }
  619. void checkBullet2Zm()
  620. {
  621. int bCount = sizeof(bullets) / sizeof(bullets[0]);
  622. int zCount = sizeof(zms) / sizeof(zms[0]);
  623. for (int i = 0; i < bCount; i++)
  624. {
  625. if (bullets[i].used == false || bullets[i].blast)
  626. {
  627. continue;
  628. }
  629. for (int k = 0; k < zCount; k++)
  630. {
  631. //if (zms[i].used == false) continue;
  632. if (zms[k].used == false) continue;
  633. int x1 = zms[k].x + 80;
  634. int x2 = zms[k].x + 110;
  635. int x = bullets[i].x;
  636. if (zms[k].dead == false && bullets[i].row == zms[k].row && x > x1 && x < x2)
  637. {
  638. zms[k].blood -= 20;
  639. bullets[i].blast = true;
  640. bullets[i].speed = 0;
  641. if (zms[k].blood <= 0)
  642. {
  643. zms[k].dead = true;
  644. zms[k].speed = 0;
  645. zms[k].frameIndex = 0;
  646. }
  647. break;
  648. }
  649. }
  650. }
  651. }
  652. void checkZm2Zhiwu()
  653. {
  654. int zCount = sizeof(zms) / sizeof(zms[0]);
  655. for (int i = 0; i < zCount; i++)
  656. {
  657. if (zms[i].dead) continue;
  658. int row = zms[i].row;
  659. for (int k = 0; k < 9; k++)
  660. {
  661. if (map[row][k].type == 0)
  662. {
  663. continue;
  664. }
  665. int ZhiWuX = 256 + k * 81;
  666. int x1 = ZhiWuX + 10;
  667. int x2 = ZhiWuX + 60;
  668. int x3 = zms[i].x + 80;
  669. if (x3 > x1 && x3 < x2)
  670. {
  671. if (map[row][k].catched)
  672. {
  673. map[row][k].deadTime++;
  674. if (map[row][k].deadTime > 100)
  675. {
  676. map[row][k].deadTime = 0;
  677. map[row][k].type = 0;
  678. zms[i].eating = false;
  679. zms[i].frameIndex = 0;
  680. zms[i].speed = 1;
  681. }
  682. }
  683. else
  684. {
  685. map[row][k].catched = true;
  686. map[row][k].deadTime = 0;
  687. zms[i].eating = true;
  688. zms[i].speed = 0;
  689. zms[i].frameIndex = 0;
  690. }
  691. }
  692. }
  693. }
  694. }
  695. void collisionCheck()
  696. {
  697. checkBullet2Zm();
  698. checkZm2Zhiwu();
  699. }
  700. void updateGame()
  701. {
  702. for (int i = 0; i < 3; i++)
  703. {
  704. for (int j = 0; j < 9; j++)
  705. {
  706. if (map[i][j].type > 0)
  707. {
  708. map[i][j].frameIndex++;
  709. int Zhiwutype = map[i][j].type - 1;
  710. int index = map[i][j].frameIndex;
  711. if (imgZhiwu[Zhiwutype][index] == NULL)
  712. {
  713. map[i][j].frameIndex = 0;
  714. }
  715. }
  716. }
  717. }
  718. creatSunshine();//创建阳光
  719. updateSunshine();//更新阳光状态
  720. creatZM();//创建僵尸
  721. updataZM();//更新僵尸的状态
  722. shoot();//发射豌豆子弹
  723. updataBullets();//更新豌豆子弹
  724. collisionCheck();//实现豌豆子弹和僵尸的碰撞
  725. }
  726. void startUI()
  727. {
  728. IMAGE imgBg,imgMenu1,imgMenu2;
  729. loadimage(&imgBg,"res/menu.png");
  730. loadimage(&imgMenu1, "res/menu1.png");
  731. loadimage(&imgMenu2, "res/menu2.png");
  732. int flag = 0;
  733. while (1)
  734. {
  735. BeginBatchDraw();
  736. putimage(0,0,&imgBg);
  737. putimagePNG(474, 75, flag ? &imgMenu2 : &imgMenu1);//如果flag=0,那么加载第二个菜单,
  738. //就是鼠标点击冒险模式后冒险模式的图标会暗淡下来
  739. ExMessage msg;
  740. if (peekmessage(&msg))//如果有消息响应
  741. {
  742. if (msg.message == WM_LBUTTONDOWN&&msg.x>474&&msg.x<474+300
  743. &&msg.y>75&&msg.y<75+140)//按下鼠标
  744. //判断按下的位置对不对
  745. {
  746. flag = 1;
  747. //鼠标松开
  748. //EndBatchDraw();//渲染一下
  749. }
  750. else if (msg.message == WM_LBUTTONUP&&flag)//鼠标抬起
  751. {
  752. return;
  753. }
  754. }
  755. EndBatchDraw();
  756. }
  757. }
  758. int main(void)
  759. {
  760. gameInit();//进入游戏的程序函数
  761. startUI();//菜单函数
  762. int timer = 0;
  763. bool flag = true;
  764. while (1)
  765. {
  766. userClick();
  767. timer += getDelay();
  768. if (timer > 20)
  769. {
  770. flag = true;
  771. timer = 0;
  772. }
  773. if (flag)
  774. {
  775. flag = false;
  776. updateWindow();
  777. updateGame();
  778. }
  779. }
  780. system("pause");
  781. return 0;
  782. }

接着是tools.cpp文件

  1. #include "tools.h"
  2. // 载入PNG图并去透明部分
  3. void _putimagePNG(int picture_x, int picture_y, IMAGE* picture) //x为载入图片的X坐标,y为Y坐标
  4. {
  5. DWORD* dst = GetImageBuffer(); // GetImageBuffer()函数,用于获取绘图设备的显存指针,EASYX自带
  6. DWORD* draw = GetImageBuffer();
  7. DWORD* src = GetImageBuffer(picture); //获取picture的显存指针
  8. int picture_width = picture->getwidth(); //获取picture的宽度,EASYX自带
  9. int picture_height = picture->getheight(); //获取picture的高度,EASYX自带
  10. int graphWidth = getwidth(); //获取绘图区的宽度,EASYX自带
  11. int graphHeight = getheight(); //获取绘图区的高度,EASYX自带
  12. int dstX = 0; //在显存里像素的角标
  13. // 实现透明贴图 公式: Cp=αp*FP+(1-αp)*BP , 贝叶斯定理来进行点颜色的概率计算
  14. for (int iy = 0; iy < picture_height; iy++)
  15. {
  16. for (int ix = 0; ix < picture_width; ix++)
  17. {
  18. int srcX = ix + iy * picture_width; //在显存里像素的角标
  19. int sa = ((src[srcX] & 0xff000000) >> 24); //0xAArrggbb;AA是透明度
  20. int sr = ((src[srcX] & 0xff0000) >> 16); //获取RGB里的R
  21. int sg = ((src[srcX] & 0xff00) >> 8); //G
  22. int sb = src[srcX] & 0xff; //B
  23. if (ix >= 0 && ix <= graphWidth && iy >= 0 && iy <= graphHeight && dstX <= graphWidth * graphHeight)
  24. {
  25. dstX = (ix + picture_x) + (iy + picture_y) * graphWidth; //在显存里像素的角标
  26. int dr = ((dst[dstX] & 0xff0000) >> 16);
  27. int dg = ((dst[dstX] & 0xff00) >> 8);
  28. int db = dst[dstX] & 0xff;
  29. draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16)
  30. | ((sg * sa / 255 + dg * (255 - sa) / 255) << 8)
  31. | (sb * sa / 255 + db * (255 - sa) / 255);
  32. }
  33. }
  34. }
  35. }
  36. // 适用于 y <0 以及x<0的任何情况
  37. void putimagePNG(int x, int y, IMAGE* picture) {
  38. IMAGE imgTmp, imgTmp2, imgTmp3;
  39. int winWidth = getwidth();
  40. int winHeight = getheight();
  41. if (y < 0) {
  42. SetWorkingImage(picture);
  43. getimage(&imgTmp, 0, -y,
  44. picture->getwidth(), picture->getheight() + y);
  45. SetWorkingImage();
  46. y = 0;
  47. picture = &imgTmp;
  48. }
  49. else if (y >= getheight() || x >= getwidth()) {
  50. return;
  51. }
  52. else if (y + picture->getheight() > winHeight) {
  53. SetWorkingImage(picture);
  54. getimage(&imgTmp, x, y, picture->getwidth(), winHeight - y);
  55. SetWorkingImage();
  56. picture = &imgTmp;
  57. }
  58. if (x < 0) {
  59. SetWorkingImage(picture);
  60. getimage(&imgTmp2, -x, 0, picture->getwidth() + x, picture->getheight());
  61. SetWorkingImage();
  62. x = 0;
  63. picture = &imgTmp2;
  64. }
  65. if (x > winWidth - picture->getwidth()) {
  66. SetWorkingImage(picture);
  67. getimage(&imgTmp3, 0, 0, winWidth - x, picture->getheight());
  68. SetWorkingImage();
  69. picture = &imgTmp3;
  70. }
  71. _putimagePNG(x, y, picture);
  72. }
  73. int getDelay() {
  74. static unsigned long long lastTime = 0;
  75. unsigned long long currentTime = GetTickCount();
  76. if (lastTime == 0) {
  77. lastTime = currentTime;
  78. return 0;
  79. }
  80. else {
  81. int ret = currentTime - lastTime;
  82. lastTime = currentTime;
  83. return ret;
  84. }
  85. }

然后是vector2.cpp

  1. //头文件要求
  2. #include <cmath>
  3. struct vector2
  4. {
  5. vector2(int _x = 0, int _y = 0) :x(x), y(y){}
  6. vector2(int* data):x(data[0]),y(data[1]){}
  7. long long x, y;
  8. };
  9. //加法
  10. vector2 operator +(vector2 x, vector2 y) {
  11. return vector2(x.x + y.x, x.y + y.y );
  12. }
  13. //减法
  14. vector2 operator -(vector2 x, vector2 y) {
  15. return vector2(x.x - y.x, x.y - y.y);
  16. }
  17. // 乘法
  18. vector2 operator *(vector2 x, vector2 y) {
  19. return vector2(x.x * y.x - x.y * y.y, x.y * y.x + x.x * y.y);
  20. }
  21. // 乘法
  22. vector2 operator *(vector2 y, float x) {
  23. return vector2(x*y.x, x*y.y);
  24. }
  25. vector2 operator *(float x, vector2 y) {
  26. return vector2(x * y.x, x * y.y);
  27. }
  28. //叉积
  29. long long cross(vector2 x, vector2 y) { return x.y * y.x - x.x * y.y; }
  30. //数量积 点积
  31. long long dot(vector2 x, vector2 y) { return x.x * y.x + x.y * y.y; }
  32. //四舍五入除法
  33. long long dv(long long a, long long b) {//注意重名!!!
  34. return b < 0 ? dv(-a, -b)
  35. : (a < 0 ? -dv(-a, b)
  36. : (a + b / 2) / b);
  37. }
  38. //模长平方
  39. long long len(vector2 x) { return x.x * x.x + x.y * x.y; }
  40. //模长
  41. long long dis(vector2 x) { return sqrt(x.x * x.x + x.y * x.y); }
  42. //向量除法
  43. vector2 operator /(vector2 x, vector2 y) {
  44. long long l = len(y);
  45. return vector2(dv(dot(x, y), l), dv(cross(x, y), l));
  46. }
  47. //向量膜
  48. vector2 operator %(vector2 x, vector2 y) { return x - ((x / y) * y); }
  49. //向量GCD
  50. vector2 gcd(vector2 x, vector2 y) { return len(y) ? gcd(y, x % y) : x; }
  51. vector2 calcBezierPoint(float t, vector2 p0, vector2 p1, vector2 p2, vector2 p3) {
  52. float u = 1 - t;
  53. float tt = t * t;
  54. float uu = u * u;
  55. float uuu = uu * u;
  56. float ttt = tt * t;
  57. vector2 p = uuu * p0;
  58. p = p + 3 * uu * t * p1;
  59. p = p + 3 * u * tt * p2;
  60. p = p + ttt * p3;
  61. return p;
  62. }

最后头文件tools.h

  1. #pragma once
  2. #include <graphics.h>
  3. void putimagePNG(int picture_x, int picture_y, IMAGE* picture);
  4. int getDelay();

vector2.h

  1. #pragma once
  2. //头文件要求
  3. #include <cmath>
  4. struct vector2 {
  5. vector2(int _x=0, int _y=0) :x(_x), y(_y) {}
  6. vector2(int* data) :x(data[0]), y(data[1]){}
  7. long long x, y;
  8. };
  9. //加法
  10. vector2 operator +(vector2 x, vector2 y);
  11. //减法
  12. vector2 operator -(vector2 x, vector2 y);
  13. // 乘法
  14. vector2 operator *(vector2 x, vector2 y);
  15. vector2 operator *(vector2, float);
  16. vector2 operator *(float, vector2);
  17. //叉积
  18. long long cross(vector2 x, vector2 y);
  19. //数量积 点积
  20. long long dot(vector2 x, vector2 y);
  21. //四舍五入除法
  22. long long dv(long long a, long long b);
  23. //模长平方
  24. long long len(vector2 x);
  25. //模长
  26. long long dis(vector2 x);
  27. //向量除法
  28. vector2 operator /(vector2 x, vector2 y);
  29. //向量膜
  30. vector2 operator %(vector2 x, vector2 y);
  31. //向量GCD
  32. vector2 gcd(vector2 x, vector2 y);
  33. vector2 calcBezierPoint(float t, vector2 p0, vector2 p1, vector2 p2, vector2 p3);

这里给大家演示一下画面

6b3ea17134324b1ea083daa4d7211357.png

185d6eb5c86f422fa31409ef6b2c3a8e.png

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/621704
推荐阅读
相关标签
  

闽ICP备14008679号