首页 前端知识 H5实现点击获取金币小游戏以及大富翁

H5实现点击获取金币小游戏以及大富翁

2024-07-24 23:07:09 前端知识 前端哥 451 355 我要收藏

最近做了一个比较不错的点击获取金币小游戏,这里分享给大家
主要实现方式是通过hilojs实现的

以下为官方文档的地址
官方文档

第一步:安装插件

npm i hilojs或者yarn add hilojs

第二步:创建一个Asset.js文件

import Hilo from "hilojs";
export default Hilo.Class.create({//素材加载类
    Mixes: Hilo.EventMixin,
    queue: null,  // 下载类
    gold10: null,   // 金币
    gold20: null,   // 金币
    gold50: null,   // 金币
    blindBox: null,   // 盲盒
    fireElement: null,   // 金币
    soil: null, // 红包
    person: null, // 车
    score0: null,   // -1分
    score1: null,   // +1分
    score2: null,   // +2分

    load() {
        let imgs = [
            {
                id: 'gold10',//金币
                src: 'https://sunndybody.gitee.io/monthover/10.png', 
            },
            {
                id: 'gold20',//金币
                src: 'https://sunndybody.gitee.io/monthover/20.png', 
            },
            {
                id: 'gold50',//金币
                src: 'https://sunndybody.gitee.io/monthover/50.png', 
            },
            {
                id: 'blindBox',//金币
                src: 'https://sunndybody.gitee.io/monthover/hezi_120.png', 
            },
        ];
        this.queue = new Hilo.LoadQueue();
        this.queue.add(imgs);
        this.queue.on('complete', this.onComplete.bind(this));
        this.queue.on('error', (e) => {
            console.log('加载出错', e)
        })
        this.queue.start();
    },
    onComplete() {
        console.log('加载完成。。。。。')
        this.gold10 = this.queue.get('gold10').content;//金币
        this.gold20 = this.queue.get('gold20').content;//金币
        this.gold50 = this.queue.get('gold50').content;//金币
        this.blindBox = this.queue.get('blindBox').content;//盲盒
        //删除下载队列的complete事件监听
        this.queue.off('complete');
        // complete暴露
        this.fire('complete');
    }
})

第三步:创建一个game.js文件

import Hilo from "hilojs";
import Asset from './Asset'//定义金币红包车参数
import goldContainer from './goldContainer'//随机生成金币红包臭蛋
const setTime = 14//游戏时长单位(s)
let startTime = 0
export default class game {//游戏主模块
    constructor(page) {
        this.page = page
        //设置的游戏时间
        this.setGameTime = setTime//设置时间
        this.gameTime = 15
        this.gameStatus = "start"//游戏状态

        // 下载队列
        this.asset = new Asset()
        // 画布对象
        this.stage = null

        // 画布信息 
        this.width = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) * 2
        // this.height = innerHeight * 2 < 1334 ? innerHeight * 2 : 1334
        this.height = (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) * 2
        this.scale = 0.5

        // 定时器对象
        this.ticker = null

        //生成金币盲盒
        this.Gold = null
        //金币生成速度
        this.createSpeed = 300
        //分数
        this.score = 0
        //定义一个碰撞的数组
        this.crashList = []
        //定时器
        this.timerAll = null
        //倒计时
        this.countDown = 0
        //盲盒
        this.blindBoxNum = 0
    }
    init() {
        this.asset.on('complete', function () {
            this.asset.off('complete')
            this.initStage()
        }.bind(this));
        this.asset.load()
    }
    initStage() {
        // console.log(this.width,this.height)
        // 舞台
        this.stage = new Hilo.Stage({
            renderType: 'canvas',
            width: this.width,
            height: this.height,
            scaleX: this.scale,
            scaleY: this.scale,
            container: this.page
        });
        this.stage.enableDOMEvent([Hilo.event.POINTER_START, Hilo.event.POINTER_MOVE, Hilo.event.POINTER_END, 'click', 'mousedown', 'ontouchstart']);
        // 启动定时器刷新页面 参数为帧率
        this.ticker = new Hilo.Ticker(60)
        // 舞台添加到定时队列中
        this.ticker.addTick(this.stage)
        // 添加动画类到定时队列
        this.ticker.addTick(Hilo.Tween);
        //启动ticker
        this.ticker.start(true);
        this.startGame();
    }
    startGame() {   //开始游戏
        startTime = new Date().getTime()
        this.initGolds();
        this.gameTime = this.setGameTime;
        this.score = 0;
        this.blindBoxNum = 0;
        this.crashList = [];
        this.gameStatus = "start"
        this.calcTime()
    }
    calcTime() { //游戏时间
        this.timerAll = setTimeout(() => {
            if (this.gameTime > 0) {
                this.gameTime--;
                this.calcTime()
            } else {
                setTimeout(() => {
                    this.gameOver()
                }, 500);
            }
        }, 1000);
    }
    clearCalcTime() {
        this.Gold.score = [10, 20, 50, 0]
        clearTimeout(this.timerAll);
    }
    gameOver() {//游戏结束调用
        if (this.Gold && this.Gold.stopCreateEnemy()) {
            this.Gold.stopCreateEnemy()
        }
        this.gameStatus = "end"
    }
    initGolds() {//初始化金币红包
        this.Gold = new goldContainer({
            id: 'background',
            height: this.height,
            width: this.width,
            createSpeed: this.createSpeed,
            pointerEnabled: true, // 不关闭事件绑定 无法操作舞台
            goldList: [this.asset.gold10, this.asset.gold20, this.asset.gold50, this.asset.blindBox],
            startTime
        }).addTo(this.stage, 2)
        this.Gold.on('click', (e) => {
            this.checkedGlod(e)
        })
        //舞台更新
        // this.stage.onUpdate = this.onUpdate.bind(this);
    }
    checkedGlod(e) {
        // console.log(e.eventTarget.type, e.eventTarget)
        if (e.eventTarget.type) {
            if (e.eventTarget.type == "blindBox") {
                this.blindBoxNum = 1
            }
            this.score += e.eventTarget.score
            e.eventTarget.remove()
        }
    }
    // onUpdate() {//舞台更新
    // }
}

