NPC API demo

by Chih-Hsuan Fan

HTML

<div class="game-zone">
  <div class="npc">
    NPC
  </div>
  <div class="npc-dialog">
    NPC 說了一些話
    <button>OK</button>
  </div>
</div>

<div class="actions">
  <button class="js-npc-trigger">OnTrigger()</button>
  <button class="js-npc-dialog">OnDialog()</button>
  <button class="js-npc-walk">OnWalk()</button>
</div>

CSS

.game-zone {
  width: 100%;
  height: 200px;
  
  position: relative;
}

.npc {
  display: none;
  
  position: absolute;
  left: 0; top: 0;
  
  font-size: 24px;
  font-weight: bold;
  
  font-family: Arial;
  
  -webkit-transition: all 250ms ease-out;
  transition: all 250ms ease-out;
}

.npc-dialog {
  display: none;
  
  box-sizing: border-box;
  
  position: absolute;
  left: 50%;
  top: 50%;
  
  width: 200px;
  height: 100px;
  
  margin-left: -100px;
  margin-top: -50px;
  
  padding: 5px;
  
  background-color: rgba(0, 0, 0, 0.8);
  color: #eee;
}

.npc-dialog button {
  position: absolute;
  right: 5px;
  bottom: 5px;
}

.actions {
  text-align: center;
}

JavaScript

var Npc = function (npcElm, dialogElm) {
  this.init(npcElm, dialogElm);
};

Npc.prototype._dialogPromise = null;

Npc.prototype.entity = null;

Npc.prototype.init = function (npcElm, dialogElm) {
  this.entity = npcElm;
  this.dialog = dialogElm;
};

Npc.prototype.OnTrigger = function () {
  this.entity.show();
};

Npc.prototype.OnDialog = function () {
  var dfd = $.Deferred();
  
  this._dialogPromise = dfd.promise();
  
  var self = this;
  this.dialog.show()
    .find('button').one('click', function () {
      self.dialog.hide();
      dfd.resolve();
    });
};

Npc.prototype.OnWalk = function () {
  if (!this._dialogPromise) {
    return;
  }
  
  var rand = function (max) {
    return Math.random() * max + 1;
  };
  
  var self = this;
  this._dialogPromise = this._dialogPromise.then(function () {
    var x = rand($(window).width() - 80),
        y = rand(150),
        dfd = $.Deferred();
    
    self.entity
    .css({
      transform: 'translate('+x+'px, '+y+'px)'
    })
    .one('transitionend webkitTransitionEnd', function () {
      dfd.resolve();
    });
    
    return dfd.promise();
  });
};


$(function () {
  // start here
  
  var npc = new Npc($('.npc'), $('.npc-dialog'));
  
  $('.js-npc-trigger').on('click', function () {
    npc.OnTrigger();
  });
  $('.js-npc-dialog').on('click', function () {
    npc.OnDialog();
  });
  $('.js-npc-walk').on('click', function () {
    npc.OnWalk();
  });
});