在vue中实现接物类小游戏

先放张效果图

<template><div id="container"><div id="guidePanel"></div><div id="gamepanel"><div class="score-wrap"><div class="heart"></div><span id="score">0</span></div><canvas v-show="isShowCanvas" id="stage"></canvas></div><div id="gameoverPanel"></div><div id="resultPanel"><!-- <div class="weixin-share"></div> --><a href="javascript:void(0)" class="replay"></a><div id="fenghao"></div><!-- <div id="scorecontent">您在<span id="stime" class="lighttext">2378</span>秒内抢到了<span id="sscore" class="lighttext">21341</span>个月饼<br>超过了<span id="suser" class="lighttext">31%</span>的用户!</div> --><!-- <div class="textc"><span class="btn1 share">请小伙伴吃月饼</span></div> --></div><audio style="display: none;" id="media" src="https://ppt-mp3cdn.hrxz.com/d/file/filemp3/hrxz.com-owjof3jyx1p46949.mp3"></audio><img :class="{ 'isRotate': isRotateMusic }" class="music_btn" :src="isPlayMusic ? '/static/image/active/musicOn.png' : '/static/image/active/musicOff.png'" alt="音乐播放" @click="playPause"></div>
</template><script>
export default {name: 'activeTest',data () {return {isShowCanvas: true,isRotateMusic: false,isPlayMusic: true}},mounted () {// const self = this// 实现canvas铺满整个屏幕var canvas = document.getElementById('stage')canvas.setAttribute('width', window.innerWidth)canvas.setAttribute('height', window.innerHeight)// 接物类function Ship (ctx) {// 预加载图片// gameMonitor.im.loadImage(['/static/game/static/img/player.png'])this.width = 70this.height = 70this.left = gameMonitor.w/2 - this.width/2this.top = gameMonitor.h - this.height// this.player = gameMonitor.im.createImage('/static/game/static/img/player.png')let myImg = new Image()myImg.src = '/static/game/static/img/player.png'this.player = myImgthis.paint = function () {// 取消上下移动ctx.drawImage(this.player, this.left, gameMonitor.h - this.height, this.width, this.height)}// 保存接收物移动的位置this.setPosition = function (event) {var tarL = event.changedTouches[0].clientX// 取消上下移动// var tarT = event.changedTouches[0].clientY// 测试减少计算 能否减少移动飞船时的重影this.left = tarL - 35// this.top = tarT - this.height/2if (this.left < 0) {this.left = 0}if (this.left > gameMonitor.w - this.width) {this.left = gameMonitor.w - this.width}// if (this.top > gameMonitor.h - this.height) {//     this.top = gameMonitor.h - this.height// }// if (this.top < gameMonitor.h - this.height) {//     this.top = gameMonitor.h - this.height// }this.paint()}// 监听touch时间,来调用setPosition来计算位置this.controll = function () {const _this = thisconst stage = $('#gamepanel')let move = falsestage.on(gameMonitor.eventType.start, function (event) {_this.setPosition(event)move = true}).on(gameMonitor.eventType.end, function () {move = false}).on(gameMonitor.eventType.move, function (event) {event.preventDefault()if(move) {_this.setPosition(event) }})}// 每次帧刷新时做碰撞检测(两圆心的距离小于半径之和,则认为发生了碰撞)this.eat = function (foodlist) {for(let i = foodlist.length-1; i >= 0; i--) {let f = foodlist[i]if (f) {const l1 = this.top+this.height/2 - (f.top+f.height/2)const l2 = this.left+this.width/2 - (f.left+f.width/2)const l3 = Math.sqrt(l1*l1 + l2*l2)if (l3 <= this.height/2 + f.height/2) {foodlist[f.id] = nullif (f.type == 0) {gameMonitor.stop()$('#gameoverPanel').show()self.isShowCanvas = falsesetTimeout(function () {$('#gameoverPanel').hide()$('#resultPanel').show()gameMonitor.getScore()}, 2000)} else {document.querySelector('#media').currentTime = 0document.querySelector('#media').play()$('#score').text(++gameMonitor.score)$('.heart').removeClass('hearthot').addClass('hearthot')setTimeout(function () {$('.heart').removeClass('hearthot')}, 200)}}}}}}/*** 掉落物类* type 0 == 炸弹 1 == 好东西*/function Food (type, left, id) {// 加速的时间间隔this.speedUpTime = 600this.id = idthis.type = typethis.width = 50this.height = 50this.left = leftthis.top = -50// 掉落时间this.speed = 0.01 * Math.pow(1.2, Math.floor(gameMonitor.time/this.speedUpTime))console.log(this.speed);this.loop = 0const p = this.type == 0 ? '/static/game/static/img/food1.png' : '/static/game/static/img/food2.png'this.pic = gameMonitor.im.createImage(p)}Food.prototype.paint = function (ctx) {ctx.drawImage(this.pic, this.left, this.top, this.width, this.height)}Food.prototype.move = function (ctx) {if (gameMonitor.time % this.speedUpTime == 0) {this.speed *= 1.2}this.top += ++this.loop * this.speedif (this.top>gameMonitor.h) {gameMonitor.foodList[this.id] = null} else {// 去掉上下移动// this.paint(ctx)}}// 图片加载器,让浏览器预加载图片,方便直接调用function ImageMonitor () {let imgArray = []return {// 返回当前数组中对应的图片,如果不存在该图片,则new一个来返回createImage: function (src) {return typeof imgArray[src] != 'undefined' ? imgArray[src] : (imgArray[src] = new Image(), imgArray[src].src = src, imgArray[src])},// 接收一个数组和一个回调函数,把数组中的图片路径逐一加载,保存到一个数组中,最后一张图片加载完后执行一个回调函数loadImage: function (arr, callback) {for(let i = 0, l = arr.length; i < l; i++) {let img = arr[i]imgArray[img] = new Image()imgArray[img].onload = function () {if(i == l-1 && typeof callback == 'function') {callback()}}imgArray[img].src = img}}}}var gameMonitor = {w: window.innerWidth,h: window.innerHeight,bgWidth: window.innerWidth,bgHeight: window.innerHeight,time: 0,timmer: null,bgSpeed: 2,bgloop: 0,score: 0,im: new ImageMonitor(),foodList: [],bgDistance: 0,//背景位置eventType: {start : 'touchstart',move : 'touchmove',end : 'touchend'},init: function(){var _this = this;var canvas = document.getElementById('stage')var ctx = canvas.getContext('2d')//绘制背景var bg = new Image()_this.bg = bgbg.onload = function(){ctx.drawImage(bg, 0, 0, _this.bgWidth, _this.bgHeight);           }bg.src = '/static/game/static/img/bg.jpg'_this.initListener(ctx)},initListener: function (ctx) {const _this = thisconst body = $(document.body)$(document).on(gameMonitor.eventType.move, function(event){event.preventDefault()})body.on(gameMonitor.eventType.start, '.replay, .playagain', function(){$('#resultPanel').hide()self.isShowCanvas = trueconst canvas = document.getElementById('stage')const ctx = canvas.getContext('2d')_this.ship = new Ship(ctx)_this.ship.controll()_this.reset()_this.run(ctx)})body.on(gameMonitor.eventType.start, '#frontpage', function(){$('#frontpage').css('left', '-100%')})body.on(gameMonitor.eventType.start, '#guidePanel', function(){$(this).hide()self.isRotateMusic = truedocument.querySelector('#media').playbackRate = 1_this.ship = new Ship(ctx)_this.ship.paint()_this.ship.controll()gameMonitor.run(ctx)})},// 生成滚动的背景rollBg: function(ctx){// if(this.bgDistance>=this.bgHeight){//     this.bgloop = 0// }// this.bgDistance = ++this.bgloop * this.bgSpeed// ctx.drawImage(this.bg, 0, this.bgDistance-this.bgHeight, this.bgWidth, this.bgHeight)ctx.drawImage(this.bg, 0, 0, this.bgWidth, this.bgHeight)},run: function(ctx){var _this = gameMonitorctx.clearRect(0, 0, _this.bgWidth, _this.bgHeight)_this.rollBg(ctx)//绘制飞船_this.ship.paint()_this.ship.eat(_this.foodList)//产生月饼_this.genorateFood()//绘制月饼for (let i = _this.foodList.length-1; i>=0; i--) {var f = _this.foodList[i]if (f) {f.paint(ctx)f.move(ctx)}}// 通过setTimeout来控制帧率_this.timmer = setTimeout(function () {gameMonitor.run(ctx)}, Math.round(1000/200))_this.time++},stop: function () {var _this = this$('#stage').off(gameMonitor.eventType.start + ' ' +gameMonitor.eventType.move)setTimeout(function () {clearTimeout(_this.timmer)}, 0)},// 生成食物genorateFood: function () {var genRate = 70 //产生月饼的频率var random = Math.random()if (random*genRate>genRate-1) {var left = Math.random()*(this.w - 50)// 随机生成食物类型 bad goodvar type = Math.floor(left) % 2 == 0 ? 0 : 1var id = this.foodList.lengthvar f = new Food(type, left, id)this.foodList.push(f)}},// 点击在玩一次后 重置所有数据reset: function(){this.foodList = []this.bgloop = 0this.score = 0this.timmer = nullthis.time = 0$('#score').text(this.score)},getScore: function () {// var time = Math.floor(this.time/60)// var score = this.score// var user = 1// if(score==0){//     $('#scorecontent').html('真遗憾,您竟然<span class="lighttext">一个</span>月饼都没有抢到!')//     $('.btn1').text('大侠请重新来过').removeClass('share').addClass('playagain')//     $('#fenghao').removeClass('geili yinhen').addClass('yinhen')//     return// }// else if(score<10){//     user = 2// }// else if(score>10 && score<=20){//     user = 10// }// else if(score>20 && score<=40){//     user = 40// }// else if(score>40 && score<=60){//     user = 80;// }// else if(score>60 && score<=80){//     user = 92// }// else if(score>80){//     user = 99// }$('#fenghao').removeClass('geili yinhen').addClass('geili')// $('#scorecontent').html('您在<span id="stime" class="lighttext">2378</span>秒内抢到了<span id="sscore" class="lighttext">21341</span>个月饼<br>超过了<span id="suser" class="lighttext">31%</span>的用户!')// $('#stime').text(time)// $('#sscore').text(score)// $('#suser').text(user+'%')// $('.btn1').text('请小伙伴吃月饼').removeClass('playagain').addClass('share')},}gameMonitor.init()},methods: {playPause () {const music = document.querySelector('#media')this.isRotateMusic = !this.isRotateMusicthis.isPlayMusic = !this.isPlayMusicdocument.querySelector('#media').muted = !this.isPlayMusic}}
}
</script><style scoped>
#container{position: relative;overflow: hidden;width: 100%;height: 100%;
}
#startgame{position: absolute;right: 20px;bottom: 20px;
}
#gamepanel{width: 100%;height: 100%;
}
#stage{background-color: #CCC;
}
.score-wrap {background: url('/static/game/static/img/scorebg.png') no-repeat;background-size: 100%;color: #FFF;/*display: none;*/font-family: "Helvetica","Microsoft YaHei",sans-serif;font-style: italic;font-size: 17px;font-weight: 700;height: 32px;letter-spacing: 2px;padding: 7px 10px;position: absolute;right: 20px;text-align: right;text-shadow: 1.5px 0 0 #613209,-1.5px 0 0 #613209,0 1px 0 #613209,0 -1.5px 0 #613209,1px 1px 0 #613209,-1px 1px 0 #613209,1px -1px 0 #613209,-1px -1px 0 #613209;top: 10px;width: 105px;z-index: 1005
}.score-wrap div {background: url('/static/game/static/img/heart.png') no-repeat;background-size: 100%;height: 26px;left: 2px;position: absolute;top: 2px;width: 26px;z-index: 1009
}div.hearthot {-webkit-animation: fire .2s linear;-o-animation: fire .2s linear;animation: fire .2s linear
}@-webkit-keyframes fire {0% {opacity: 1;-webkit-transform: scale(1.1);-moz-transform: scale(1.1);-ms-transform: scale(1.1);-o-transform: scale(1.1);transform: scale(1.1)}100% {opacity: 0;-webkit-transform: scale(3.0);-moz-transform: scale(3.0);-ms-transform: scale(3.0);-o-transform: scale(3.0);transform: scale(3.0)}
}@keyframes fire {0% {-webkit-transform: scale(1.1);-moz-transform: scale(1.1);-ms-transform: scale(1.1);-o-transform: scale(1.1);transform: scale(1.1)}100% {-webkit-transform: scale(1.0);-moz-transform: scale(1.0);-ms-transform: scale(1.0);-o-transform: scale(1.0);transform: scale(1.0)}
}
#guidePanel {background: rgba(0,0,0,0.6) url('/static/game/static/img/startbg.png') center 50% no-repeat;background-size: 219px 369px;height: 100%;left: 0;position: absolute;top: 0;width: 100%;z-index: 10000
}
#gameoverPanel {background: rgba(0,0,0,0.8) url('/static/game/static/img/gameover.jpeg') center 30% no-repeat;background-size: 230px 260px;top: 0
}#gameoverPanel,#resultPanel {display: none;height: 100%;position: absolute;width: 100%;z-index: 10000
}#resultPanel{background:url('/static/game/static/img/endpage.jpg') center top no-repeat;background-size: 100% 100%;
}#resultPanel,#resultPanel .weixin-share {left: 0;top: 0
}
#resultPanel .weixin-share {background: rgba(0,0,0,.8) url('/static/game/static/img/weixin.png') right top no-repeat;background-size: 212px 196px;display: none;height: 100%;position: absolute;width: 100%;z-index: 100
}#resultPanel .replay {background: url('/static/game/static/img/replay.png') 0 0 no-repeat;height: 36px;line-height: 36px;right: 24px;overflow: hidden;position: absolute;top: 11px;width: 86px;z-index: 10;color: #E44324;text-align: right;padding-right: 6px;font-weight: 700;font-size: 12px;
}
#resultPanel .panel,#scoreBoard .score-result {display: none;height: 100%;left: 0;position: absolute;top: 0;width: 100%
}
#fenghao{height: 68px;margin-top: 90px;
}
#scorecontent{font-size: 16px;font-weight: 700;color: #FFF;text-align: center;line-height: 1.8em;margin-top: 5px;
}
.lighttext{color: #F6DE0A;
}
.geili{background: url('/static/game/static/img/geili.png') center no-repeat;
}
.yinhen{background: url('/static/game/static/img/yinhen.png') center no-repeat;
}
.textc{text-align: center;
}
.btn1, .btn2{display: inline-block;width: 196px;height: 54px;line-height: 54px;color: #FFF;font-size: 20px;border-radius: 5px;text-align: center;
}
.btn1{margin-top: 22px;background-color: #E8722C;
}
.btn2{margin-top: 12px;border: 1px solid #6A6B6D;}
#container .music_btn {position: absolute;left: 20px;top: 20px;width: 36px;height: 36px;display: block;
}
#container .isRotate {animation: rotating 1.2s linear infinite;
}
@keyframes rotating {0% {transform: rotate(0);}100% {transform: rotate(360deg);}
}
</style>

