微信小游戏源码(从入门到入坑-火柴人勇闯地下城))

在大家准备开始编写小游戏之前,我先泼一盆冷水,微信小游戏不同小程序,审核流程有差别。

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(请大家理解,需要积分交互资源使用,如果特别有积分困难的可以留言,谢谢。)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章