Đã chán với việc lập trình trang web .Chúng ta hãy thư giãn và thỏa trí 1 chút với việc lập trình game và vì đã tốn công làm sao lại không làm đa nền tảng và không tốn công phải mày mò thêm ngôn ngữ mới chúng ta có thể làm game HTML5.

 


 

HTML5 không còn xa lạ gì nữa và với tiêu chí tạo ra để phát triên trên nền tảng di động ta không phải lo về việc tương thích và phân mảnh của các thiết bị di động hơn nữa ta cũng không khó khăn gì khi chuyển 1 ứng dụng HTML5 thành natural app ,và js thì là phần không thể thiếu của lập trình web. Đầu tiên ta hãy chọn  game framework tôi chọn thử Phaser vì gọn nhẹ và được đánh giá cao cũng như miễn phí hãy vào trang chủ để tìm hiểu sâu hơn, tôi cảm thấy khá thích game  ConnectMe rất thú vị và cảm thấy nếu có thể tạo game như vậy là quá tốt. Về Phaser tôi vẫn chưa có thời gian khám phá hết nên sẽ không ý kiến gì nhiều bài viết dưới đây được tham khảo từ tut của emanueleferonato để cho mọi người hình dung được tạo game HTML5 đơn giản

Một điểm khá thú vị của Phaser trong bài viết là quản lí State(trạng thái). Chúng ta dùng State trong việc phát triển game thế nào? Về cơ bản nếu game của bạn được chia thành những Block như màn hình game ,  thông báo, menu …. Mỗi thứ như thế đều có thể phát triển như Block. Việc quản lí State rất hữu dụng trong việc quản lí bộ nhớ , giải phóng tài nguyên và bộ hủy.

Trước khi bắt đầu hãy nhìn … thành quả để bạn có thể hình dung mình đang làm gì

 

Ý tưởng rất đơn giản : Mãy sẽ ra số ngẫu nhiên từ 0-9 và bạn sẽ dự đoán số tiếp theo sẽ cao hơn hay thấp hơn số hiện tại đang thấy. Mỗi lần đoán đúng được thêm 1 điểm và đoán sai sẽ gameover . Hãy thử khả năng của bạn và comment số điểm cao nhất mà bạn đạt được có hơn 8 điểm của tôi không ^^.

Lưu ý : Bản game trên vì để chèn vào bài nên tôi đã lấy từ web khác và có bug số điểm không trở về 0 nếu không refresh trang .Bug này đã fix với souce upload ở cuối bài.

Giờ hãy phân tích trình tự :

Như bạn thấy game bắt đầu với loading rồi main menu tiếp theo là Game chính và cuối cùng là màn hình game over với khả năng gọi lại game.

Mỗi màn hình được xem như 1 state và nên chúng ta thấy có 4 state và 1 state đặc biệt.

Bắt đầu với file đầu tiên của chùng ta index.html



    <head>
        <script src="phaser.min.js"></script>
        <script src="src/boot.js"></script>
        <script src="src/preload.js"></script>
        <script src="src/gametitle.js"></script>
        <script src="src/thegame.js"></script>
        <script src="src/gameover.js"></script>    
            <style>
                body{margin:0}
            </style>
        <script>
            (function() {
                var game = new Phaser.Game(320, 480, Phaser.CANVAS, "game");
                game.state.add("Boot",boot);
                game.state.add("Preload",preload);
                game.state.add("GameTitle",gameTitle);
                game.state.add("TheGame",theGame);
                game.state.add("GameOver",gameOver);
                game.state.start("Boot");
            })();    
        </script>
    </head>
 

 

 

 

Phần Head khá dễ hiểu đầu tiên ta load framework Phaser sau đó là 5 file tương ứng với 5 state của chúng ta. Việc chia thành 5 file nhỏ là không bắt buộc và cần thiết tôi chỉ làm thế để quản lí tốt hơn và tương ứng với 5 state chúng ta sẽ trải qua.

Việc gán state để gọi được làm bằng  game.state.add: với tham số đầu là tên state và tham số 2 là tên function sẽ gọi trong state đó.


game.state.add("Boot",boot);

game.state.add("Preload",preload);

game.state.add("GameTitle",gameTitle);

game.state.add("TheGame",theGame);

game.state.add("GameOver",gameOver);

 

 

 

Cuối cùng ta gọi state đầu tiền Boot với game.state.start

 


game.state.start("Boot");

 

Giờ ta hãy chuyển đến xem boot.js


var boot = function(game){

    console.log("%cStarting my awesome game", "color:white; background:red");

};

  

boot.prototype = {

    preload: function(){

          this.game.load.image("loading","assets/loading.png");

    },

      create: function(){

        this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;

        this.scale.pageAlignHorizontally = true;

        this.scale.setScreenSize();

        this.game.state.start("Preload");

    }

}

 

 

 

Boot chính là state đặc biệt của chúng ta chỉ với nhiệm vụ là điều chính kích cỡ màn hình để phù hợp và lấy ảnh loading (để dùng cho state sau). Khi đã căn chỉnh xong ta tới với state tiếp theo Preload với preload.js


preload.prototype = {

    preload: function(){

          var loadingBar = this.add.sprite(160,240,"loading");

          loadingBar.anchor.setTo(0.5,0.5);

          this.load.setPreloadSprite(loadingBar);

        this.game.load.spritesheet("numbers","assets/numbers.png",100,100);

        this.game.load.image("gametitle","assets/gametitle.png");

        this.game.load.image("play","assets/play.png");

        this.game.load.image("higher","assets/higher.png");

        this.game.load.image("lower","assets/lower.png");

        this.game.load.image("gameover","assets/gameover.png");

    },

      create: function(){

        this.game.state.start("GameTitle");

    }

}

 

 

 