这里是原文链接,不是vue的

canvas实现H5接物类小游戏相关推荐

  1. 《uni-app》一个非canvas的飞机对战小游戏实现-碰撞检测的实现

    这是一个没有套路的前端博主,热衷各种前端向的骚操作,经常想到哪就写到哪,如果有感兴趣的技术和前端效果可以留言-博主看到后会去代替大家踩坑的-接下来的几篇都是uni-app的小实战,有助于我们更好的去学 ...

  2. 《uni-app》一个非canvas的飞机对战小游戏实现-敌机模型实现

    这是一个没有套路的前端博主,热衷各种前端向的骚操作,经常想到哪就写到哪,如果有感兴趣的技术和前端效果可以留言-博主看到后会去代替大家踩坑的-接下来的几篇都是uni-app的小实战,有助于我们更好的去学 ...

  3. 《uni-app》一个非canvas的飞机对战小游戏实现(一)准备

    这是一个没有套路的前端博主,热衷各种前端向的骚操作,经常想到哪就写到哪,如果有感兴趣的技术和前端效果可以留言-博主看到后会去代替大家踩坑的-接下来的几篇都是uni-app的小实战,有助于我们更好的去学 ...

  4. 《uni-app》一个非canvas的飞机对战小游戏-启动页

    这是一个没有套路的前端博主,热衷各种前端向的骚操作,经常想到哪就写到哪,如果有感兴趣的技术和前端效果可以留言-博主看到后会去代替大家踩坑的-接下来的几篇都是uni-app的小实战,有助于我们更好的去学 ...

  5. 《uni-app》一个非canvas的飞机对战小游戏实现-我方飞机实现

    这是一个没有套路的前端博主,热衷各种前端向的骚操作,经常想到哪就写到哪,如果有感兴趣的技术和前端效果可以留言-博主看到后会去代替大家踩坑的-接下来的几篇都是uni-app的小实战,有助于我们更好的去学 ...

  6. 使用canvas写一个flappy bird小游戏

    简介 canvas 是HTML5 提供的一种新标签,它可以支持 JavaScript 在上面绘画,控制每一个像素,它经常被用来制作小游戏,接下来我将用它来模仿制作一款叫flappy bird的小游戏. ...

  7. h5忍者小游戏源码下载

    下载地址一款忍者html5小游戏源码,可以当做手机端h5小游戏.在游戏中点击来改变忍者行动的路线,在游戏途中尽可能多的获得金币,要注意的是地图会随机生成,现在就让我们一起来试试吧! dd:

  8. 226款H5手机端小游戏源码下载 - HTML+JavaScript开发的网页小游戏开源源码大合集,经过亲测可用!

    演示端:http://game.tutou.wang/  (手机访问)  可在线试玩的分享. 链接:https://pan.baidu.com/s/1-R6wEZjLXYm0iowBJLFS8g?pw ...

  9. VUE+Canvas实现财神爷接元宝小游戏

    之前的canvas小游戏系列欢迎大家戳: <VUE实现一个Flappy Bird~~~> <VUE+Canvas实现上吊火柴人猜单词游戏> <VUE+Canvas 实现桌 ...

