var timerArray = [], userOpenid = '', speedNormal = 0, speedQuick = 0, speedSlow = 0, runSpeed = 0, runDistance = 0, //100米长度 obstacleTimer = '', //障碍物作用的定时器 startLineHeight = 0, swipeLock = true, //人物滑动锁定 giftListLock = false, //礼品列表弹出锁定 vertigoMs = 2000, //眩晕毫秒数 manAnimateTimer = 0, //人物动画定时器 isSubmitUserInfo = false, //是否提交过用户信息 afId = ''; //初始化AnimationFrame (function() { var lastTime = 0; var vendors = ['webkit', 'moz']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; } }()); $(document).ready(function() { $('body').show(); _initLoader(); _initData(); }); var vm = avalon.define({ $id: 'parkour', alertText: '', runwayPosition: 50, //跑到位置 timeCount: 0, //计时毫秒数 costSeconds: 0, //跑步时显示的时间 manState: 'nm', //人物状态 manToggleType: 1, //人物动画帧 manToggleInterval: 100, //人物动画切换毫秒 curIntegral: 0, //当前积分 totalLife: 100, //总生命 totalIntegral: 0, //总积分 preloadPercent: 0, //预加载百分比 friendsList: [], //帮助好友列表 friendsNum: 0, //帮助好友人数 userName: '', //用户名称 vertigoTime: '2s', //眩晕作用剩余时间 baseScore: 0, //基础分数 timeScore: 0, //时间奖励 giftList: [], //总共奖品列表 myGiftList: [], //我的礼品列表 broadcastList: [], //公告列表 totalGameScore: 0, //本次游戏获得的总积分 accidentPrompt: '', //意外提示 frameRate: 0 //帧率 }); //跑步计时 function _runTime() { var runTimerId = setInterval(function() { vm.timeCount += 31; vm.costSeconds = _formatSecond(vm.timeCount); }, 31); timerArray.push(runTimerId); } function _formatSecond(ms) { return Math.floor(ms / 1000) + '.' + Math.floor((ms % 1000) / 100) + ((ms % 10) > 0 ? (ms % 10) : 0); } //初始化跑步界面的组件尺寸 function _initRunview() { $('#obstacle-prompt').height($('#obstacle-prompt').width() * 160 / 300); } //预加载图片 function _initLoader() { var loader = new resLoader({ resources : [ './img/countdown_bg_1.png', './img/countdown_bg_2.png', './img/countdown_bg_3.png', './img/destination_bg.png', './img/new_bg1.jpg', './img/person_nm_1.png', './img/person_nm_2.png', './img/show.png', './img/show_btn.png', ], onProgress : function(current, total) { vm.preloadPercent = Math.floor(current / total * 100); }, onComplete : function(total) { $('#load-progress').hide(); $('#main-bottom').show(); //图片加载完成后才能加载canvas gameMonitor.init(); } }); loader.start(); } function _initData() { var deviceWidth = $(window).width(); $('body').height($(window).height()); } //初始化首页广播 function _initBroadcast() { var marginLeft = 0, curIndex = 0; $('#broadcast').css('visibility', 'hidden'); setTimeout(function () { $('#broadcast').css('visibility', 'visible'); }, 500); var broadcastTimer = setInterval(function () { if ($('#broadcast .broadcast-slide').length < 1) { return false; } var wrapperWidth = 0; $('#broadcast .broadcast-slide').each(function () { //因为每个slide的margin-left为20px,所以这里要加20,outerWidth没生效 wrapperWidth += ($(this).width() + 20); }); $('#broadcast .broadcast-wrapper').width(wrapperWidth); marginLeft -= 3; $('#broadcast .broadcast-wrapper').css('margin-left', marginLeft + 'px'); var secondSlideLeft = $('#broadcast .broadcast-slide').eq(curIndex + 1).offset().left; if (secondSlideLeft < 0) { var html = '
'; $('#broadcast .broadcast-wrapper').append(html); var lastSlideWidth = $('#broadcast .broadcast-slide').eq(curIndex).width() + 20, curWrapperWidth = $('#broadcast .broadcast-wrapper').width(); $('#broadcast .broadcast-wrapper').width(curWrapperWidth + lastSlideWidth); curIndex++; } }, 100); timerArray.push(broadcastTimer); } //结束游戏 function _gameover() { $('#show').show(); $('#popup-container').show(); document.getElementById("mediaTwo").play() document.getElementById("mediaTwo").muted = false document.getElementById("mediaId").pause() document.getElementById("mediaId").muted = true _resizePopup(); } function _resizePopup() { // $('#popup-rule').height($('#popup-rule').width() * 829 / 581); // $('#popup-friend').height($('#popup-friend').width() * 729 / 581); // $('#popup-lucky').height($('#popup-lucky').width() * 709 / 583); $('#popup-game-result').height($('#popup-game-result').width() * 709 / 583); $('#gift-list').height($('#gift-list').width() * 750 / 501); $('#draw-result').height($('#draw-result').width()); $('#popup-my-gift').height($('#popup-my-gift').width() * 709 /583); $('#draw-failed').height($('#draw-failed').width() * 360 / 501); $('#draw-result-real').height($('#draw-result-real').width() * 841 / 581); } function _alert(content) { vm.alertText = content; $('#alert').show(); setTimeout(function () { $('#alert').hide(); }, 2000); } //游戏规则 function handleShowRule() { $('#popup-rule').show(); $('#popup-container').show(); _resizePopup(); } //帮助好友 function handleShowFriends() { $('#popup-friend').show(); $('#popup-container').show(); _resizePopup(); } //打开抽奖 function handleShowLucky() { $('#popup-lucky').show(); $('#popup-container').show(); _resizePopup(); } //返回首页,还原数据 function handleReturnMain() { if (manAnimateTimer) { clearInterval(manAnimateTimer); manAnimateTimer = 0; } $('#running-man').removeClass('left').removeClass('right'); $('#count-down').attr('class', 'bg-3'); vm.manState = 'nm'; vm.totalGameScore = vm.costSeconds = vm.timeCount = vm.runwayPosition = vm.baseScore = vm.curIntegral = vm.timeScore = 0; $('#view-main').show(); $('#view-game').hide(); handleClosePopup(); _initBroadcast(); gameMonitor.init(); } var blockData = { star: { width: 0.4, height: 79 / 85, src: './img/article/star1.png' }, speed: { width: 0.34, height: 78 / 70, src: './img/article/star1.png' }, roadblock: { width: 0.4, height: 97 / 97, src: './img/article/bomb1.png' }, bomb: { width: 0.5, height: 97 / 93, src: './img/article/bomb1.png' }, pool: { width: 0.6, height: 90 / 98, src: './img/article/car1.png' }, car: { width: 0.6, height: 90 / 98, src: './img/article/car1.png' } } var Block = function (type, left, top, width, height, src, id) { var blockImg = new Image(); blockImg.src = src; this.type = type; this.left = left; this.top = top; this.width = width; this.height = height; this.src = blockImg; this.id = id; this.isShow = false; } Block.prototype.paint = function(ctx){ var _this = this; this.src.onload = function () { ctx.drawImage(_this.src, _this.left, _this.top, _this.width, _this.height); } }; Block.prototype.move = function(ctx) { this.top += gameMonitor.bgSpeed; if(this.top > gameMonitor.h){ gameMonitor.blockList[this.id] = null; } else if (this.top > 0) { this.isShow = true; ctx.drawImage(this.src, this.left, this.top, this.width, this.height); } }; var Scale = function (ordinate, num) { this.ordinate = ordinate; this.text = '-' + num + 'm'; } Scale.prototype.move = function(ctx) { this.ordinate += gameMonitor.bgSpeed; if (this.ordinate > 0 && this.ordinate < gameMonitor.h) { ctx.fillText(this.text, 0, this.ordinate); } }; var gameMonitor = { w: $(window).width(), h: $(window).height(), bgDistance: 0, bgAdditionHeight: 0, //bgAddition是跑道附加素材 bgAdditionDistance: 0, runner: {}, frameCount: 0, swipeLock: true, totalDistance: 0, runwayLength: 0, bgSpeed: 0, baseSpeed: 0, //基础速度,bgSpeed在此基础上根据帧率发生变化 blockList: [], runActTimer: '', startLineHeight: 0, scaleHeight: 0, scaleList: [], isInit: false, speedNormal: 0, speedFast: 0, speedSlow: 0, collisionTimer: '', endLine: {}, rafId: '', lastTime: 0, init: function () { var _this = this, html = ''; this.lastTime = 0; this.w = $(window).width(); this.h = $(window).height(); if (!this.isInit) { html += ''; $('#view-game').append(html); } var canvas = document.getElementById('stage'); var ctx = canvas.getContext('2d'); ctx.clearRect(0, 0, _this.w, _this.h); this.totalDistance = this.runwayLength = this.w * 15; //跑道长度是宽度15倍 this.baseSpeed = this.speedNormal = this.bgSpeed = Math.round(this.runwayLength / 700); //25秒完成游戏,一秒60帧 this.speedFast = Math.round(this.speedNormal * 7 / 4); this.speedSlow = Math.round(this.speedNormal / 4); this.startLineHeight = this.w * 120 / 640; this.scaleHeight = this.runwayLength / 20; this.initBg(ctx); this.initEndline(); if (!this.isInit) { this.initListener(ctx); this.isInit = true; } }, initBg: function (ctx) { var _this = this, bgAddition = new Image(); this.bgDistance = 0; this.bg = new Image(); this.bg.src = './img/new_bg1.jpg'; this.bg.onload= function () { ctx.drawImage(_this.bg, 0, 0, _this.w, _this.h); } bgAddition.src = './img/new_bg1.jpg'; this.bgAddition = bgAddition; this.bgAdditionHeight = this.w * 721 / 640; this.bgAdditionDistance = 0 - this.bgAdditionHeight; this.initScale(ctx); this.initBlock(ctx, function (ctx) { _this.initRunner(ctx); }); }, initEndline: function (ctx) { this.endLine = new Image(); this.endLine.src = './img/destination_bg.png'; this.endLine.height = this.w / 660 * 109; }, initScale: function (ctx) { //刻度高度 ctx.font = 'bold 18px 苹方'; ctx.fillStyle = '#d26b60'; ctx.fillText('-5m', 0, this.h - this.startLineHeight - this.scaleHeight); ctx.fillText('-10m', 0, this.h - this.startLineHeight - this.scaleHeight * 2); this.scaleList = []; for (var i = 1; i <= 20; i++) { var ordinate = this.h - this.startLineHeight - this.scaleHeight * i; var scaleItem = new Scale(ordinate, 5 * i); this.scaleList.push(scaleItem); } }, initRunner: function (ctx) { var _this = this; this.runner = new Object(); //按照图片尺寸设定人物宽高 this.runner.size = [this.w * 0.2, this.w * 0.2 * 190 / 130]; this.runner.centerPositon = (this.w - this.runner.size[0]) / 2; this.runner.leftPosition = (this.w / 3 - this.runner.size[0]) / 2; this.runner.rightPositon = this.w / 3 * 2 + (this.w / 3 - this.runner.size[0]) / 2; this.runner.positon = [this.runner.centerPositon, this.h - this.runner.size[1]]; this.runner.animateState = 1; var runnerImg = { normal: './img/person_nm_' // fast: './img/person_sp_', // slow: './img/person_sl_', // stop: './img/person_st_', // die: './img/person_die_' } for (var key in runnerImg) { this.runner[key] = new Object(); for (var i = 1; i < 3; i++) { this.runner[key][i] = new Image(); this.runner[key][i].src = runnerImg[key] + i + '.png'; } } this.runner.curState = 'normal'; this.runner.normal[1].onload = function () { ctx.drawImage(_this.runner.normal[1], _this.runner.positon[0], _this.runner.positon[1], _this.runner.size[0], _this.runner.size[1]); } }, initListener: function (ctx) { var _this = this; $('#btn-begin').click(function () { document.getElementById("mediaId").play() document.getElementById("mediaId").muted = false $('#view-main').hide(); $('#view-game').show(); $('#count-down').show(); var readyCountNum = 3; var readyCountTimer = setInterval(function () { readyCountNum--; if (readyCountNum == 0) { clearInterval(readyCountTimer); $('#count-down').hide(); _this.run(ctx); _runTime(); } else { $('#count-down').attr('class', 'bg-' + readyCountNum); } }, 1000); }); this.initTouchEvent(); }, initTouchEvent: function () { var _this = this; touch.on('#view-game', 'touchstart', function (ev) { ev.preventDefault(); }); touch.on('#view-game', 'swipeup', function(ev) { ev.preventDefault(); }); touch.on('#view-game', 'swipedown', function(ev) { ev.preventDefault(); }); touch.on('#view-game', 'swipeleft', function(ev) { ev.preventDefault(); if (_this.swipeLock) { return false; } if (_this.runner.swipeState == 'left') { return false; } else if (_this.runner.swipeState == 'right') { _this.runner.swipeState = 'center'; _this.runner.positon[0] = _this.runner.centerPositon; } else { _this.runner.swipeState = 'left'; _this.runner.positon[0] = _this.runner.leftPosition; } }); touch.on('#view-game', 'swiperight', function(ev) { ev.preventDefault(); if (_this.swipeLock) { return false; } if (_this.runner.swipeState == 'left') { _this.runner.swipeState = 'center'; _this.runner.positon[0] = _this.runner.centerPositon; } else if (_this.runner.swipeState == 'right') { return false; } else { _this.runner.swipeState = 'right'; _this.runner.positon[0] = _this.runner.rightPositon; } }); }, initBlock: function (ctx, callback) { var _this = this; _this.blockList = []; var blockIndex = 0, runwayDataList = []; if (Math.random() > 0.5) { runwayDataList = [[{"type":"star","row":6},{"type":"roadblock","row":13},{"type":"star","row":22},{"type":"pool","row":26},{"type":"star","row":35},{"type":"speed","row":37},{"type":"speed","row":44},{"type":"star","row":56},{"type":"car","row":71},{"type":"speed","row":80},{"type":"star","row":83},{"type":"pool","row":88},{"type":"pool","row":97},{"type":"star","row":99}],[{"type":"star","row":1},{"type":"star","row":5},{"type":"star","row":8},{"type":"star","row":10},{"type":"star","row":16},{"type":"star","row":45},{"type":"star","row":51},{"type":"pool","row":58},{"type":"pool","row":65},{"type":"star","row":68},{"type":"star","row":73},{"type":"star","row":75},{"type":"star","row":76},{"type":"speed","row":77},{"type":"speed","row":84},{"type":"pool","row":90},{"type":"star","row":97}],[{"type":"roadblock","row":9},{"type":"roadblock","row":25},{"type":"star","row":28},{"type":"star","row":35},{"type":"star","row":37},{"type":"star","row":38},{"type":"speed","row":41},{"type":"star","row":42},{"type":"star","row":48},{"type":"roadblock","row":55},{"type":"star","row":58},{"type":"star","row":64},{"type":"pool","row":72},{"type":"star","row":74},{"type":"pool","row":78},{"type":"star","row":83},{"type":"bomb","row":86}]]; } else { runwayDataList = [[{"type":"star","row":1},{"type":"star","row":15},{"type":"speed","row":31},{"type":"speed","row":39},{"type":"star","row":41},{"type":"star","row":45},{"type":"star","row":49},{"type":"star","row":55},{"type":"pool","row":61},{"type":"star","row":63},{"type":"speed","row":70},{"type":"star","row":73},{"type":"car","row":76},{"type":"star","row":79},{"type":"star","row":81},{"type":"roadblock","row":84},{"type":"star","row":88},{"type":"star","row":89},{"type":"speed","row":94}],[{"type":"star","row":1},{"type":"star","row":8},{"type":"star","row":30},{"type":"pool","row":34},{"type":"star","row":38},{"type":"star","row":39},{"type":"bomb","row":46},{"type":"star","row":49},{"type":"pool","row":52},{"type":"star","row":57},{"type":"speed","row":59},{"type":"star","row":61},{"type":"pool","row":75},{"type":"star","row":79},{"type":"star","row":82},{"type":"roadblock","row":87},{"type":"speed","row":96}],[{"type":"star","row":5},{"type":"star","row":8},{"type":"pool","row":21},{"type":"star","row":23},{"type":"star","row":25},{"type":"star","row":31},{"type":"pool","row":35},{"type":"roadblock","row":55},{"type":"roadblock","row":64},{"type":"pool","row":72},{"type":"star","row":76},{"type":"pool","row":82}]]; } $.each(runwayDataList, function(runwayIndex, runwayData) { var baseLeftDistance = 0, lineWidth = _this.w / 3; if (runwayIndex == 0) { baseLeftDistance = 0; } else if (runwayIndex == 1) { baseLeftDistance = lineWidth; } else { baseLeftDistance = lineWidth * 2; } $.each(runwayData, function(index, val) { var curBlockData = blockData[val.type], itemWidth = curBlockData.width * lineWidth; var blockItem = new Block( val.type, (lineWidth - itemWidth) / 2 + baseLeftDistance, _this.h - (val.row / 100) * _this.runwayLength - _this.startLineHeight, curBlockData.width * lineWidth, itemWidth * curBlockData.height, curBlockData.src, blockIndex++ ); _this.blockList.push(blockItem); }); }); for (var i = 0; i < _this.blockList.length; i++) { var blockItem = _this.blockList[i]; if (blockItem) { blockItem.paint(ctx); } } callback(ctx); }, rollBg: function (ctx) { this.bgDistance += this.bgSpeed; if (this.bgDistance < this.h) { ctx.drawImage(this.bg, 0, this.bgDistance, this.w, this.h); } this.bgAdditionDistance += this.bgSpeed; for (var i = 0; i < 100; i++) { ctx.drawImage(this.bgAddition, 0, this.bgAdditionDistance - i * this.bgAdditionHeight, this.w, this.bgAdditionHeight); if (this.bgAdditionDistance - i * this.bgAdditionHeight <= 0) { break; } } }, drawRunner: function (ctx) { if (this.frameCount % 10 == 0) { this.runner.animateState == 1 ? this.runner.animateState = 2 : this.runner.animateState = 1; } ctx.drawImage(this.runner[this.runner.curState][this.runner.animateState], this.runner.positon[0], this.runner.positon[1], this.runner.size[0], this.runner.size[1]); }, drawScale: function () { ctx.fillText('-10m', 0, this.h - this.startLineHeight - this.scaleHeight * 2); }, //碰撞检测 collisionTest: function () { for (var i = 0; i < this.blockList.length; i++) { if (this.blockList[i] && this.blockList[i].isShow) { var blockItem = this.blockList[i], //小人中心点坐标 runnerHoriCenterCord = [this.runner.positon[0] + this.runner.size[0] / 2, this.runner.positon[1] + this.runner.size[1] / 2], //障碍物中心点坐标 blockHoriCenterCord = [blockItem.left + blockItem.width / 2, blockItem.top + blockItem.height / 2]; if (Math.abs(runnerHoriCenterCord[0] - blockHoriCenterCord[0]) < (this.runner.size[0] + blockItem.width) / 2 && Math.abs(runnerHoriCenterCord[1] - blockHoriCenterCord[1]) < (this.runner.size[1] + blockItem.height) / 2) { this.handleCollision(blockItem.type); this.blockList[i] = null; } } } }, handleCollision: function (type) { var _this = this; if (type == 'star') { vm.curIntegral++; } else if (type == 'speed') { vm.curIntegral++; // this.baseSpeed = this.speedFast; // this.runner.curState = 'fast'; // this.collisionRecover(); } else if (type == 'roadblock') { vm.curIntegral++; // this.baseSpeed = 0; // this.runner.curState = 'stop'; // this.swipeLock = true; // $('#obstacle-prompt').show(); // $('#obstacle-prompt').height($('#obstacle-prompt').width() * 160 / 300); // var vertigoTimer = setInterval(function () { // vertigoMs -= 100; // vm.vertigoTime = vertigoMs % 1000 > 0 ? vertigoMs / 1000 : vertigoMs / 1000 + '.0'; // if (vertigoMs <= 0) { // vm.manState = 'nm'; // _this.swipeLock = false; // $('#obstacle-prompt').hide(); // vertigoMs = 2000; // clearInterval(vertigoTimer); // } // }, 100); // this.collisionRecover(); } else if (type == 'pool') { vm.curIntegral++; // this.baseSpeed = this.speedSlow; // this.runner.curState = 'slow'; // this.collisionRecover(); } else if (type == 'car' || type == 'bomb') { vm.curIntegral+=5 // this.baseSpeed = 0; // this.runner.size = [this.w * 0.2, this.w * 0.2 * 159 / 143]; // this.runner.curState = 'die'; // this.swipeLock = true; // setTimeout(function () { // _this.endRun(); // }, 300); } }, collisionRecover: function () { var _this = this; if (this.collisionTimer) { clearTimeout(this.collisionTimer); } this.collisionTimer = setTimeout(function () { _this.runner.curState = 'normal'; _this.baseSpeed = _this.speedNormal; _this.swipeLock = false; }, 2000); }, drawEndLine: function (ctx) { if (this.runwayLength + this.runner.size[1] + this.h > 0) { ctx.drawImage(this.endLine, 0, 0 - (this.runwayLength + this.runner.size[1]) + this.h, this.w, this.endLine.height); } }, run: function (ctx) { var _this = this; _this.swipeLock = false; function animateRun () { var curTime = new Date().getTime(); if (_this.lastTime > 0) { _this.bgSpeed = _this.baseSpeed * (60 * (curTime - _this.lastTime) / 1000); } _this.lastTime = curTime; //注意顺序,先画背景,再画终点线,再画刻度,再画障碍物,最后画人物 ctx.clearRect(0, 0, _this.w, _this.h); _this.rollBg(ctx); _this.drawEndLine(ctx); for (var i = 0; i < _this.scaleList.length; i++) { var scaleItem = _this.scaleList[i]; if (scaleItem) { scaleItem.move(ctx); } } for (var i = 0; i < _this.blockList.length; i++) { var blockItem = _this.blockList[i]; if (blockItem) { blockItem.move(ctx); } } _this.frameCount++; _this.drawRunner(ctx); if (_this.frameCount % 5 == 0) { _this.collisionTest(); } _this.runwayLength -= _this.bgSpeed; if (_this.runwayLength + _this.runner.size[1] <= 0) { _this.endRun(); return false; } _this.rafId = window.requestAnimationFrame(animateRun); } animateRun(); }, endRun: function () { for (var i = 0; i < timerArray.length; i++) { clearInterval(timerArray[i]); } window.cancelAnimationFrame(this.rafId); this.swipeLock = true; //记录分数 var surplusLength = this.runwayLength + this.runner.size[1] < 0 ? 0 : this.runwayLength + this.runner.size[1]; vm.baseScore = Math.floor(80 * (1 - surplusLength / (this.totalDistance + this.runner.size[1]))); if (surplusLength <= 0) { var totalTime = Math.ceil(parseFloat(vm.costSeconds)); vm.timeScore = 20 - (totalTime > 25 ? totalTime - 25 : 0); } vm.totalGameScore = vm.baseScore + vm.curIntegral + vm.timeScore; vm.totalIntegral += vm.totalGameScore; _gameover(); } }