第四步:创建一个goldBitmap.js文件

import Hilo from "hilojs";
let goldBitmap = Hilo.Class.create({
  Extends: Hilo.Bitmap,
  tweenChild: null,
  constructor: function (properties) {
    goldBitmap.superclass.constructor.call(this, properties);
    this.tweenChild = Hilo.Tween;
    this.onUpdate = this.onUpdate.bind(this);
    this.remove = this.remove.bind(this);
  },
  over() {
    this.removeFromParent();
  },
  checkedAnimation(bol) {
    if (bol) {
      //Tween.to创建一个缓动动画,让当前可视对象从当前属性(scaleX: .2,scaleY: .2)变换到目标属性(scaleX: 1.4, scaleY: 1.4)
      this.tweenChild.to(this,
        { scaleX: 6, scaleY: 6 },
        {
          duration: 600,  //完成这个变换的时长
        })
    }
  },
  remove() {
    // console.log(this)
    this.removeFromParent();
  },
  onUpdatefn() { },
  onUpdate() {
    if (this.parent.height < this.y) {
      this.removeFromParent();
      return
    }
  }
})

export default goldBitmap

第五步:创建一个goldContainer.js文件

import Hilo from "hilojs";
import goldBitmap from './goldBitmap'
let goldContainer = Hilo.Class.create({
    Extends: Hilo.Container,
    goldBitmapImg: null,
    timer: null, // 定时器
    goldList: [],
    createSpeed: 0,
    score: [10, 20, 50, 0],//分数
    ids: ['gold10', 'gold20', 'gold50', 'blindBox'],
    gold10Num: [],
    gold20Num: [],
    gold50Num: [],
    tween: null,
    startTime: null,
    differenceTime: 0,
    constructor: function (properties) {
        goldContainer.superclass.constructor.call(this, properties);
        this.startTime = properties.startTime
        this.tween = Hilo.Tween;
        this.creatEnemy();
        this.beginCreateEnemy();
    },
    random(lower, upper) {
        return Math.floor(Math.random() * (upper - lower + 1)) + lower;
    },
    creatEnemy() {//最大分数700
        // 金币雨持续时间15s,掉落61个,10金币50个,20金币10个,彩蛋1个
        let now = new Date().getTime()
        let differenceLine = parseInt((now - this.startTime) / this.createSpeed)
        let difference = parseInt((now - this.startTime) / 1000)
        this.differenceTime = difference
        let str = differenceLine + ''
        let s = Number(str.substring(str.length - 1))
        // console.log(differenceLine, '-', s)
        if (differenceLine < 50) {
            this.createGold(0, 290)
        }
        if (differenceLine == 26) {
            this.createGold(3, 300)
        }
        if (s == 4 || s == 8) {
            this.createGold(1, 170)
        }
    },
    createGold(index, enemySpeed) {
        let hold = undefined
        if (this.goldList[index].width && this.goldList[index].height) {//判断报错宽高
            hold = new goldBitmap({
                image: this.goldList[index],
                rect: [0, 0, this.goldList[index].width, this.goldList[index].height],
                width: this.goldList[index].width / 2,
                height: this.goldList[index].height / 2,
                scaleX: 3,//倍数
                scaleY: 3,//倍数
            }).addTo(this);
            hold.type = this.ids[index]
        }
        //随机掉落
        // hold.y = 600 * Math.random();
        hold.y = 0;
        hold.x = this.random(0, (this.width - this.goldList[index].width));
        // console.log('x',hold.x)
        hold.score = this.score[index]
        this.tween.to(hold, {//运动速度
            x: this.random(0, (this.width - this.goldList[index].width - 50)),
            y: this.height
        }, {
            duration: 1400 / enemySpeed * 1000,
            loop: false,
            onComplete: () => {
                hold.removeFromParent()
            }
        });

    },
    beginCreateEnemy() {//开始生成
        this.timer = setInterval(() => {
            this.creatEnemy();
        }, this.createSpeed);
    },
    stopCreateEnemy() {//停止生成并全部移除
        if (this.timer) {
            clearInterval(this.timer)
            this.removeAllChildren()
        }
    },
    checkCollision(enemy) {//碰撞检测
        console.log('enemy', enemy)
        // for (var i = 0, len = this.children.length; i < len; i++) {
        //     if (enemy.hitTestObject(this.children[i], true)) {
        //         return true;
        //     }
        // }
        // return false;
    }
})