Nhiệm vụ state này là load tài nguyên cần thiết để bắt đầu chơi điều thú vị duy nhất ở đây có lẽ là  cách thể hiện loading


var loadingBar = this.add.sprite(160,240,"loading");

loadingBar.anchor.setTo(0.5,0.5);

this.load.setPreloadSprite(loadingBar)

 

 

 

với load.setPreloadSprite Phaser thể hiện tham số truyền vào như thanh loading

và khi Preload hoàn tất chúng ta lại chuyển tới state tiếp theo GameTitle


var gameTitle = function(game){}

gameTitle.prototype = {

      create: function(){

        var gameTitle = this.game.add.sprite(160,160,"gametitle");

        gameTitle.anchor.setTo(0.5,0.5);

        var playButton = this.game.add.button(160,320,"play",this.playTheGame,this);

        playButton.anchor.setTo(0.5,0.5);

    },

    playTheGame: function(){

        this.game.state.start("TheGame");

    }

}

 

Đây là menu chính công việc ở đây là ta add ảnh tên game và nút Play vào màn hình. Giờ hãy đến với phần chính sau khi click Play state TheGame sẽ được kích hoạt và đây là phần game play

 


var theGame = function(game){
    spriteNumber = null;
    number = 0;
    workingButtons = true;
    higher = true;
    score = 0;
}

theGame.prototype = {
      create: function(){
      score = 0;
        number = Math.floor(Math.random()*10);
        spriteNumber = this.game.add.sprite(160,240,"numbers");
        spriteNumber.anchor.setTo(0.5,0.5);
        spriteNumber.frame = number;    
        var higherButton = this.game.add.button(160,100,"higher",this.clickedHigher,this);
        higherButton.anchor.setTo(0.5,0.5);
        var lowerButton = this.game.add.button(160,380,"lower",this.clickedLower,this);
        lowerButton.anchor.setTo(0.5,0.5);    
    },

    clickedHigher: function(){
        higher=true;
        this.tweenNumber(true);
    },

    clickedLower: function(){
        higher=false;
        this.tweenNumber(false);
    },

    tweenNumber: function(higher){
        if(workingButtons){
            workingButtons=false;
            var exitTween = this.game.add.tween(spriteNumber);
              exitTween.to({x:420},500);
             exitTween.onComplete.add(this.exitNumber,this);
              exitTween.start();
         }

    },
    exitNumber: function(){
        spriteNumber.x = -180;
         spriteNumber.frame = Math.floor(Math.random()*10);
         var enterTween = this.game.add.tween(spriteNumber);
         enterTween.to({x:160},500);
         enterTween.onComplete.add(this.enterNumber,this);
         enterTween.start();
    
    },

    enterNumber: function(){
        workingButtons=true;
        if((higher && spriteNumber.frame<number)||(!higher && spriteNumber.frame>number)){
            this.game.state.start("GameOver",true,false,score);    
        }

        else{  
            score++;
            number = spriteNumber.frame;
        }    
    }
}

 

Việc giải thích code hoạt động như thế nào có vẻ là quá dông dài và không cần thiết tôi chỉ nêu mục đích chính của từng function

 

Create  : tạo 2 button cao ,thấp và số khởi đầu

clickedHigher: sự kiện khi click Higher

clickedLower : sự kiện khi click Lower

tweenNumber : Khóa nút sau khi đã click chọn và cho số cũ trượt ra

exitNumber : gọi kiểm tra kết quả nếu chính xác thì cho số mới vào

enterNumber : kiểm tra kết quả sai thì gọi gameover đúng thì cộng điểm

 

Có lẽ đến đây thì chỉ còn lại state game over và tôi lưu ý về cách gọi có phần hơi khác bình thường


this.game.state.start("GameOver",true,false,score);

 

tham số đầu là tên state , tham số thứ 2 clearWorld   default là true  , tham số thứ 3 là clearCache default là false chúng ta thường không dùng nó vì nó sẽ xóa hết asset. Tất cả tham số kể từ thứ 4 là biến của ta. Tôi sẽ truyền vào score vì cần thể hiện điểm người chơi đạt được. Hãy xem gameover.js


gameOver.prototype = {

    init: function(score){

        alert("You scored: "+score)

    },

      create: function(){

          var gameOverTitle = this.game.add.sprite(160,160,"gameover");

        gameOverTitle.anchor.setTo(0.5,0.5);

        var playButton = this.game.add.button(160,320,"play",this.playTheGame,this);

        playButton.anchor.setTo(0.5,0.5);

    },

    playTheGame: function(){

        this.game.state.start("TheGame");
     }
    }

bạn có thấy




init: function(score){

    alert("You scored: "+score)

}

 

Đó là nơi tôi xuất điểm ra đơn giản nhất và function gọi lại game khi bấm play

 

[DOWNLOAD SOURCECODE]

Hi vọng bài viết giúp bạn hiểu phần nào về framework game HTML5 và có thêm lựa chọn cho những ý tưởng của mình nếu có khả năng tôi sẽ viết nhiều hơn về Phaser hoặc tut làm ứng dụng khác


Leave a Comment

Fields with * are required.