零基础入门微信小游戏开发(一)初试

1、背景

多年java后台开发经验,前端略懂皮毛。多年游戏经验,一直在玩别人的游戏。有一天突然在想为啥不自己做个玩玩呢?重度的游戏开发不在考虑范围,技术和资源都不允许。原生手游是比较理想的类型,但除了需要补充游戏开发相关技术,还需要补充 ios 和安卓相关开发,这个作为一个长期目标。思前想后,比较务实的做法就是先弄个微信小游戏趟趟水。微信小游戏侧重创意,相对实现都比较简单,微信平台也提供了很多方便开发者实施的服务,非常适合用来练手。

2、搞起

刷微信小游戏开发的官方文档 

https://developers.weixin.qq.com/minigame/dev/guide/

心得:微信官网文档迅速的刷一遍,注重看基本规则,api细节暂时不用太纠结。

刷的差不多了下载微信开发者工具,开发者工具会自带一个打飞机的示例项目,新手建议详读。这个示例虽然很简单,但却把游戏的基本框架展示了出来,可以帮助初学者建立基本的游戏开发的概念。笔者学习时打开两个窗口,一个窗口加载示例程序,一个窗口建一个空白项目,尝试着在空白项目上一点一点的复制实现demo的内容。

原始demo运行画面:

笔者尝试实现一些粗糙的想法,对程序改造后的效果:

曲线子弹

多行子弹效果:

 

核心改动代码:main.js

import BackGround from './background'
import Databus from './databus'
import Bullet from '../player/bullet'

let ctx = canvas.getContext('2d')
let databus = new Databus()
let bulletX = 100
let bylletAdd = 0 //可调整该值使子弹漂移


export default class Main{
  constructor(){
    // 维护当前requestAnimationFrame的id
    this.aniId = 0
    this.restart() 
  }

  restart() {
    databus.reset()
    this.bg = new BackGround(ctx)


    this.bindLoop = this.loop.bind(this)
    this.hasEventBind = false
    // 清除上一局的动画
    window.cancelAnimationFrame(this.aniId);
    this.aniId = window.requestAnimationFrame(
      this.bindLoop,
      canvas
    )
  }

  /**
   * canvas重绘函数
   * 每一帧重新绘制所有的需要展示的元素
   */
  render() {
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    this.bg.render(ctx)
    databus.bullets
      .concat(databus.enemys)
      .forEach((item) => {
        item.drawToCanvas(ctx)
      })
  }

  // 游戏逻辑更新主函数
  update() {
    if (databus.gameOver)
      return;

    // this.bg.update()

    databus.bullets
      .concat(databus.enemys)
      .forEach((item) => {
        item.update()
      })

    if (databus.frame % 20 === 0) {
      this.shoot(0, () => -3)
      this.shoot(-0.5, () => -3)
      this.shoot(0.5, () => -3)
    }

    console.log(databus.bullets.length)

  }

  // 实现游戏帧循环
  loop() {
    databus.frame++

    this.update()
    this.render()

    this.aniId = window.requestAnimationFrame(
      this.bindLoop,
      canvas
    )
  }

  shoot(sx = 0, sy = () => -10 ){
    bulletX += bylletAdd
    if (bulletX < 100 || bulletX > 300){
      bylletAdd *= -1
    } 

    let bullet = databus.pool.getItemByClass('bullet', Bullet)
    bullet.init(
      bulletX,
      window.innerHeight * 0.8,
      sx,
      sy
    )
    databus.bullets.push(bullet)
  }
}

bullet.js

import Sprite from '../common/sprite'
import DataBus from '../main/databus'

const BULLET_IMG_SRC  = 'images/bullet.png'
const BULLET_WIDTH    = 16
const BULLET_HEIGHT   = 30
const SCREEN_WIDTH    = window.innerWidth
const SCREEN_HEIGHT   = window.innerHeight

const __ = {
  sx: Symbol('sx'),
  sy: Symbol('sy')
}

let databus = new DataBus()


export default class Bullet extends Sprite {
  constructor() {
    super(BULLET_IMG_SRC, BULLET_WIDTH, BULLET_HEIGHT)
  }

  init(x, y, speedX, f_speedY) {
    this.x = x
    this.y = y

    this[__.sx] = speedX
    this[__.sy] = f_speedY

    this.visible = true
    
  }

  // 每一帧更新子弹位置
  update() {
    this.x += this[__.sx]
    this.y += this[__.sy](this.x)
    

    // 超出屏幕外回收自身
    if (this.y < -this.height || this.x < -this.width || this.x > SCREEN_WIDTH || this.y > SCREEN_HEIGHT)
      databus.removeBullets(this)
  }

}

databus.js

import Pool from '../common/pool'

let instance

/**
 * 全局状态管理
 */
export default class Databus{
  constructor(){
    if(instance)
      return instance
    
    instance = this
    this.pool = new Pool()
    this.reset()
  }

  reset(){
    this.frame     = 0
    this.score     = 0
    this.bullets   = []
    this.enemys    = []
    this.animation = []
    this.gameover  = false
  }

  /**
   * 回收敌人
   */
  removeEnemy(enemy){
    let temp = this.enemys.shift()
    temp.visible = false
    this.pool.recover('enemy', enemy)
  }

/**
 * 回收子弹
 * 原始的代码因为子弹是单条直线,最先发出的子弹最先消失,所以简单的使用了 shift 操作
 */
  removeBullets(bullet){
    bullet.visible = false
    let index = this.bullets.indexOf(bullet)
    this.bullets.splice(index, 1)
    this.pool.recover('bullet', bullet)
  }
}

小结:

官方提供的微信开发者工具非常难用,基本的快捷键都没有,笔者虽然使用了当时最新的版本(1.02.1910120),依然感觉像是一个非常粗糙的原型版本,不像是一个完成版本,写代码特别累。

刷完这个后,感觉直接用demo的这个原生框架改一改,再加上一些wx的api,应该能直接构建一些简单的小游戏了。特别是一些创意玩法的小游戏,不需要有太多的界面和交互。但做程序猿这么多年,知道各行各业都有一些主流框架的存在。所以在正式开始实现自己想法之前,决定先刷一下游戏开发的框架:游戏引擎

问题:大多数莫名其妙的问题,可以通过重启客户端解决(惊不惊喜)。

部分wx的api无法在测试项目上使用,比如广告组件,需要申请真实的id才能跑通。

部分wx的api在开发者工具上无法使用,但是通过预览二维码在手机端可以正常使用。比如游戏圈、分享

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值