export default goldContainer

到现在所有的js文件已经创建实现完成了

我这个是在vue中实现的代码如下:

index.vue

<template>
  <div class="fix">
    <div class="start" v-if="isSow">
      <start @open="startFn" />
    </div>
    <div class="hilo" v-else>
      <div class="time">
        剩余时间:{{ game.gameStatus == "end" ? 0 : gameTime }}s
      </div>
      <div ref="hilo" class="canvas"></div>
    </div>
    <Popup v-model="show" :close-on-click-overlay="false">
      <div class="result">
        <div class="res">
          <div class="top">
            <div class="jiangli">
              <img src="@/assets/images/gold/huodejiangli.png" alt="" />
            </div>
          </div>
          <div class="top1">
            <img src="@/assets/images/gold/gonxihuode.png" alt="" />
          </div>
          <div class="jinbi">
            <img src="@/assets/images/gold/jinbi.png" alt="" />
            <span>+{{ score || 0 }}</span>
          </div>
          <div class="saizhi">
            <img src="@/assets/images/gold/saizi12.png" alt="" />
            <span>+{{ blindBoxNum || 0 }}</span>
          </div>
          <div class="bottom">
            <Button @click="backHome" type="default" class="back"
              ><img src="@/assets/images/gold/allow_kxj.png" alt=""
            /></Button>
          </div>
        </div>
      </div>
    </Popup>
  </div>
</template>

<script>
import Game from "./js/game";
import start from "./start";
import { Popup, Button, Toast } from "vant";
export default {
  name: "game",
  mixins: [],
  components: { start, Popup, Button },
  data() {
    return {
      game: new Game(),
      isSow: true, //显示开始开始游戏页面
      show: false,
    };
  },
  created() {},
  computed: {
    score() {
      //金币分数
      return this.game.score;
    },
    blindBoxNum() {
      //盲盒数
      return this.game.blindBoxNum;
    },
    gameTime() {
      //游戏时间
      return this.game.gameTime;
    },
  },
  watch: {
    "game.gameStatus": {
      handler(newName) {
        if (newName == "end") {
          //  this.show = true;
          this.queryGold({ score: this.score, blindBoxNum: this.blindBoxNum });
        }
      },
      immediate: true,
    },
  },
  mounted() {},
  beforeDestroy() {
    this.game.gameOver();
  },
  destroyed() {},
  methods: {
    queryGold(parems) {
      console.log(parems);
      this.show = true;
    },
    startFn() {
      this.isSow = false;
      let that = this;
      this.$nextTick(() => {
        that.game.page = this.$refs.hilo;
        that.game.init();
      });
    },
    backHome() {
      this.show=false
    },
  },
};
</script>
<style lang="less" scoped>
.fix {
  width: 100%;
  height: 100vh;
  background-color: #0a080b; //1a1511
  background-image: url("../../assets/images/gold/gold-background.png");
  background-repeat: no-repeat;
  background-size: 100% auto;
  background-position: bottom center;
  .van-button {
    border: none;
    background: none;
    height: auto;
  }
  .start {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 100;
  }
  .hilo {
    width: 100%;
    height: 100%;
    position: relative;
    overflow: hidden;
    position: relative;
    .canvas {
      canvas {
        width: 100% !important;
        height: 99vh !important;
      }
    }
    .time {
      position: absolute;
      top: 50px;
      width: 100%;
      text-align: center;
      color: #fdf100;
      font-size: 35px;
      font-weight: 600;
    }
  }
  .van-popup {
    background: none;
    width: 90%;
    .result {
      display: flex;
      flex-direction: column;
      align-items: center;

      .res {
        background: #ffff;
        width: 100%;
        border: 4px solid #d98f2d;
        border-radius: 16px;
        overflow: hidden;
        .top {
          display: flex;
          align-items: center;
          justify-content: center;
          .jiangli {
            width: 70%;
            background-image: url("../../assets/images/gold/background54.png");
            background-repeat: no-repeat;
            background-size: 100% 100%;
            text-align: center;
            padding: 7px 0;
            img {
              width: 50%;
              height: auto;
            }
          }
        }
        .top1 {
          text-align: center;
          margin-top: 30px;
          img {
            width: 30%;
          }
        }
        .jinbi,
        .saizhi {
          display: flex;
          justify-content: center;
          align-items: center;
          margin-top: 30px;
          img {
            width: 80px;
            height: 80px;
          }
          span {
            font-size: 60px;
            font-weight: 600;
            color: #d98f2d;
            margin-left: 20px;
            text-shadow: 0 0 5px black, 0 0 10px black;
          }
        }
        .bottom {
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          background: #fdf100;
          padding: 30px 0;
          margin-top: 30px;

          .back {
            text-align: center;
            width: 50%;
            margin-top: 20px;
            img {
              width: 100%;
              height: auto;
            }
          }
        }
      }
    }
  }
}
</style>