最新文章

  1. 解读Python的命名空间
  2. AAAI 2021: 微调对小样本学习究竟起何作用?搜索或是解决方案
  3. “私有云”安全的“过渡”时期-“云朵”方案的设计思路
  4. async await异步发送请求例子
  5. eclipse为什么导入不了awt_为什么选择javafx?
  6. IOS之SplitViewController的使用
  7. apache+php32位平台安装
  8. 用excel制作双层饼图_双层饼图,让你的工作更出彩
  9. Python3.10 结构化模式匹配 PEP 634
  10. 微课在小学计算机教学中的应用,微课技术在小学信息技术课堂中的应用
  11. 还在为满意的渐变色发愁吗?10+个网站帮你解决烦恼
  12. 计算机网络技术班级16字口号,十六字班级加油口号
  13. 神经网络学说的主要观点,神经网络研究属于下列
  14. 谷歌浏览器账号密码自动填充和明文显示问题
  15. Git安装及密钥的生成
  16. 艾永亮:英语教育往事:一部商业的进化史
  17. android怎么获取专辑名称,获取相册名称为Android的专辑封面
  18. IPA进军城市大脑丨实在智能与银江技术达成战略合作
  19. EDG为何刷爆你的朋友圈?是什么让年轻人那么激动?作为程序员你关注了么?
  20. 专科学游戏建模好找工作嘛?

热门文章

  1. JAVA面向对象程序编程
  2. Json4s的一些用法 JSon转对象实体 Json转Map Map转Json
  3. 中国自推式割晒机行业市场供需与战略研究报告
  4. C语言 良乡足球场 割草机问题
  5. 复利C语言,C计算复利增长
  6. python爬虫案例(二):大学排名
  7. php有strock吗,PHP应用JSON技巧讲解
  8. IDEA报Cannot resolve symbol ‘XXX‘
  9. 了解身边的超线程、双核、双cpu
  10. RS485接口说明——简单明了