微信小遊戲源碼(從入門到入坑-火柴人勇闖地下城))

在大家準備開始編寫小遊戲之前,我先潑一盆冷水,微信小遊戲不同小程序,審覈流程有差別。

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(請大家理解,需要積分交互資源使用,如果特別有積分困難的可以留言,謝謝。)

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