用Phaser制作iOS游戏circle path
前几天,我发布了教程“【HTML5游戏原型】用Phaser制作了TwinSpin游戏”,我一直都说要充分重用代码提高开发效率,今天就基于TwinSpin的代码,创建另外一个叫做Circle path的游戏原型,好吧,基本重现了原版的游戏。
我确定这个是Apple store推荐的特色游戏,适用平台是iPhone或iPad。
不管怎么样,下面就是游戏原型。把握好时机,点击或触摸屏幕,让小球停止旋转,并落到目标位置上去。
点击图片查看游戏
游戏的官方介绍里说《你的预感能力怎么样?瞬间判断能力如何?时间把握的好不好?反应能力高不高?》
这我不知道,我只知道游戏源代码和TwinSpin游戏非常相似。唯一的不同是这里使用了线性差值算法,实现了镜头跟随效果
我知道实现这个效果的方法有很多种,但我还是希望介绍线性差值法,因为我在Unity种也创建了这个算法原型,后续我会详细的介绍两个游在开发中遇到的问题。
下面是游戏源代码
var game; var ballDistance = 120; var rotationSpeed = 4; var angleRange = [25, 155]; var visibleTargets = 7; var bgColors = [0x62bd18, 0xffbb00, 0xff5300, 0xd21034, 0xff475c, 0x8f16b2]; window.onload = function() { game = new Phaser.Game(640, 960, Phaser.AUTO, ""); game.state.add("PlayGame", playGame); game.state.start("PlayGame"); } var playGame = function(game){}; playGame.prototype = { preload: function(){ game.load.image("ball", "ball.png"); game.load.image("target", "target.png"); game.load.image("arm", "arm.png"); game.scale.pageAlignHorizontally = true; game.scale.pageAlignVertically = true; game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL; }, create: function(){ this.savedData = localStorage.getItem("circlepath")==null?{score:0}:JSON.parse(localStorage.getItem("circlepath")); var style = { font: "bold 64px Arial", fill: "#ffffff" }; var text = game.add.text(0, game.height - 64, "Best score: "+this.savedData.score.toString(), style); this.destroy = false; this.saveRotationSpeed = rotationSpeed; this.tintColor = bgColors[game.rnd.between(0, bgColors.length - 1)]; do{ this.tintColor2 = bgColors[game.rnd.between(0, bgColors.length - 1)]; } while(this.tintColor == this.tintColor2) game.stage.backgroundColor = this.tintColor; this.targetArray = []; this.steps = 0; this.rotatingDirection = game.rnd.between(0, 1); this.gameGroup = game.add.group(); this.targetGroup = game.add.group(); this.ballGroup = game.add.group(); this.gameGroup.add(this.targetGroup); this.gameGroup.add(this.ballGroup); this.arm = game.add.sprite(game.width / 2, game.height / 4 * 2.7, "arm"); this.arm.anchor.set(0, 0.5); this.arm.tint = this.tintColor2; this.ballGroup.add(this.arm); this.balls = [ game.add.sprite(game.width / 2, game.height / 4 * 2.7, "ball"), game.add.sprite(game.width / 2, game.height / 2, "ball") ] this.balls[0].anchor.set(0.5); this.balls[0].tint = this.tintColor2; this.balls[1].anchor.set(0.5); this.balls[1].tint = this.tintColor2; this.ballGroup.add(this.balls[0]); this.ballGroup.add(this.balls[1]); this.rotationAngle = 0; this.rotatingBall = 1; var target = game.add.sprite(0, 0, "target"); target.anchor.set(0.5); target.x = this.balls[0].x; target.y = this.balls[0].y; this.targetGroup.add(target); this.targetArray.push(target); game.input.onDown.add(this.changeBall, this); for(var i = 0; i < visibleTargets; i++){ this.addTarget(); } }, update: function(){ var distanceFromTarget = this.balls[this.rotatingBall].position.distance(this.targetArray[1].position); if(distanceFromTarget > 90 && this.destroy && this.steps > visibleTargets){ this.gameOver(); } if(distanceFromTarget < 40 && !this.destroy){ this.destroy = true; } this.rotationAngle = (this.rotationAngle + this.saveRotationSpeed * (this.rotatingDirection * 2 - 1)) % 360; this.arm.angle = this.rotationAngle + 90; this.balls[this.rotatingBall].x = this.balls[1 - this.rotatingBall].x - ballDistance * Math.sin(Phaser.Math.degToRad(this.rotationAngle)); this.balls[this.rotatingBall].y = this.balls[1 - this.rotatingBall].y + ballDistance * Math.cos(Phaser.Math.degToRad(this.rotationAngle)); var distanceX = this.balls[1 - this.rotatingBall].worldPosition.x - game.width / 2; var distanceY = this.balls[1 - this.rotatingBall].worldPosition.y - game.height / 4 * 2.7; this.gameGroup.x = Phaser.Math.linearInterpolation([this.gameGroup.x, this.gameGroup.x - distanceX], 0.05); this.gameGroup.y = Phaser.Math.linearInterpolation([this.gameGroup.y, this.gameGroup.y - distanceY], 0.05); }, changeBall:function(){ this.destroy = false; var distanceFromTarget = this.balls[this.rotatingBall].position.distance(this.targetArray[1].position); if(distanceFromTarget < 20){ this.rotatingDirection = game.rnd.between(0, 1); var detroyTween = game.add.tween(this.targetArray[0]).to({ alpha: 0 }, 500, Phaser.Easing.Cubic.In, true); detroyTween.onComplete.add(function(e){ e.destroy(); }) this.targetArray.shift(); this.arm.position = this.balls[this.rotatingBall].position; this.rotatingBall = 1 - this.rotatingBall; this.rotationAngle = this.balls[1 - this.rotatingBall].position.angle(this.balls[this.rotatingBall].position, true) - 90; this.arm.angle = this.rotationAngle + 90; for(var i = 0; i < this.targetArray.length; i++){ this.targetArray[i].alpha += 1 / 7; } this.addTarget(); } else{ this.gameOver(); } }, addTarget: function(){ this.steps++; startX = this.targetArray[this.targetArray.length - 1].x; startY = this.targetArray[this.targetArray.length - 1].y; var target = game.add.sprite(0, 0, "target"); var randomAngle = game.rnd.between(angleRange[0] + 90, angleRange[1] + 90); target.anchor.set(0.5); target.x = startX + ballDistance * Math.sin(Phaser.Math.degToRad(randomAngle)); target.y = startY + ballDistance * Math.cos(Phaser.Math.degToRad(randomAngle)); target.alpha = 1 - this.targetArray.length * (1 / 7); var style = { font: "bold 32px Arial", fill: "#" + this.tintColor.toString(16), align: "center" }; var text = game.add.text(0, 0, this.steps.toString(), style); text.anchor.set(0.5); target.addChild(text); this.targetGroup.add(target); this.targetArray.push(target); }, gameOver: function(){ localStorage.setItem("circlepath",JSON.stringify({ score: Math.max(this.savedData.score, this.steps - visibleTargets) })); game.input.onDown.remove(this.changeBall, this); this.saveRotationSpeed = 0; this.arm.destroy(); var gameOverTween = game.add.tween(this.balls[1 - this.rotatingBall]).to({ alpha: 0 }, 1000, Phaser.Easing.Cubic.Out, true); gameOverTween.onComplete.add(function(){ game.state.start("PlayGame"); },this) } }
点击下载源代码。你的最好成绩是多少?
- 原文名称:HTML5 prototype of iOS game “Circle Path” made with Phaser
- 原文链接: 点击阅读原文
- 原文作者:Emanuele feronato
联系作者
这个赞一个。。