微信小游戏开发教程-游戏实现1

概述

微信开发者工具官方提供一个飞机大战的游戏Demo,这里我们不再使用这个demo,我们以FlappyBird为例,为了让读者更加容易理解。

源码

https://github.com/onlynight/FlappyBird

强烈建议读者根据教程自己实现一遍游戏,这让能让你更加熟悉开发的流程和代码的原理;在一些不清楚的地方可以参考源码实现的方法。

游戏开发

首先我们在 src 目录下新建一个 base 目录用于存放基类,然后创建一个基类 Sprite,这个类中会包含游戏的的一些通用功能,例如2d绘图,碰撞检测等。

1. canvas#drawImage()

这个方法是2D游戏的核心绘图函数,用于将图片绘制到canvas上。

ctx.drawImage(this.img,this.x,this.y,this.width,this.height
)

2. 碰撞检测

碰撞检测对游戏体验影响比较大,有多种碰撞检测方法:

a. 中心点检测法

这种检测方法代码最简单,只需要判断中心点是否在目标矩形区域内即可:

isCollideWith(target) {let targetX = target.x + target.width / 2let targetY = target.y + target.height / 2return (targetX >= this.x &&targetX <= this.x + this.width &&targetY >= this.y &&targetY <= this.y + this.height)
}

b. 边缘碰撞检测法

图片都是矩形,当两个矩形有任何一部分重合即视为碰撞:

isClollideEdgeWith(target) {return ((target.x >= this.x &&target.x <= this.x + this.width &&target.y >= this.y &&target.y <= this.y + this.height) || // top left(target.x + target.width >= this.x &&target.x + target.width <= this.x + this.width &&target.y >= this.y &&target.y <= this.y + this.height) || // top right(target.x >= this.x &&target.x <= this.x + this.width &&target.y + target.height >= this.y &&target.y + target.height <= this.y + this.height) || // bottom left(target.x + target.width >= this.x &&target.x + target.width <= this.x + this.width &&target.y + target.height >= this.y &&target.y + target.height <= this.y + this.height)) // bottom right
}

Sprite 完整代码源码如下:

// @author: wyndam
// @email: only.night@qq.com/*** 精灵类,包含绘图以及碰撞检测等*/
export default class Sprite {constructor(imgSrc, x, y, width, height) {// 当前对象的坐标以及尺寸this.x = xthis.y = ythis.width = widththis.height = height// 当前对象显示的图片this.img = new Image()this.img.src = imgSrc// 标识当前对象是否显示this.visible = true}/*** 将图片绘制到 canvas 上* {@param ctx cancas context 对象}*/drawToCanvas(ctx) {if (!this.visible) {return}ctx.drawImage(this.img,this.x,this.y,this.width,this.height)}/*** 中心点检测* {@param target 目标物体}*/isCollideWith(target) {if (!this.visible || !target.visible) {return}let targetX = target.x + target.width / 2let targetY = target.y + target.height / 2return (targetX >= this.x &&targetX <= this.x + this.width &&targetY >= this.y &&targetY <= this.y + this.height)}/*** 严格边缘检测,会误判* {@param target 目标物体}*/isClollideEdgeWith(target) {if (!this.visible || !target.visible) {return}return ((target.x >= this.x &&target.x <= this.x + this.width &&target.y >= this.y &&target.y <= this.y + this.height) || // top left(target.x + target.width >= this.x &&target.x + target.width <= this.x + this.width &&target.y >= this.y &&target.y <= this.y + this.height) || // top right(target.x >= this.x &&target.x <= this.x + this.width &&target.y + target.height >= this.y &&target.y + target.height <= this.y + this.height) || // bottom left(target.x + target.width >= this.x &&target.x + target.width <= this.x + this.width &&target.y + target.height >= this.y &&target.y + target.height <= this.y + this.height)) // bottom right}}

创建渲染循环

window.requestAnimationFrame() 方法告诉浏览器您希望执行动画并请求浏览器在下一次重绘之前调用指定的函数来更新动画。该方法使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。

注意:若您想要在下次重绘时产生另一个动画画面,您的回调例程必须调用 requestAnimationFrame()。

main.js中:

我们创建一个 loop 函数,然后在 loop 函数中调用 requestAnimationFrame 方法,然后在初始化时再调用一次 requestAnimationFrame ,并且将 requestAnimationFrame 的执行指向 loop函数,这样就实现了循环。

// @author: wyndam
// @email: only.night@qq.comlet ctx = canvas.getContext('2d')export default class Main {constructor() {this.onCreate()}onCreate(){this.bindLoop = this.loop.bind(this)window.cancelAnimationFrame(this.aniId);this.aniId = window.requestAnimationFrame(this.bindLoop,canvas)}loop(){this.aniId = window.requestAnimationFrame(this.bindLoop,canvas)}}

绘制背景

接下来我们绘制游戏的背景,先绘制一个静态的背景,然后我们再让背景动起来。

  1. 新建 runtime 包
  2. 新建一个 background.js 文件
  3. 新建一个 Background 类,然后将背景填入默认参数
// @author: wyndam
// @email: only.night@qq.comimport Sprite from '../base/sprite.js'const BG_IMG_SRC = 'images/bg_day.png'
const BG_IMG_WIDTH = 288
const BG_IMG_HEIGHT = 512export default class Background extends Sprite {constructor() {super(BG_IMG_SRC, 0, 0, BG_IMG_WIDTH, BG_IMG_HEIGHT)}}

以上静态背景类就创建好了,然后我们将它添加到绘制流程中去。

  1. main.js中添加一个新的属性 this.bg = new Background()
  2. loop函数中调用绘制函数即可 this.bg.drawToCanvas(),添加后的代码如下:
// @author: wyndam
// @email: only.night@qq.comimport Background from './runtime/background.js'let ctx = canvas.getContext('2d')export default class Main {constructor() {this.onCreate()}onCreate(){this.bg = new Background()this.bindLoop = this.loop.bind(this)window.cancelAnimationFrame(this.aniId);this.aniId = window.requestAnimationFrame(this.bindLoop,canvas)}loop(){this.render()this.aniId = window.requestAnimationFrame(this.bindLoop,canvas)}render(){this.bg.drawToCanvas(ctx)}}

这时候保存一下代码,你就可以看到背景图绘制到屏幕上了。

接着我们让背景动起来,先在背景类的构造函数中添加一个位移变量:

this.left = 0

然后我们修改一下绘制函数,根据前面我们提到的无限循环背景原理,我们这里需要绘制两张背景图:

drawToCanvas(ctx) {ctx.drawImage(this.img,this.x + this.left,this.y,window.innerWidth,window.innerHeight)ctx.drawImage(this.img,this.x + window.innerWidth + this.left,this.y,window.innerWidth,window.innerHeight)}

接着,添加一个更新函数,动态修改 this.left的值,让背景动起来:

update(){this.left+=2
}

其中 this.left的增长率就是背景移动的速度,你可以自己修改一下这个值看下效果。

最后在 main.jsloop函数中调用更新函数即可让背景动起来,修改后的代码如下:

// main.js
// @author: wyndam
// @email: only.night@qq.comimport Background from './runtime/background.js'let ctx = canvas.getContext('2d')export default class Main {constructor() {this.onCreate()}onCreate(){this.bg = new Background()this.bindLoop = this.loop.bind(this)window.cancelAnimationFrame(this.aniId);this.aniId = window.requestAnimationFrame(this.bindLoop,canvas)}loop(){this.update()this.render()this.aniId = window.requestAnimationFrame(this.bindLoop,canvas)}render(){this.bg.drawToCanvas(ctx)}update(){this.bg.update()}}

微信小游戏开发教程-游戏实现1相关推荐

  1. 微信小游戏开发教程-游戏实现3

    微信小游戏开发教程-游戏实现3 对象池 由于游戏过程中会创建很多临时对象,这些对象很快又不再使用,垃圾回收器也能帮我们主动回收这部分垃圾,但是回收时间不可控制,同时增大了创建对象的开销,所以我们使用对 ...

  2. 微信小游戏开发教程-游戏实现2

    微信小游戏开发教程-游戏实现2 绘制地面 类似于绘制背景,读者自行完成代码.src/runtime/land.js 简易View系统 坐标布局对于复杂的页面来说维护相当困难,因此这里我们引入布局的概念 ...

  3. 微信小程序开发的游戏《拼图游戏》

    微信小程序开发的游戏<拼图游戏> 代码直接考进去就能用 pintu.js // pintu.js Page({/*** 页面的初始数据*/data: {},initGame: functi ...

  4. 视频教程-微信小程序开发教程(第1篇)-微信开发

    微信小程序开发教程(第1篇) 微信企业号星级会员.10多年软件从业经历,国家级软件项目负责人,主要从事软件研发.软件企业员工技能培训.已经取得计算机技术与软件资格考试(软考)--"信息系统项 ...

  5. 微信小程序开发分销制度济南_花店微信小程序开发教程

    如何将自己的鲜花商品快速配送出去,避免鲜花过期浪费,是很多传统花店商家的难题.不过随着微信小程序的出现,这一难题也渐渐得到了解决.花店商家可以通过自己的小程序商城,打通线上渠道,可以加大推广.扩大销量 ...

  6. 微信小程序开发教程第七章:微信小程序编辑名片页面开发

    前面我们更新了六篇的微信小程序开发教程,现在更新第七章:微信小程序编辑名片页面开发,(第一二章:微信小程序开发教程,第三四章:微信小程序项目结构以及配置&微信小程序首页面开发,第五章:微信小程 ...

  7. 微信小程序开发教程第八章:微信小程序分组开发与左滑功能实现

    接着上面微信小程序开发教程第八章:微信小程序分组开发与左滑功能实现.(第一二章:微信小程序开发教程,第三四章:微信小程序项目结构以及配置&微信小程序首页面开发,第五章:微信小程序名片夹详情页开 ...

  8. 小程序开发用什么编程语言_微信小程序开发教程是什么?费用多少?

    微信小程序如今已经非常常见,渗透到了我们日常生活的方方面面,包括生活服务.出行.点餐.电商购物.企业展示--商家可以开发适合自己行业的小程序,以吸引线上用户,同时提高自身服务运营效率.不过这些不同种类 ...

  9. 微信小程序开发语言(微信小程序开发教程)详细步骤

    微信小程序开发语言 开发微信小程序用什么语言 1.微信小程序开发所需要的语言比较特别,首先介绍一下需要使用到的文件类型大致分为:WXML(WeiXin Mark Language 微信标记语言).WX ...

最新文章

  1. shell中十种实现自加的方法
  2. python机器学习入门(Day11:ANN)
  3. python实操培训_python实训day1
  4. matlab共轭梯度法_优化算法之牛顿法
  5. VisualBasic 版 (精华区)
  6. linux命令之有关关机和查看系统信息的命令
  7. 2012三足鼎立:BEC、托业与博思的比较
  8. golang游戏服务器框架_教你从头写游戏服务器框架
  9. 从零学ELK系列(二):VMware安装Centos(超详细图文教程)
  10. 网络安全分析 | 用OpenFEA定位WebShell木马后门
  11. 北斗导航 | 卫星导航系统中的GNSS信号技术参数/技术参数/规格
  12. css定义文字加粗,css文字加粗font-weight
  13. word方框中打对号
  14. 单选按钮、字体的设置、沿着y轴旋转、面向用户的这一面不可见、三维效果、背景线性渐变、将背景剪切至文本
  15. 市场调研—2021-2027全球与中国硬质托盘包装市场现状及未来发展趋势
  16. win7系统计算机无最小化,win7我的电脑图标没了win7我的电脑不见解决方法(图)
  17. Switch 无法 关联账号 this page cannot be displayed
  18. Android 获取电池容量 mAh
  19. 基于docker 搭建mysql8.0主从复制
  20. win10搭建Java开发环境(2020年版)

热门文章

  1. 电脑网络禁用了怎么恢复_网卡禁用怎么启用恢复
  2. react中高阶组件
  3. EasyBridge:一种简单的js-bridge设计方案
  4. 常见的和端口,IP相关的企业面试题
  5. Android中Handler的使用
  6. TaintDroid深入剖析之启动篇
  7. 建立jackrabbit内容仓库实例
  8. SVN项目锁定解决方案
  9. xml 和 json 序列化忽略字段
  10. Unity面试题汇总(第一部分)