About me
• 近澤良(chikathreesix) @ DeNA
• フロントエンドエンジニア
• JavaScript, Flash, HTML/CSS,
  Objective-C等

• 蒙古タンメン中本
Arctic.jsとは
スマートフォンブラウザ向け
 ゲームフレームワーク
Arctic.jsとは

• スマートフォンの
• ブラウザで動く
• ゲームを開発する為の
• フレームワーク
活用例
available on
  GitHub
 with MIT License
About Arctic.js


• HTML5のCanvas要素を利用
• 環境差異を吸収
• AS3との互換性
なぜCanvasか
HTML5
• DOM
 • style.left、style.topをいじる方法
• CSS3
 • CSSでアニメーションを記述
• Canvas
 • Canvasに描画しまくる
DOM


• 再描画のコストが高すぎる
• スマホではパフォーマンス出ない
CSS3


• 簡単でハイパフォーマンス
• アニメーションの経過点とれない
Canvas


• 自由度高い
• APIがローレベル
• CSS3よりはパフォーマンス悪い
Canvasを利用


• スマートフォン向けにハイパフォーマン
 スかつ複雑なものを実装するには
 Canvasを用いるのが良い
環境差異の吸収
環境における差異


• OSによる差異
• デバイスの性能による差異
OSによる差異
•   iPhone
OSによる差異
•   Android2.1
Android2.1

• Canvasに重大なバグあり
• 座標やサイズがscreen.width/320倍され
 る

• 変換マトリックス系がおかしい
デバイスの性能による差異


• setIntervalは信用できない
• デバイスによって実行速度が全く異な
 る
フレームベース

• setInterval/setTimeout内でプロパ
 ティを目標値に向かって足していく

• 環境によってアニメーションの速度が
 変わってしまう
タイムベース
• setInterval / setTimeout内で経過時
 間を取得して、適切な値を設定する

• 描画が間引かれる
• 体感的な速度はどの環境でも保たれる
• Arctic.jsではこちらを採用
Design
OOP

• 全ての機能はオブジェクトを生成して
 使う

• クラスベースの開発スタイル
Class作成
var Person = arc.Class.create({
  _name:null,
 
  initialize: function(name) {
    this.setName(name);
  },
 
  setName: function(name){
    this._name = name;
  },
 
  getName: function() {
    return this._name;
  }
});
Class継承
var Friend = arc.Class.create(Person, {
  _nickname:null,
 
  initialize:function(name) {
    this.setName(name);
  },
 
  setName: function($super, name, nickname){
    $super(name);
    this._nickname = nickname;
  },
 
  getNickName:function(){
    return this._nickname;
  }
});
Getting started
HTMLを用意
<html>
<head>
<meta http-equiv="content-type" content="text/html;
charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-
scale=1, maximum-scale=1, user-scalable=no;"/>
<title>Game</title>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript" src="js/arctic.js"></script>
<script type="text/javascript" src="js/game.js"></script>
</body>
</html>
ゲームクラス作成

var GameMain = arc.Class.create(arc.Game, {
  //Gameパラメーターをセットする処理等の初期化処理
  initialize:function(params){
    console.log(params.hp); 
  },
  //ランループから毎フレーム実行される
  update:function(){
 
  }
});
ゲームクラス利用
window.addEventListener('DOMContentLoaded', function(e){
  var system = new arc.System(320, 416, 'canvas');
  system.setGameClass(GameMain, {hp:100, mp:100});
 
  system.addEventListener(arc.Event.PROGRESS, function(e){
      console.log(e.loaded + ", " + e.total);
  });
 
  system.addEventListener(arc.Event.COMPLETE, function(){
      console.log('loaded');
  });

  system.load(['a.png', 'b.png']);
}, false);
Features
Event
EventDispatcher
• ほぼ全てのクラスがこれを継承してい
 る

• addEventListenerを用いて非同期処理
• dispatchEventを用いてカスタムイベント
 発火
EventDispatcher
•   例


    var disp = new arc.display.DisplayObject();
    disp.addEventListener('HOGE', function(e){
        console.log('hogehoge');
    });
    disp.dispatchEvent('HOGE');
    disp.removeEventListener('HOGE');
    disp.dispatchEvent('HOGE');
Display Object
arc.display
•   DisplayObject

•   Sprite

•   Shape

•   SheetMovieClip

•   DisplayObjectContainer

•   MovieClip

•   JSONMovieClip

•   TextField
DisplayObject

• 全ての表示要素がこれを継承している
• setX, setScaleY, getAlpha等のgetter/setter
  メソッドを保持
Sprite

• 画像を一つ格納することができる
• DisplayObjectのサブクラス
• arc.display.Imageオブジェクトを取得して
 利用
Sprite
•   例


var obj = new arc.display.Sprite(system.getImage('sample.png'));

obj.setAlign(arc.display.Align.CENTER);
obj.setX(100);
obj.setY(100);
obj.setAlpha(0.5);
Shape
•   自由に描画ができる


•   塗りを行うbeginFill, endFill,


•   線の描画を行うbeginStroke, endStroke


•   線をつなぐlineTo, moveTo


•   図形の描画を行う drawCircle, drawRect
Shape
•   例


var shape = new arc.display.Shape();
shape.beginStroke(10, 0x00ffff);
shape.beginFill(0xff0000);
shape.drawCircle(200,200, 100);
shape.endFill();
shape.endStroke();
Shape


• DEMO
SheetMovieClip
•   コマが連続した画像をアニメーションさせる




var mc = new arc.display.SheetMovieClip(
   this._system.getImage('sample.png'), 174, 12);
