前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >微信小程序 案例二 飞机大战

微信小程序 案例二 飞机大战

作者头像
万少
修改2025-02-10 17:35:57
修改2025-02-10 17:35:57
9100
代码可运行
举报
运行总次数:0
代码可运行

案例二 飞机大战

本案例主要使用 微信开发者工具内置的 小游戏 来开发

新建项目

要选择 微信小程序

20191225160125
20191225160125

精简代码

  1. 删除 js 文件夹
  2. 清空 game.js的代码

核心概念

canvas

提供了一个通过JavaScriptHTMLcanvas元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。

requestAnimationFrame

setTimeout 等 会重复让浏览器执行 回流 和重绘

告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新

  1. 屏幕刷新频率:屏幕每秒出现图像的次数。普通笔记本为60Hz
  2. 动画原理:计算机每16.7ms刷新一次,由于人眼的视觉停留,所以看起来是流畅的移动
代码语言:javascript
代码运行次数:0
复制
requestAnimationFrame(callback);

核心API

函数名

作用

wx.createCanvas()

创建 canvas 的绘图上下文 CanvasContext 对象

canvas.getContext('2d')

该方法返回 Canvas 的绘图上下文

wx.createImage()

创建一个图片对象

CanvasContext.drawImage()

绘制图像到画布

wx.createInnerAudioContext()

创建内部 audio 上下文 InnerAudioContext 对象

InnerAudioContext.src

设置要播放的音频

InnerAudioContext.play()

播放音频

CanvasContext.clearRect()

清除画布上在该矩形区域内的内容

面向对象-编写游戏-高能预警

接下来使用 es6 + 面向对象对游戏代码进行简单的封装

搭建项目结构

在根目录下,新建 js 文件夹, 然后新建以下文件

代码语言:javascript
代码运行次数:0
复制
+ /base/env.js 存放全局变量(height)和 引入资源(如图片等)
+ /background/music.js 音乐
+ /background/bg.js 背景图
+ /play/player.js 英雄
+ /play/enemy.js 敌机
+ /play/bullet.js 子弹
+ /databus.js 全局的状态管理对象

整体的关系图

image-20191226123803857
image-20191226123803857

编写环境类

js\base\env.js

  1. 在项目启动的时候先把需要用到的图片资源全部下载后,通过promise形势进行封装
  2. 把下载好的图片对象都存入到全局的window.imgs对象中,方便获取
代码语言:javascript
代码运行次数:0
复制
window.canvas = wx.createCanvas()
window.ctx = canvas.getContext('2d');
window.width = wx.getSystemInfoSync().screenWidth;
window.height = wx.getSystemInfoSync().screenHeight;
window.imgs = [];
class env {
  init() {
    return new Promise((r, j) => {
      [
        "./images/bg.jpg",
        "./images/bullet.png",
        "./images/Common.png",
        "./images/enemy.png",
        "./images/explosion1.png",
        "./images/explosion10.png",
        "./images/explosion11.png",
        "./images/explosion12.png",
        "./images/explosion13.png",
        "./images/explosion14.png",
        "./images/explosion15.png",
        "./images/explosion16.png",
        "./images/explosion17.png",
        "./images/explosion18.png",
        "./images/explosion19.png",
        "./images/explosion2.png",
        "./images/explosion3.png",
        "./images/explosion4.png",
        "./images/explosion5.png",
        "./images/explosion6.png",
        "./images/explosion7.png",
        "./images/explosion8.png",
        "./images/explosion9.png",
        "./images/hero.png"
      ]
        .forEach((v, i, arr) => {
          const img = wx.createImage();
          img.src = v;
          window.imgs[v.match(/(\w+)\.[jpg|png|gif|jpeg|webp]+/)[1]] = img;
          img.onload = () => {
            if (i === arr.length - 1) {
              r();
            }
          }
        })
    })
  }
}
export default env;

编写 背景图片类

  1. 实现动态的显示图片

js\background\bgc.js

代码语言:javascript
代码运行次数:0
复制
class bg {
  constructor() {
    this.img = imgs["bg"];
    this.top = 0;
    this.render();
  }
  render() {
    ctx.drawImage(this.img, 0, this.top, width, height);
    ctx.drawImage(this.img, 0, -height + this.top, width, height);
  }
  update() {
    this.top++;
    if (this.top === height) {
      this.top = 0;
    }
    this.render();
  }
}
export default bg;

编写全局状态管理类

  1. 负责控制其他类的状态
  2. 引入背景图片类,然后实例化

js\databus.js

代码语言:javascript
代码运行次数:0
复制
import Bgc from "./background/bgc";
class databus {
  constructor() {
    this.bgc = null;
  }
  init() {
    this.bgc = new Bgc();
  }
  update() {
    this.bgc.update();
  }
}

export default databus

编写游戏入口文件

  1. 负责引入环境类和全局状态管理类
  2. 开始运行游戏

game.js

代码语言:javascript
代码运行次数:0
复制
import Env from "./js/base/env";
import Databus from "./js/databus";
const env = new Env();

