经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 游戏设计 » 查看文章
如何快速开发一个微信小游戏--实例《打气球》
来源:cnblogs  作者:田想兵  时间:2019/10/9 8:37:53  对本文有异议

首先,我们来看下h5游戏和微信小游戏之间的区别:

1.我认为最大的一点区别在于,微信小游戏全是基于单个canvas的结构,而h5的游戏,我们可以使用多层的canvas对游戏进行分类,比如我之前有开发一个《大头吃小头》的h5游戏,如下图,演示地址:http://www.lovewebgames.com

 

在这里,我们就对它进行了三层结构的划分,1层为主游戏层,主要处理游戏内的各精灵的活动,1层为控制器层(或操作层),主要处理事件或摇杠的操作,第3层就是显示层了,主要展示一些文字如得分、生命值等信息。这样划分的好处是显而意见的,可以充分利用每层的独立渲染,减少性能的开销。然而在微信小游戏中,只有一个canvas是显示的,再创建的canvas都是不可见的。

2.第二点不同在于,无法使用dom元素,dom虽然在动画的性能上比canvas差很多,但它也有很多的优点,比如他可以结合css样式快速的呈现很好的展示效果,包括事件的处理也大不同,例如在《大头吃小头》这款游戏中,控制杠就是用html元素展示的,包括游戏里的一些按钮,它们并不是在每帧都需要重绘的,更多的可能是位置的变化。而在微信小游戏的开发中,我们完全不能使用除canvas外的html元素,游戏里的任何变化,只能通过每帧的清屏重绘来完成。

3.第三点不同在于api不同,基本上原来在浏览器端的api都不能用,包括事件的绑定也不一样,这也就是别人说的,小程序的开发,并不会给你前端的开发加成,因为是两套完全不同的api玩法,所以我们需要adapter,官方有提供一个简单的weapp-adapter,来综合小游戏和h5之间的差异,在下面的内容里,我将抛弃它,完全使用api来操作,既然是两套不同的玩法,我认为没必要统一。

上面说到adapter,是不是意味着我们要写很多的基础代码呢,当然要写,不过我已经把这些基础的代码写成了一个库,名字叫wx-jy,它的作用与adapter又有着不同,主要是为了我们减少对游戏的转承启合而开发代码,多的不说了,源码在github上有,包括h5版的jy和微信版的wx-jy

下面我们来看一下,今天我们要带大家完成的小游戏《打气球》,这款游戏很适合做入门教程,首先他包含有小游戏的所有过程,然后他逻辑简单,不会看不懂。说到游戏的过程,我把它分成六大状态:

前面三个状态loading、title、descript为游戏准备阶段,runing就是游戏的核心运行状态了,也许你会问了,为啥要分这么细,游戏不就是开始和结束吗?呃,那是你觉得,我要我觉得。

说了这么多了,我们还是没开始写《打气球》的一行代码,不要紧,老弟,磨材不误砍刀工,其实打气球的代码不超过十行,我们总不能拿那十行代码讲一天吧?好了,开始正式的撸码吧!

第一步,我们要创建一个游戏的舞台,我们所有的游戏小伙伴们都将在这个舞台上起舞。

import {
    JY,
    STATE,
    Stage,
    Title,
    Descript,
    Sprite,
    lib
} from 'wx-jy';

  1. const canvas = wx.createCanvas();
  2. const [height, width] = [canvas.height, canvas.width]
  3. //创建舞台
  4. let stage = new Stage(canvas, width, height, '#FFFFFF');

