在大家准备开始编写小游戏之前,我先泼一盆冷水,微信小游戏不同小程序,审核流程有差别。
A. 个人主体需提交:2个,《计算机软件著作权登记证书》、《游戏自审自查报告》
B. 非个人主体需提交:4个,《广电总局版号批文》 、《计算机软件著作权登记证书》、《文化部备案信息》、《游戏自审自查报告》
我附一个链接,审核需求https://developers.weixin.qq.com/community/develop/doc/00004455a34458355496d601b5b808?page=1
所以想要开发微信小游戏的并且准备上线的 一定要事先去准备这些东西。。。(我就是开发网,去审核的时候,脸就黑了。。)
回归正题:
我这篇 微信小游戏的开发还是很基础的。主要就是用es6+canvas 进行编写的。所以本文适合带大家入门,具体什么游戏引擎(Cocos Creator,白鹭)什么的之后的再做介绍吧。但是这里大家一定要熟悉es6的写法,比如class的使用和箭头函数这些,不会也没关系 ,大家去看阮大大的es6的博客 大概看下就明白了。
先讲一下 开发思路,很重要,很重要,很重要。
1.优先准备图片资源,也就是res中的静态资源文件,一个好的小游戏,这些资源文件堪比灵魂。
2.资源文件准备好后,我们就要编写图片加载器,目的是在小游戏正式运行游戏逻辑前先把资源文件加载完成。
3.之后在Maim.js中 创建canvas 预加载资源文件,监听全局点击事件,调用Director.js导演类中的方法。
4.Director.js到导演类中 调用各种类,编写逻辑,完成游戏。
我相信 思路理清,大家做东西肯定会很快。
ResourceLoader.js(资源文件加载器)
//资源文件加载器,确保canvas在图片资源加载后才进行渲染
import {Resources} from "./Resources.js";
export class ResourceLoader{
constructor(){
this.map=new Map(Resources)
for(let[key,value] of this.map){
const image=wx.createImage();
image.src=value;
this.map.set(key,image);
}
}
onLoader(callback){
let loadedCount=0;
for(let value of this.map.values()){
value.onload = () => {
loadedCount++;
if(loadedCount>=this.map.size){
callback(this.map);
}
}
}
}
static create() {
return new ResourceLoader();
}
}
Main.js(入口文件)
//初始化整个游戏的精灵,作为游戏开始的入口
import {ResourceLoader} from "./js/base/ResourceLoader.js";
import {Director} from "./js/Director.js";
import {BackGround} from "./js/runtime/BackGround.js";
import {DataStore} from "./js/base/DataStore.js";
import {Land} from "./js/runtime/Land.js";
import {Superman} from "./js/player/Superman.js";
import { End } from "./js/player/End.js";
import {Score} from "./js/player/Score.js";
import {Logo} from "./js/player/Logo.js";
import {OpenButton} from "./js/player/OpenButton.js";
export class Main {
constructor() {
this.canvas =wx.createCanvas();;
this.ctx = this.canvas.getContext('2d');
this.dataStore=DataStore.getInstance();
this.director=Director.getInstance();
const loader = ResourceLoader.create();
loader.onLoader(map => this.onResourceFirstLoaded(map));
}
onResourceFirstLoaded(map) {
this.dataStore.canvas=this.canvas;
this.dataStore.ctx=this.ctx;
this.dataStore.res=map;
// this.createBackgroundMusic();
this.init();
// let background =new BackGround(this.ctx,map.get('background'));
// background.draw();
}
createBackgroundMusic(){
const bgm=wx.createInnerAudioContext();
bgm.autoplay=true;
bgm.loop=true;
bgm.src='res/bgm.mp3';
}
init(type=true){
console.log("init")
this.director.isGameOver =false;
this.director.isReady = type;
this.dataStore.put('background',BackGround)
.put('pencils',[])
.put('land',Land)
.put('superman',Superman)
.put('score',Score)
.put('logo',Logo)
.put('openButton',OpenButton)
.put('score',Score)
.put('end', End);
this.director.createPencil();
this.registerEvent()
this.director.run();
}
registerEvent(){
wx.onTouchStart(()=>{
console.log("1")
if (!this.director.isGameOver && this.director.isReady){
this.director.isReady = false;
this.director.run();
}else if (this.director.isGameOver) {
this.init(false);
} else {
this.director.supermanEvent();
}
})
}
Director.js(游戏逻辑)
//导演类,控制游戏的逻辑
import {DataStore} from "./base/DataStore.js";
import {UpPencil} from "./runtime/UpPencil.js";
import {DownPencil} from "./runtime/DownPencil.js";
export class Director {
static getInstance() {
if (!Director.instance) {
Director.instance = new Director();
}
return Director.instance;
}
constructor() {
this.dataStore = DataStore.getInstance();
this.moveSpeed = 2;
}
createPencil() {
const minTop = DataStore.getInstance().canvas.height / 8;
const maxTop = DataStore.getInstance().canvas.height / 2;
const top = minTop + Math.random() * (maxTop - minTop);
this.dataStore.get('pencils').push(new UpPencil(top));
this.dataStore.get('pencils').push(new DownPencil(top));
}
supermanEvent() {
for (let i = 0; i <= 2; i++) {
this.dataStore.get('superman').y[i] =
this.dataStore.get('superman').supermanY[i];
}
this.dataStore.get('superman').time = 0;
}
//判断超人是否和障碍撞击
static isStrike(bird, pencil) {
let s = false;
if (bird.top > pencil.bottom ||
bird.bottom < pencil.top ||
bird.right < pencil.left ||
bird.left > pencil.right
) {
s = true;
}
return !s;
}
//判断超人是否撞击地板和障碍
check() {
const superman = this.dataStore.get('superman');
const land = this.dataStore.get('land');
const pencils = this.dataStore.get('pencils');
const score = this.dataStore.get('score');
//地板的撞击判断
if (superman.supermanY[0] + superman.supermanHeight[0] >= land.y) {
console.log('撞击地板啦');
this.isGameOver = true;
return;
}
//超人的边框模型
const supermanBorder = {
top: superman.y[0],
bottom: superman.supermanY[0] + superman.supermanHeight[0],
left: superman.supermanX[0],
right: superman.supermanX[0] + superman.supermanWidth[0]
};
const length = pencils.length;
for (let i = 0; i < length; i++) {
const pencil = pencils[i];
const pencilBorder = {
top: pencil.y,
bottom: pencil.y + pencil.height,
left: pencil.x,
right: pencil.x + pencil.width
};
if (Director.isStrike(supermanBorder, pencilBorder)) {
console.log('撞到障碍啦');
this.isGameOver = true;
return;
}
}
//加分逻辑
if (superman.supermanX[0] > pencils[0].x + pencils[0].width
&& score.isScore) {
wx.vibrateShort({
success: function () {
console.log('振动成功');
}
});
score.isScore = false;
score.scoreNumber++;
}
}
run() {
this.check();
if (this.isReady){
this.dataStore.get('background').draw();
this.dataStore.get('land').draw();
this.dataStore.get('logo').draw();
this.dataStore.get('openButton').draw();
this.dataStore.get('superman').draw();
}else if (!this.isGameOver) {
this.dataStore.get('background').draw();
const pencils = this.dataStore.get('pencils');
if (pencils[0].x + pencils[0].width <= 0 &&
pencils.length === 4) {
pencils.shift();
pencils.shift();
this.dataStore.get('score').isScore = true;
}
if (pencils[0].x <= (DataStore.getInstance().canvas.width - pencils[0].width) / 2 &&
pencils.length === 2) {
this.createPencil();
}
this.dataStore.get('pencils').forEach(function (value) {
value.draw();
});
this.dataStore.get('land').draw();
this.dataStore.get('score').draw();
this.dataStore.get('superman').draw();
let timer = requestAnimationFrame(() => this.run());
this.dataStore.put('timer', timer);
} else {
console.log('游戏结束');
this.dataStore.get('end').draw();
cancelAnimationFrame(this.dataStore.get('timer'));
this.dataStore.destroy();
//触发微信小游戏垃圾回收
wx.triggerGC();
}
}
}
我把这三个主类直接贴出了了,其余子类的代码比较好理解,大家尽量下载下来直接看吧。
为了方便大家直接学习 我把项目代码也放到csdn上了
有需要的朋友可以直接下载 有问题留言问我吧
https://download.csdn.net/download/houtailei/11135110(请大家理解,需要积分交互资源使用,如果特别有积分困难的可以留言,谢谢。)