this.addChild(mc);
mc.play(true);
SheetMovieClip


• DEMO
DisplayObjectContainer
•   DisplayObjectの子供を持つことができる表示オブ
    ジェクト


•   addChild, removeChild, contains, setMask


var container = new arc.display.DisplayObjectContaner();
var obj = new arc.display.Sprite(system.getImage('sample.png'));

container.addChild(obj);
MovieClip
•   DisplayObjectContainerを継承


•   FlashのMovieClipを再現


var mc = new arc.display.MovieClip(12, true);
mc.addChild(ball0, {
" 1 : {x:0, y:0, transition:arc.anim.Transition.SINE_OUT},
" 5 : {x:250, y:100}
});
mc.addChild(ball1, {
" 1 : {scaleX:0.5, scaleY:0.5, transition:arc.anim.Transition.SINE_OUT},
" 10 : {scaleX:3, scaleY:3}
});
MovieClip


• DEMO
JSONMovieClip

• MovieClipを継承
• 定義されたJSONに従ってアニメーショ
 ンを行う
JSONMovieClip
    •   JSON
{
"   "fps":24,
"   "frame":40,
"   "main":3,
"   "lib":[
"   "     {"id":1, "type":"data", "data":"sample.png", "pos":[0,0,34,34]},
"   "     {"id":2, "type":"mc", "loop":"true", "timelines":[
"   "     "     {"target":1, "align":"CENTER", "keyframes":{
"   "     "     "    "1" : {"x":17, "y":17, "transition":"SINE_IN"},
"   "     "     "    "10": {"y":117, "transition":"SINE_OUT"},
"   "     "     "    "19": {"y":17}
"   "     "     }}
"   "     ]},
"   "     {"id":3, "type":"mc", "loop":"true", "timelines":[
"   "     "     {"target":2, "align":"LEFT", "keyframes":{
"   "     "     "    "1" : {"x":-34, "transition":"LINEAR"},
"   "     "     "    "40": {"x":320}
"   "     "     }}
"   "     ]}
"   ]
}
JSONMovieClip
•   JS


var ajax = new arc.Ajax();
var self = this;
ajax.addEventListener(arc.Event.COMPLETE, function(){
" var mc = new arc.display.JSONMovieClip(ajax.getResponseJSON());
" self.addChild(mc);
});
ajax.load('sample.json');
JSONMovieClip


• DEMO
TextField
•   テキスト表示を行う


•   Alignの設定、文字色、フォントの設定



var numTxt = new arc.display.TextField();
numTxt.setX(10);
numTxt.setY(100);
numTxt.setAlign(arc.display.Align.CENTER);
numTxt.setFont("Helvetica", 20, true);
numTxt.setColor(0xff0000);
Animation
arc.anim.Animation
•   Tweenerライク

var target = new arc.display.Sprite(system.getImage('ball0.png'));
var anim = new arc.anim.Animation(target,
" {x:0, y:0},
" {x:200, y:100, time:1000, transition:arc.anim.Transition.SINE_OUT},
" {x:100, y:300, time:1000, transition:arc.anim.Transition.SINE_OUT});

anim.addEventListener(arc.Event.COMPLETE, function(e){
" console.log('animation finished');
});
anim.play();
arc.anim.Animation


• DEMO
Touch Event
Touch Event
• TOUCH_START
 • タッチ開始
• TOUCH_MOVE
 • タッチが動いた
• TOUCH_END
 • タッチ終了
Touch Event
var sprite = new arc.display.Sprite(system.getImage('ball.png')),

sprite.addEventListener(arc.Event.TOUCH_START, function(event){
    console.log(‘touchStart x : ‘ + event.x + ‘ y : ‘ + event..y);
});

sprite.addEventListener(arc.Event.TOUCH_MOVE, function(event){
    console.log(‘touchMove x : ‘ + event.x + ‘ y : ‘ + event..y);
});

sprite.addEventListener(arc.Event.TOUCH_END, function(event){
    console.log(‘touchEnd x : ‘ + event.x + ‘ y : ‘ + event..y);
});
イベント伝播


• 表示の階層構造がある場合親でもタッ
 チイベントを受け取ることができる
others
Timer
 •   経過時間を取得したい時に使う


 •   Dateは重いのでメインループから時間経過を取得



var timer = new arc.Timer();
timer.start();
console.log(timer.getElapsed());
CountTimer
•   setIntervalやsetTimeoutの代わりに使う


•   ゲームの進行速度に合わせて実行


var countTimer = new arc.CountTimer(3000, 1);
countTimer.addEventListener(arc.Event.TIMER_COMPLETE, function(){
    console.log(‘count’);
});
countTimer.start();
ImageManager
•   画像の読み込みを管理する


•   複数の画像を読み込みたい時に利用


var imageManager = new arc.ImageManager();
imageManager.addEventListener(arc.Event.COMPLETE, function(){
    console.log(‘loaded images’);
});
imageManager.load([‘a.png’, ‘b.png’]);
System
•   最初にインスタンス化するシステムクラス

•   いくつか便利なメソッドを用意している




system.setFullScreen();   //フルスクリーンで表示
system.getFps();   //実測FPSを取得
Rivals
enchant.js

• DOMベース
• ゲーム制作における機能が豊富(サウ
 ンド再生、マップ等)

• Canvas版に期待
EaselJS

• Canvasベース
• APIはかなりAS3.0に似せてある
• クラスベースで開発しない
• Adobeがサポート
DEMO
Canvasの未来は明るい
ご清聴ありがとうご
  ざいました

Arctic.js