chemdraw 聚合物_用聚合物制造推箱子

chemdraw 聚合物

当我第一次听说Polymer时,我想到了我过去的Silverlight时代。 Silverlight使用XHTML进行标记,并使用C#进行代码。 Polymer与此类似,但是Polymer使用HTML和Javascript。 有关聚合物的介绍,请参见这篇出色的文章 。 在本教程中,我们将利用Web组件和出色的Yeoman生成器generator-polymer ,构建经典的推箱子游戏,并使用Bower进行发布。

设置聚合物

设置Polymer项目非常简单,只需以下两个命令:

$ npm install generator-polymer -g
$ yo polymer

它将要求您包括一些标准组件。 由于我们不需要任何东西,因此您可以对所有人拒绝。

这是生成的文件夹结构。 所有自定义元素都在app/elements文件夹中。

.
|-- Gruntfile.js
|-- app
|   |-- elements
|   |   |-- elements.html
|   |   |-- soko-ban
|   |   |   |-- soko-ban.html
|   |   |   `-- soko-ban.scss
|   |-- index.html
|   |-- scripts
|   |   |-- app.js
|-- bower.json
`-- package.json

要开始发展, grunt serve 。 它将提供index.html并监视文件更改时的实时重新加载。 这是index.html ,我只包括了使用Polymer的必要部分。

<html>
  <head>
    <script src="bower_components/platform/platform.js"></script>
    <!-- build:vulcanized elements/elements.vulcanized.html -->
    <link rel="import" href="elements/elements.html">
    <!-- endbuild -->
  </head>

  <body unresolved>
    <div class="game-container">
      <!-- insert your elements here -->
      <soko-ban></soko-ban>
    </div>

    <script src="scripts/app.js"></script>
  </body>
</html>

我们包含用来启用Polymer的platform.js ,并elements.html进一步导入所有元素的elements.html。 请注意,它包装在build:vulcanized构建块中,它将所有我们导入的元素连接在一个文件中。 最后,在body添加自定义的Polymer元素。 我已经包含了我们将要构建的最后一个元素sokoban-ban ,您可以将其替换为其他子元素以在构建时对其进行测试。

自定义元素: sprite-el

我们将构建的第一个自定义元素是sprite元素,它将用作所有sprite的基础,例如盒子和播放器。 要添加自定义元素,请运行一个命令。

$ yo polymer:el sprite-el

这将创建elements/sprite-el子文件夹,并添加两个文件sprite-el.htmlsprite-el.scss 。 它还会在elements.html注入sprite-el.html ,基本上是为您做样板。

请参见由Yeoman注入到elements.htmlsprite-el.html

File: elements/elements.html

<link rel="import" href="sprite-el/sprite-el.html">

元素声明

让我们定义自定义元素sprite-el

<link rel="import" href="../../bower_components/polymer/polymer.html">
<polymer-element name="sprite-el">
  <template>
    <link rel="stylesheet" href="sprite-el.css">
    <div class="sprite" style="top: {{posY}}px; left: {{posX}}px; height: {{frame.height}}px; width: {{frame.width}}px; background: url({{spriteUrl}}) {{frame.x}}px {{frame.y}}px">
    </div>
  </template>
  <script>
    (function () {
      'use strict';

      Polymer({
       publish: {
         spriteUrl: 'images/sprites.png',
         frame: {
           x: 0,
           y: 0
         },
         position: {
           x: 0,
           y: 0
         },

         computed: {
           posX: 'position.x * 64',
           posY: 'position.y * 64'
         }
       }
     });

    })();
  </script>
</polymer-element>

首先,我们包含polymer.html ,并打开一个带有sprite-el name属性的polymer-element标签,该标签是必需的,并且必须包含- 。 接下来,我们有两个子标签, templatescripttemplate包含我们自定义元素的标记。 在script我们调用Polymer函数来启动自定义元素。 有关更多信息,请参阅文档

元素模板

在模板中,我们包括样式sprite-el.css由咕噜从编译sprite-el.scss

接下来,我们有一个带有sprite类和style属性的divstyle属性定义topleftheightwidthbackground样式,以决定精灵及其图像的位置和边界。 我们将这些样式内联包括在内,因为我们必须对这些样式属性使用数据绑定。

数据绑定,发布和计算的属性