前两行引用wx-jy的相关依赖,你可以把这个文件单独下载下来引用。下面就是new Stage了,有了舞台后,我们就需要把一些要素放进去了,比如标题和介绍 

  1. let title = new Title('打气球', stage);
  2. title.create = (resolve) => {
  3. lib.write(stage, '一起来打气球')
  4. resolve();
  5. }
  6. let descript = new Descript(stage)
  7. descript.create = async (resolve) => {
  8. lib.draw(stage, 'images/descript.jpg', 0, 0, stage.width, stage.height)
  9. // await lib.waitMoment(3000);
  10. //添加开始按钮的Sprite
  11. let btn = new Sprite(stage, 'images/btn-start.png', 100, 40, (width - 100) / 2, height - 40 - 40);
  12. btn.draw();
  13. wx.onTouchStart((e) => {
  14. btn.touchHits(e,()=>{
  15. wx.offTouchStart();
  16. resolve()
  17. })
  18. });
  19. }

在descript这里的代码为什么会多一点,主要是要展示一个按钮,然后绑定点击的事件,所有步聚的方法都使用异步函数的方式编写,这样只需要resolve()调用就会自动走到下一步了。

接下来就是声明一个气球的精灵类了,这个精灵,有两个属性方法,一个是上升的速度,一个是更新位置的方法。

  1. //气球类
  2. class Ball extends Sprite {
  3. speed: number = 1;//速度
  4. //更新位置
  5. update() {
  6. this.y -= this.speed;
  7. if (this.y+this.height < 0) {
  8. this.visible = false;
  9. }
  10. }
  11. }

做完这些,我们就可以写我们的主体函数类了,它继承于JY,对过程进行扩展。

  1. class Game extends JY {
  2. frame: number = 0;//帧数
  3. ballList: Ball[] = [];//所有球的集合
  4. newGame() {
  5. this.stage.style = "green";
  6. this.setState(STATE.running);
  7. //事件绑定
  8. wx.onTouchStart(e => {
  9. let { clientX, clientY } = e;
  10. console.log(clientX, clientY)
  11. this.ballList.forEach((ball,index) => {
  12. //触碰回收球并播放声音
  13. ball.touchHits(e,()=>{
  14. this.ballList.splice(index,1);
  15. lib.play('audio/boom.mp3');
  16. })
  17. });
  18. });
  19. }
  20. async running() {
  21. this.frame++;
  22. //先清空场景
  23. this.stage.clear();
  24. this.createSprite();
  25. this.ballList.forEach((ball,index) => {
  26. ball.update();
  27. ball.draw();
  28. //回收球
  29. if(!ball.visible){
  30. this.ballList.splice(index,1);
  31. }
  32. });
  33. }
  34. //创建角色
  35. createSprite() {
  36. //100帧创建一个角色
  37. if (this.frame % 100 == 0) {
  38. let x = lib.random(0, stage.width - 30);
  39. let w = 40;
  40. let h = 340 / 120 * w;
  41. let ball = new Ball(this.stage, 'images/ball.png', w, h, x, this.stage.height);
  42. // ball.touchHits(this.touch)
  43. this.ballList.push(ball);
  44. }
  45. }
  46. async gameOver() {
  47. stage.clear();
  48. lib.write(stage, '游戏结束!');
  49. await lib.waitMoment(3000);
  50. this.setState(STATE.descript);
  51. }
  52. }

这里我们重写了newGame、runing和gameover这三个生命周期,目的是个性化内容,所有的游戏可能真正的区别也只是游戏开始、运行和结束三个状态是不一样的了。

最后,我们实例化这个类,然后启动它,还有资源文件的加载。

  1. let mygame = new Game(stage, title, descript);
  2. mygame.resources = [
  3. 'images/ball.png',
  4. 'images/btn-start.png',
  5. 'images/descript.jpg',
  6. 'audio/boom.mp3'
  7. ];
  8. mygame.setup()

就这样,一款好看又好玩的《打气球》就基本完成了,所有需要我们编写的代码不过100行,中间你还可以添加生命数和分值来增强游戏的可玩性。

 

 你也可以从github中clone下整个项目,然后用微信调试工具导入dev这个目录,就可以直接预览到效果了

原文链接:http://www.cnblogs.com/tianxiangbing/p/wx-jy.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号