zoukankan      html  css  js  c++  java
  • 使用Phaser开发你的第一个H5游戏(一)

    本文来自网易云社区

    作者:王鸽


    不知你是否还记得当年风靡一时的2048这个游戏,一个简单而又不简单的游戏,总会让你在空闲时间玩上一会儿。


    在这篇文章里,我们将使用开源的H5框架——Phaser来重现这个游戏。这里你可以了解到游戏内的状态管理、Sprite元件对象等,以及如何使用Preload、Create等方法。

    H5游戏框架众多,为何选择它?

    由于近几年H5的火热,H5游戏框架如雨后春笋般出现,甚至有很多定位不是游戏开发的框架都被归到这个范畴中。那么为什么选择Phaser?以下是我选择它的原因:

    • 支持原生JS。

    • 可以方便地在Canvas和WebGL之间切换。

    • 定位明确,专注H5游戏开发。

    • 完善的文档及示例。

    • 持续更新,目前Phaser 3正在开发。



    2048游戏的最终呈现效果如下


    开发准备

    首先访问Phaser官网http://www.phaser.io,下载JavaScript版本的Phaser,并搭建好项目结构

    项目文件结构如下:

    在index.html中引入相关js文件,定义一个div作为phaser生成canvas的父容器

    <!DOCTYPE html> 
    <head> 
       <meta charset="UTF-8" />
       <title>2048</title>
        <script src="js/phaser.min.js"></script>
        <script src="js/Menu.js"></script>
        <script src="js/Game.js"></script>
        <script src="js/index.js"></script>
        <style>
          body {
            margin: 0;
            padding: 0;
          }
          canvas {
            margin: 0 auto;
          }
          .game {
            position: absolute;
             100%;
            height: 100%;
          }
        </style>
    </head>
    <body>
      <div id="game" >"game"></div>
    </body>


    游戏是如何进行的

    在html文件中我们已经引入了Phaser库,这使我们拥有了一个名为Phaser的全局对象,通过这个对象,我们可以访问Phaser库中哪些用于构建游戏的方法和函数。

    现在我们使用Phaser对象来创建一个游戏实例,这个对象用来代表整个游戏,我们会为他添加不同的状态。

    index.js,在其中创建游戏实例,注册各个游戏状态以及启动游戏。

    //实例化游戏对象,参数为宽、高、渲染方式,父容器
    window.game = new Phaser.Game(240, 400, Phaser.CANVAS, 'game');
    
    //添加状态,参数为状态应用的Key值,状态所包含的对象
    game.state.add('Menu', Menu);
    game.state.add('Game', Game);
    
    //状态切换 开始游戏
    game.state.start('Menu');

    Phaser中的“状态(state)”管理使游戏的场景切换变得非常容易,此处的“状态”可以看理解为不同的游戏界面,2048这个游戏比较简单,只需要首页和游戏内两个界面即可。

    • 主页状态,由menu.js处理,用于加载游戏资源并显示游戏开始界面,点击开始按钮后切换到游戏状态并且开始游戏。

    • 游戏状态,由game.js处理,用于显示游戏界面、控制游戏逻辑,游戏结束后显示分数面板

    接下来初始化菜单状态对象(Menu),在Menu.js中定义一个新对象Menu并为它添加函数。状态启动时,首先会调用对象内的preload函数,通常加载游戏所需资源会在这一步进行;加载完成后,调用create函数,初始化游戏界面以及逻辑对象等等。

    var Menu = {
        preload: function () {
            //加载图像,参数为创建元件时所使用的Key值,文件路径
            game.load.image('background', 'assets/bg.png');
            game.load.image('btnStart', 'assets/btn-start.png');
            game.load.image('btnRestart', 'assets/btn-restart.png');
            game.load.image('logo', 'assets/logo.png');
            game.load.image('btnTryagain', 'assets/btn-tryagain.png');
        },
        create: function () {
            //创建重复元件,可以重复图片 一般用于重复纹理的底图等
            game.add.tileSprite(0, 0, game.width, game.height, 'background');
    
            //创建图片,此处是游戏logo,参数为x,y,加载图片是所保存的Key值
            var logo = game.add.image(0, 0, 'logo');
            logo.reset((game.width - logo.width) / 2, (game.height - logo.height) / 2 - 50);
    
            //开始按钮用来启动游戏
            var startBtn =  game.add.sprite(0, 0, 'btnStart');
            startBtn.reset((game.width - startBtn.width) / 2, (game.height - startBtn.height) / 2 + 100);
            //开启元件点击监听,并添加监听事件
            startBtn.inputEnabled = true;
            startBtn.events.onInputDown.add(this.startGame);
        },
        startGame: function () {
            //转换状态至游戏界面
            game.state.start('Game');
        }
    };


    至此,启动界面已经完成了,开启本地web服务器后,在浏览器中打开index.html,就可以看到游戏的启动界面了。


    接着在Game.js开始处理游戏的界面以及逻辑

    var Game = {
        create: function () {
            //添加背景
            game.add.tileSprite(0, 0, game.width, game.height, 'background');
    
            //变量用于保存游戏分数
            this.score = 0;
            this.best = 0;
    
            //文字样式,font:字体字号等 fill:颜色
            var titleStyle = { font: "bold 12px Arial", fill: "#4DB3B3", boundsAlignH: "center" };
            var scoreStyle = { font: "bold 20px Arial", fill: "#FFFFFF", boundsAlignH: "center" };
            var scoreSprite = game.add.sprite(10, 10);
    
            //使用graphics绘制图形作为界面UI
            var scoreGraphics = game.add.graphics(0, 0);
            scoreGraphics.lineStyle(5, 0xA1C5C5);
            scoreGraphics.beginFill(0x308C8C);
            //绘制一个带圆角的矩形
            scoreGraphics.drawRoundedRect(0, 0, 70, 50, 10);
            scoreGraphics.endFill();
            //把图形添加到父容器上,便于整体调整位置等
            scoreSprite.addChild(scoreGraphics);
    
            //添加文字 参数为x,y,文字内容,文字样式
            var scoreTitle = game.add.text(0, 5, "SCORE", titleStyle);
            scoreTitle.setTextBounds(0, 0, 70, 50);
            //把文字添加到父容器上,便于整体调整位置等
            scoreSprite.addChild(scoreTitle);
    
            this.scoreText = game.add.text(0, 20, this.score, scoreStyle);
            this.scoreText.setTextBounds(0, 0, 70, 50);
            scoreSprite.addChild(this.scoreText);
    
            ......
    
            //添加键盘方向件的监听以及监听事件
            var up = this.game.input.keyboard.addKey(Phaser.Keyboard.UP);
            up.onDown.add(function () {...});
            var down = this.game.input.keyboard.addKey(Phaser.Keyboard.DOWN);
            down.onDown.add(function () {...});
            var left = this.game.input.keyboard.addKey(Phaser.Keyboard.LEFT);
            left.onDown.add(function () {...});
            var right = this.game.input.keyboard.addKey(Phaser.Keyboard.RIGHT);
            right.onDown.add(function () {...});
            
            ......
    
            //获取手势滑动的X轴差值和Y轴差值 用于计算滑动方向
            var deltaX = this.game.input.activePointer.position.x - this.game.input.activePointer.positionDown.x;
            var deltaY = this.game.input.activePointer.position.y - this.game.input.activePointer.positionDown.y;
            
            ......

    2048这个游戏的规则非常简单,开发的思路也非常明确,维护一个4*4的数组,每次触发移动事件时遍历数组,进行方向上的叠加判断,然后在数组中寻找空格,随机生成新的数字,如果没有则游戏结束。相关的一些开发思路以及算法优化在此也就不详述了,大家可以自行查阅。


    资料推荐

    虽然这个游戏非常简单,但通过这个项目,可以了解到Phaser的多个方面。如果对此感兴趣,可以再深入接触以下资料:


    网易云免费体验馆,0成本体验20+款云产品!

    更多网易研发、产品、运营经验分享请访问网易云社区


    相关文章:
    【推荐】 Android复杂列表的实现
    【推荐】 论用户体验测试:牛逼的功能千篇一律,好的体验万里挑一

  • 相关阅读:
    Service Name Port Number Transport Protocol tcp udp 端口号16bit
    linux linux 互传文件 win 不通过 ftp sftp 往linux 传文件(文件夹)
    soft deletion Google SRE 保障数据完整性的手段
    Taylor series
    Taylor's theorem
    Moving average
    REQUEST
    Unix file types
    mysqld.sock
    Tunneling protocol
  • 原文地址:https://www.cnblogs.com/163yun/p/9790495.html
Copyright © 2011-2022 走看看