元素上的属性可以使用Polymer表达式 (例如{{posY}}{{frame.height}}{{spriteUrl}}直接绑定到视图中。

posXposYcomputed属性下定义,指示这些是计算属性 。 它们是动态属性,基于其他属性值进行计算。 在我们的例子中,它们依赖于position.xposition.y因此,每当position属性更改时,它们也会在视图中重新计算和更新。

spriteUrlframe已发布的属性 。 这意味着您正在将该属性作为元素的“公共API”的一部分。 因此,元素的用户可以更改它们。 发布的属性也是数据绑定的,可以通过{{}}访问。

自定义元素: box-el

下一个自定义元素是box元素,它将由我们的sprite-el ,将代表盒子,墙壁和地面。 让我们再一次困扰Yeoman。

$ yo polymer:el box-el

游戏美术和精灵画面

所有游戏插图都来自1001.com ,并获得CC-BY-SA 4.0许可。 您可以在GitHub上找到所有sprites和完整的源代码。

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

我们有五个子画面框架B代表盒子, BD代表暗盒, T代表目标, W代表墙壁, G代表地面。 实际上最好在单独的图层中定义移动框和背景精灵,但是为简单起见,我们将所有元素和元素包含在其中。 每个框架都定义了精灵页面中的框架位置及其高度和宽度。

让我们定义我们的自定义元素box-el

<polymer-element name="box-el">
  <template>
    <link rel="stylesheet" href="box-el.css">
    <sprite-el frame="{{frame}}" position="{{model.position}}" style="height: {{frame.height}}px; width: {{frame.width}}px;"></sprite-el>
  </template>
  <script>
    (function () {
      'use strict';

      Polymer({
       publish: {
         model: {
           position: {
             x: 0,
             y: 0
           },
           type: 'W'
         }
       },

       computed: {
         frame: 'boxCoords[model.type]'
       },
       
       ready: function() {
         this.boxCoords = {
           "B": { x:"-192", y:"0", width:"64", height:"64" },
           "BD": { x:"-128", y:"-256", width:"64", height:"64" },
           "T": { x:"-64", y:"-384", width:"32", height:"32" },
           "W": { x:"0", y:"-320", width:"64", height:"64" },
           "G": { x:"-64", y:"-256", width:"64", height:"64" }
         };
       }
      });

    })();
  </script>
</polymer-element>

继承与构成

box和player元素将使用基本sprite元素。 有两种方法可以使用继承或组合。 我们不会扩展sprite-el ,而是使用composition。 有关继承的更多信息,请参见此博客文章和此参考

我们在模板中包含sprite-el ,并为其分配属性。 还记得发布的属性frameposition吗? 在这里,我们通过属性分配它们。

生命周期方法

ready 生命周期方法是除已发布的和已计算的属性以外的一个额外属性box-el 。 当元素ready时,将调用ready生命周期方法,我们可以在此回调中分配额外的属性,在本例中,是frame计算属性使用的boxCoords

自定义元素: sokoban-el

我们最终的自定义元素是推箱子游戏本身。 这将由我们的player-el以及盒子,墙壁和地面元素组成。

游戏模型,游戏控制器和输入管理器

所有游戏逻辑都在GameController类型内。 它生成游戏地图,并直接操纵游戏模型。 博弈模型是绑定到我们视图的数据,即聚合物元素。 因此, GameController对模型所做的所有更改GameController在视图中自动更新。 我不会在本文中详细介绍游戏逻辑,您可以查看完整的源代码以获取更多详细信息。

可以使用声明性事件映射来处理用户输入。 但是,还有一些警告。 请参阅堆栈溢出问题 。 因此,我使用了自定义类型来处理输入KeyboardInputManager

让我们定义我们的自定义元素soko-ban

<polymer-element name="soko-ban">
  <template>
    <link rel="stylesheet" href="soko-ban.css">
    <template repeat="{{box in boxes}}">
      <box-el model="{{box}}"></box-el>
    </template>
    <player-el model="{{player}}" id="character"></player-el>
  </template>
  <script>
    (function () {
      'use strict';
     
      Polymer({
       ready: function() {

         var controller = new GameController();
         var model = controller.getModel();

         /** Sample Model **/
         /**
         this.player = {
           position: {
             x: 0,
             y: 0
           }
         };

         this.boxes = [
           {
             type: 'W',
             position: {
               x: 10,
               y: 10
             }
           },
           {
             type: 'WD',
             position: {
               x: 10,
               y: 100
             }
           }
         ];
         */

         this.player = model.player;
         this.boxes = model.boxes;
         
         var inputManager = new KeyboardInputManager();
         var char = this.$.character;
         
         inputManager.on('move', function(val) {
           switch (val) {
             case KeyboardInputManager.Direction.UP:
               controller.move(GameController.Direction.UP);
               break;
             case KeyboardInputManager.Direction.RIGHT:
               controller.move(GameController.Direction.RIGHT);
               break;
             case KeyboardInputManager.Direction.DOWN:
               controller.move(GameController.Direction.DOWN);
               break;
             case KeyboardInputManager.Direction.LEFT:
               controller.move(GameController.Direction.LEFT);
               break;
           }

           if (controller.isGameOver()) {
             this.fire('finished', { target: model.target });
           }
         }.bind(this));
       }
     });
     
    })();
  </script>
</polymer-element>

注意我们的Polymer元素playerboxes上的两个属性,我们将它们设置为模型。 您可以手动将它们设置为硬编码值,如在注释的代码中看到的那样,以进行测试。

迭代模板

boxes属性是一个值数组。 我们可以为数组中的每个项目生成一个模板实例。 请注意template标记和repeat属性的用法,以遍历盒子数组。 有关更多信息,请参见文档

触发自定义事件

您还可以使用fire方法在Polymer元素内触发自定义事件。 就我们而言,当游戏finished时,我们会触发一个finished事件。 您可以如下所示监听事件。

document.querySelector('soko-ban')
        .addEventListener('finished', function(e) {
          alert('Congratz you have pushed all ' +
          e.detail.target + ' boxes!');
});

发布它

我们使用generator-polymer来构建我们的应用程序。 还有另一个生成器generator-elementPolymer样板模板,用于构建和发布自定义元素。 使用生成器构建自定义元素后,即可使用Bower发布它。 有关发布的更多信息,请在此处此处查看这些优秀文章。

不要忘记将web-component标签添加到bower.json 。 将其发布到Bower后,您的元素应该在Bower注册表中可用。 还要确保将其提交到customelements.io

了解更多和现场演示

在本教程中,我们通过构建推箱子来了解Polymer在起作用。 通常,您不必构建自己的自定义元素,可以使用现有元素,将它们组成以构建更具吸引力的元素。 访问Web组件库,网址为customelements.io

您可以使用我们尚未介绍的Polymer来做更多事情,例如样式元素,观察属性等。有关更多信息,请访问API开发者指南 。 您可以在GitHub找到该项目的完整源代码,并在我的网站上观看实时演示。

翻译自: https://www.sitepoint.com/building-sokoban-polymer/

chemdraw 聚合物

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值