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