100行代码实现“Perfect Square”游戏

你玩过由Boombit团队开发的Perfect Square“完美方块”游戏吗?

调整方块的的大小,让它可以完美的落在底部的平台上(不能掉下去哦)。按住方块可以让它变大,松开后方块落下。听起来非常的简单,不过这个简单的用一个手指就能完成的游戏,没有一定的精确度和时间强迫症,还真玩不了!

Perfect Square

乍看起来像是一个物理游戏,悄悄告诉你,只用tween缓动就可以完成,感谢Phaser游戏引擎。

先看一下我做的游戏原型(点击图片查看):

PerfectSqure

点击并按住方块,让它慢慢变大,松开鼠标方块自由落下。和你看到的一样,原始游戏中的可爱的动画效果,完美的呈现了出来。

下面是游戏示例的代码,遗憾的是,代码中没有添加注释。没关系,我会在这周内,一步一步的向你解释实现的过程。


var game;
var bgColors = [0x62bd18, 0xff5300, 0xd21034, 0xff475c, 0x8f16b2, 0x588c7e, 0x8c4646];
var holeWidthRange = [40, 280];
var wallRange = [10, 70];
window.onload = function() {        
    game = new Phaser.Game(480, 640, Phaser.AUTO, "");
     game.state.add("PlayGame", playGame);
     game.state.start("PlayGame");
}
var playGame = function(game){};
playGame.prototype = {
     preload: function(){
          game.load.image("base", "base.png");
          game.load.image("square", "square.png");
          game.load.image("top", "top.png");
     },
     create: function(){
          game.scale.pageAlignHorizontally = true;
        game.scale.pageAlignVertically = true;
          game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
          var tintColor = bgColors[game.rnd.between(0, bgColors.length - 1)];
          game.stage.backgroundColor = tintColor; 
          this.leftSquare = game.add.sprite(0, game.height, "base");
          this.leftSquare.anchor.set(1, 1); 
          this.rightSquare = game.add.sprite(game.width, game.height, "base");
          this.rightSquare.anchor.set(0, 1); 
          this.leftWall = game.add.sprite(0, game.height - this.leftSquare.height, "top");
          this.leftWall.anchor.set(1, 1); 
          this.rightWall = game.add.sprite(game.width, game.height - this.rightSquare.height, "top");
          this.rightWall.anchor.set(0, 1);
          this.square = game.add.sprite(game.width / 2, - 400, "square");
          this.square.anchor.set(0.5);
          this.square.scale.setTo(0.2, 0.2);
          this.updateLevel();            
     },
     updateLevel: function(){
          var holeWidth = game.rnd.between(holeWidthRange[0], holeWidthRange[1]);
          var wallWidth = game.rnd.between(wallRange[0], wallRange[1]);
          var leftSquareTween = game.add.tween(this.leftSquare).to({
               x: (game.width - holeWidth) / 2
          }, 500, Phaser.Easing.Cubic.Out, true); 
          var rightSquareTween = game.add.tween(this.rightSquare).to({
               x: (game.width + holeWidth) / 2
          }, 500, Phaser.Easing.Cubic.Out, true);
          var leftWalltween = game.add.tween(this.leftWall).to({
               x: (game.width - holeWidth) / 2 - wallWidth
          }, 500, Phaser.Easing.Cubic.Out, true); 
          var rightWallTween = game.add.tween(this.rightWall).to({
               x: (game.width + holeWidth) / 2 + wallWidth
          }, 500, Phaser.Easing.Cubic.Out, true);
          var squareTween = game.add.tween(this.square).to({
               y: 150,
               angle: 50
          }, 1000, Phaser.Easing.Cubic.Out, true); 
          squareTween.onComplete.add(function(){
               game.input.onDown.add(this.grow, this);
               this.rotateTween = game.add.tween(this.square).to({
                    angle: 40
               }, 300, Phaser.Easing.Linear.None, true, 0, -1, true)        
          }, this)              
     },
     grow: function(){
          game.input.onDown.remove(this.grow, this);
          game.input.onUp.add(this.stop, this);
          this.growTween = game.add.tween(this.square.scale).to({
               x: 1,
               y: 1
          }, 1500, Phaser.Easing.Linear.None, true);                        
     },
     stop: function(){
          game.time.events.add(Phaser.Timer.SECOND * 2, function(){
               game.state.start("PlayGame");     
          }, this); 
          game.input.onUp.remove(this.stop, this);  
          this.growTween.stop(); 
          this.rotateTween.stop();
          this.rotateTween = game.add.tween(this.square).to({
               angle: 0
          }, 300, Phaser.Easing.Cubic.Out, true);
          if(this.square.width <= this.rightSquare.x - this.leftSquare.x){
               this.rotateTween.onComplete.add(function(){
                    this.fallTween = game.add.tween(this.square).to({
                         y: game.height + this.square.height
                    }, 600, Phaser.Easing.Cubic.Out, true);
               }, this);       
          }
          else{
               this.square.anchor.set(0.5, 1);
               if(this.square.width <= this.rightWall.x - this.leftWall.x){
                    var destY = game.height - this.leftSquare.height;  
               }
               else{
                    var destY = game.height - this.leftSquare.height - this.leftWall.height;
               }
               game.add.tween(this.square).to({
                    y: game.height - this.leftSquare.height
               }, 600, Phaser.Easing.Bounce.Out, true);       
          }
     }
}

正如你所看到的,代码中只用了缓动,没有使用任何物理引擎。

点击下载源文件

 

  • 原文名称:HTML5 prototype of iOS game “Perfect Square!” made with Phaser using only tweens in 100 lines of code
  • 原文链接: 点击阅读原文
  • 原文作者:Emanuele feronato