main();
async function main() {
  await env.init();
  const databus = new Databus();
  databus.init();
  loop();
  function loop() {
    ctx.clearRect(0, 0, width, height);
    databus.update();
    requestAnimationFrame(loop);
  }
}

编写背景音乐类

  1. 播放和控制背景音乐

js\background\music.js

代码语言:javascript
代码运行次数:0
复制
class music {
  constructor() {
    this.bgc = wx.createInnerAudioContext();
    this.bgc.src = "./audio/bgm.mp3";
    this.bgc.play();
  }
}

export default music;

然后修改全局状态管理类 js\databus.js

  1. 引入和播放音乐
代码语言:javascript
代码运行次数:0
复制
import Bgc from "./background/bgc";
import Music from "./background/music"; // 新增代码
class databus {
  constructor() {
    this.bgc = null;
    this.music=null; // 新增代码
  }
  init() {
    this.bgc = new Bgc();
    this.music=new Music(); // 新增代码
  }
  update() {
    this.bgc.update();
  }
}

export default databus

新增英雄类

  1. 实现动态渲染飞机

js\play\hero.js

代码语言:javascript
代码运行次数:0
复制
class hero {
  constructor() {
    this.width = 50;
    this.height = 50;
    this.img = imgs["hero"];
    this.x = (width - this.width) / 2;
    this.y = (height - this.height);
  }
  render() {
    ctx.drawImage(this.img, this.x, this.y, this.width, this.height);
  }
  update() {
    this.render();
  }
}
export default hero;

修改全局管理类 js\databus.js

  1. 引入飞机
代码语言:javascript
代码运行次数:0
复制
import Bgc from "./background/bgc";
import Hero from "./play/hero";
import Music from "./background/music";
class databus {
  constructor() {
    this.hero = null;
    this.bgc = null;
    this.music=null;
  }
  init() {
    this.bgc = new Bgc();
    this.hero = new Hero();
    this.music=new Music();
  }

  update() {
    this.bgc.update();
    this.hero.update();
  }
}

export default databus

编写英雄跟随手指移动

  1. 通过给canvas绑定手指移动事件

js\play\hero.js

代码语言:javascript
代码运行次数:0
复制
class hero {
  constructor() {
    this.width = 50;
    this.height = 50;
    this.img = imgs["hero"];
    this.x = (width - this.width) / 2;
    this.y = (height - this.height);
    this.addEventMove();
  }
  render() {
    ctx.drawImage(this.img, this.x, this.y, this.width, this.height);
  }
  addEventMove() {
    canvas.addEventListener("touchmove", (e) => {
      const { clientX, clientY } = e.changedTouches[0];
      this.x = clientX - this.width / 2;
      this.y = clientY - this.height / 2;
      this.render();
    })
  }
  update() {
    this.render();
  }
}
export default hero;

0. 新增子弹类

  1. 让英雄可以发射子弹

js\play\bullet.js

代码语言:javascript
代码运行次数:0
复制
class bullet {
  constructor(x, y) {
    this.img = imgs["bullet"];
    this.width = 20;
    this.height = 20;
    this.x = x-this.width/2;
    this.y = y;
    this.top = 0;
    this.render();
  }
  render() {
    ctx.drawImage(this.img, this.x, this.y, this.width, this.height); 
  } 
  update() { 
    this.top++;
    this.y=this.y-this.top;
    this.render();
  }
}
export default bullet;

修改英雄类

js\play\hero.js

代码语言:javascript
代码运行次数:0
复制
import Bullet from "./bullet";
class hero {
  constructor() {
    this.width = 50;
    this.height = 50;
    this.img = imgs["hero"];
    this.x = (width - this.width) / 2;
    this.y = (height - this.height);
    this.bulltes = [];
    this.times = 0;
    this.render();
    this.addEventMove();
    this.createBullets();
  }
  render() {
    ctx.drawImage(this.img, this.x, this.y, this.width, this.height);
  }
  addEventMove() {
    canvas.addEventListener("touchmove", (e) => {
      const { clientX, clientY } = e.changedTouches[0];
      this.x = clientX - this.width / 2;
      this.y = clientY - this.height / 2;
      this.render();
    })
  }
  update() {
    this.render();
    this.createBullets();
    this.shoot();
    
  }
  createBullets() {
    this.times++;
    if (this.times % 30 === 0) {
      this.bulltes.push(new Bullet(this.x+this.width/2, this.y));
      this.times = 0;
    }
  }
  shoot() {
    this.bulltes.forEach(v=>{
      v.update();
    })
  }
}
export default hero;

git地址

后续可以更新

代码语言:javascript
代码运行次数:0
复制
https://github.com/itcastWsy/plane
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 案例二 飞机大战
    • 新建项目
    • 精简代码
    • 核心概念
      • canvas
      • requestAnimationFrame
    • 核心API
    • 面向对象-编写游戏-高能预警
      • 搭建项目结构
      • 整体的关系图
      • 编写环境类
      • 编写 背景图片类
      • 编写全局状态管理类
      • 编写游戏入口文件
      • 编写背景音乐类
      • 新增英雄类
      • 编写英雄跟随手指移动
      • 0. 新增子弹类
    • git地址
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档