start.vue

<template>
  <div class="start">
    <div class="content">
      <div class="center">
        <div class="zi">
          <div class="quan">
            <img src="@/assets/images/gold/3.png" alt="" v-if="ready == 3" />
            <img
              src="@/assets/images/gold/2.png"
              alt=""
              v-else-if="ready == 2"
            />
            <img
              src="@/assets/images/gold/1.png"
              alt=""
              v-else-if="ready == 1"
              class="zi_1"
            />
            <img src="@/assets/images/gold/3.png" alt="" v-else />
          </div>
        </div>
      </div>
      <div class="bottom">
        <Button
          @click="open"
          type="default"
          class="kaishi"
          :disabled="disabled"
        >
          <img src="@/assets/images/gold/lijikaiqi.png" alt=""
        /></Button>
      </div>
    </div>
  </div>
</template>

<script>
// console.log('start',end,endTime)
import { Button, Toast } from "vant";
export default {
  name: "start",
  components: {
    Button,
  },
  data() {
    return {
      show: false,
      ready: 0,
      disabled: false,
    };
  },
  computed: {},
  async mounted() {},
  created() {
    this.ready = 0;
    this.disabled = false;
  },
  methods: {
    open() {
      this.disabled = true;
      this.ready = 3;
      let timer = setInterval(() => {
        if (this.ready == 1) {
          clearInterval(timer);
          this.$emit("open");
        } else {
          this.ready--;
        }
      }, 1000);
    },
    closePopup() {
      this.show = false;
    },
  },
};
</script>

<style lang="less" scoped>
.start {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  .van-button {
    border: none;
    background: none;
    height: auto;
  }

  .content {
    width: 90%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    padding: 90px 0;

    .center {
      display: flex;
      justify-content: center;
      padding-top: 80px;
      position: relative;
      .zi {
        position: absolute;
        top: 0;
        left: 0;
        color: #ffff;
        width: 100%;
        text-align: center;
        .quan {
          display: inline-block;
          width: 260px;
          height: 260px;
          border: 10px solid #d98f2d;
          border-radius: 50%;
          position: relative;
          box-shadow: -5px 5px 10px -4px #d98f2d, 5px 5px 10px -4px #d98f2d;
          img {
            width: 130px;
            position: absolute;
            top: 0;
            left: 0;
            bottom: 0;
            right: 0;
            margin: auto;
          }
          img.zi_1 {
            width: 70px;
          }
        }
      }
    }
    .bottom {
      display: flex;
      flex-direction: column;
      align-items: center;
      .kaishi,
      .back {
        text-align: center;
        width: 80%;
        img {
          width: 100%;
          height: auto;
        }
      }
      .back {
        margin-top: 20px;
      }
    }
  }
}
</style>

这样就算完成了
可查看点击获取金币demo、大富翁demo,源码可查看gitee

转载请注明出处或者链接地址:https://www.qianduange.cn//article/14258.html
标签
评论
发布的文章

JSON File 格式详解

2024-08-08 23:08:37

nvm安装node一直没有npm

2024-08-08 23:08:25

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!