27
An example of game developing with Ember.js and WebGL Yuki Shimada 2014/09/22

Ember.js Tokyo event 2014/09/22 (English)

Embed Size (px)

DESCRIPTION

This is the slide shown at Ember.js Tokyo event. http://emberjs.doorkeeper.jp/events/14856 (Japanese Version: http://www.slideshare.net/yukishimada1/emberjs-event-tokyo-ja-20140922 )

Citation preview

Page 1: Ember.js Tokyo event 2014/09/22 (English)

An example of game developing with Ember.js and WebGL

Yuki Shimada2014/09/22

Page 2: Ember.js Tokyo event 2014/09/22 (English)

About me• I majored in Computer Graphics at Toho

University, Chiba prefecture.• I have developed a Game Engine for PS3 at a

venture company established in the University of Tokyo.

• Then, I have transfered to Sopia Inc. (now Accenture Inc.), as a system engineer.

• I have also worked to develop a renderer and WebGL Web sites at a VFX studio.

• Currently, I’m a freelancer (Web & CG).

Page 3: Ember.js Tokyo event 2014/09/22 (English)

Demonstration

• Game Playerhttp://youtu.be/0iRTk_2Wjp8

• Map Editorhttp://youtu.be/u6F3wGJpnUo

Page 4: Ember.js Tokyo event 2014/09/22 (English)

My Game Web Service• The web service that makes easily able to develop RPG and share it on the

web.

• The RPG developers is divided into basic developers and advanced developers.

• The advanced developers can develop RPG from the stage of game system.– You can write game code using TypeScript. – (I hope to support visual programming via node connecting in the future). – You can customize UI design using SCSS.

• The basic developers can cherry-pick one from game systems developed by advanced developers, then within the framework of the game system, they can easily create RPG with mouse operation only.

Page 5: Ember.js Tokyo event 2014/09/22 (English)

The structure of this web service• This web service consists of two parts; game player

and production tools.• These are constructed on Ruby on Rails.

– View and controller of Rails are rarely used.– Ember.js controls all of the system, and Rails provide only model data.– To describe the view, I used Emblem.

http://emblemjs.com– To transfer model data from Rails to Ember, I used Ember Data and

ActiveModel::Serializers.– This sample made by @ursm was very helpful in usage of Ember Data

and ActiveModel::Serializers.http://ursm.jp/blog/2013/12/03/ember-js-and-rails/

Page 6: Ember.js Tokyo event 2014/09/22 (English)

Languages

• This system was wrote in CoffeeScript for production tools, and TypeScript for game player.

• Ember.js is manipulated from Both CoffeeScript(production tools) and TypeScript(game player) .

• The definition of Router is wrote in CoffeeScript.

Page 7: Ember.js Tokyo event 2014/09/22 (English)

Using of Ember.js

• UI handling• Data transfer of Rails Model -> Ember Data• Data transfer of Ember Data -> WebGL• Ember.js Observer and WebGL• Computation of Game character’s parameters

Page 8: Ember.js Tokyo event 2014/09/22 (English)

UI Handling

Page 9: Ember.js Tokyo event 2014/09/22 (English)

UI Handling• UI consists of HTML(Emblem) and CSS(SCSS).– Creators can customize the look & feel of UI using SCSS.

• The UI is controlled by Two-stage structure model; ‘uiScreen’ and ‘uiTable’.

• The Screens(‘uiScreen’s) correspond to the Template of Ember.

• Screen switching is performed by switching templates via Ember,js.

• Switching between display and non-display of the tables(‘uiTable’s) under the screen is performed by jQuery.

Page 10: Ember.js Tokyo event 2014/09/22 (English)

uiScreen and uiTableテーブル(’ uiTable’ )

スクリーン(’ uiScreen’ )

Page 11: Ember.js Tokyo event 2014/09/22 (English)

Data transferfrom Rails Model to Ember Data

Page 12: Ember.js Tokyo event 2014/09/22 (English)

Between Rails and Ember Data

trait :as_2 do id 2 ui_screen_id 1 screenIdentifier 'battle' tableIdentifier 'character_0' tableName ' 0 :' tableName_binding 'Tool.EScenarioCharacter.0.name' selectable false trs "[" + "{"+ "'columns':[" + "{" + "'item':'HP:'," + "'binding': 'Tool.EScenarioCharacter.0.hp'" + "}" + "]" + "}," + "{"+ "'columns':[" + "{" + "'item':'MP:'," + "'binding': 'Tool.EScenarioCharacter.0.mp'" + "}" + "]" + "}" + "]" end

var uiTableDefinition = { screenIdentifier: DS.attr('string'), tableIdentifier: DS.attr('string'), tableName: DS.attr('string’), tableName_binding: DS.attr('string'), selectable: DS.attr('boolean'), trs: DS.attr('uiTableTrs'), …};

Definition of Ember Data Model A fixture of Rails Model (Factory Girl)

window.Tool.UiTableTrsTransform = DS.Transform.extend( { deserialize: function(value:any) { var json:any = null; eval("json = " + value); return Ember.create(json); } });

Transform of Ember Data Model

The data that are complex and frequently modified are hold in the column in the Rails model as JSON text. Using the Transform feature of Ember Data, transforming it to real JSON by eval in JavaScript, finally we obtain Ember objects.

Page 13: Ember.js Tokyo event 2014/09/22 (English)

Question : How can we get one–to-many relationships of Ember Data Models from Rails Models?

• There exists a partially different part in data expression of ‘one to many’ in Rails and Ember Data.• In Rails, if the child model has reference to the parent model, you can get the list of child models

from the parent model.• In Ember Data, the parent model must expressly have the id array of the child models.• From the above difference, conversion process is needed.

App.Post = DS.Model.extend({ comments: DS.hasMany('comment', {async: true})});

{ "post": { "comments": [1, 2, 3] }}

App.Comment = DS.Model.extend({ post: DS.belongsTo('post')});

{ "comment": { "post": 1 }}

create_table ”posts", force: true do |t|end

create_table ”comments", force: true do |t| t.integer "ui_screen_id”end

class Post < ActiveRecord::Base has_many :commentsend

class Comment < ActiveRecord::Base belongs_to :postend

Page 14: Ember.js Tokyo event 2014/09/22 (English)

Question : How can we get one–to-many relationships of Ember Data Models from Rails Models?

var uiTableDefinition = { screenIdentifier: DS.attr('string'), tableIdentifier: DS.attr('string'), tableName: DS.attr('string’), tableName_binding: DS.attr('string'), selectable: DS.attr('boolean'), trs: DS.attr('uiTableTrs'), …};

var uiScreenDefinition = { identifier: DS.attr('string'), config: DS.attr('uiScreenConfig'), uiTables: DS.hasMany('ui-table') };

Definition of ‘uiScreen’ which has many uiTables

Definition of ‘uiTable’ which belongs to ‘uiScreen’

create_table "ui_screens", force: true do |t| t.string "identifier" t.text "config" t.text "uiTables”end

create_table "ui_tables", force: true do |t| t.integer "ui_screen_id" t.string "screenIdentifier" t.string "tableIdentifier" t.string "tableName" t.string "tableName_binding" t.boolean "selectable" t.text "trs”end

class UiScreen < ActiveRecord::Base has_many :ui_tablesend

class UiTable < ActiveRecord::Base belongs_to :ui_screenend

Ember Data Rails Model

Page 15: Ember.js Tokyo event 2014/09/22 (English)

Answer: To generate has-many id array toward Ember Data using Rails’ controller.

class Api::UiScreensController < ApplicationController skip_before_action :verify_authenticity_token

def index uiScreens = [] UiScreen.all.each do |uiScreen|

uiTablesStr = "[" uiScreen.ui_tables.each do |uiTable| uiTablesStr += uiTable.id.to_s + ",“ end

uiTablesStr.chop! uiTablesStr += "]"

uiScreen.update_attribute(:uiTables, uiTablesStr) uiScreens.push(uiScreen) end

jsonHash = JSON.parse(uiScreens.to_json) for item in jsonHash item["uiTables"] = eval(item["uiTables"]) end jsonWrapper = {} jsonWrapper["ui_screens"] = jsonStr = jsonWrapper.to_json jsonHash = JSON.parse(jsonStr) render :json => jsonHashend

Add the all ids of uiTables that belong to the uiScreen to array character string.

Ex:”[1, 2, 5, 6, 7]”

Then, after transforming it to JSON, output it. { "ui_screens": [ { "config": "{'firstUI':'command','hiddenUIs':['physics', 'magic', 'target', 'magic-fake'],'calculatePosition': true}", "created_at": "2014-09-08T02:07:53.215Z", "id": 1, "identifier": "battle", "uiTables": [1, 2, 5, 6, 7] } ]}

Page 16: Ember.js Tokyo event 2014/09/22 (English)

Data transfer ofEmber Data to WebGL

Page 17: Ember.js Tokyo event 2014/09/22 (English)

Data transfer to WebGL

• Not using WebGL directly, I use it via Three.js.http://threejs.org

• I also use tmlib (a cool JS game library by @phi-jp).http://phi-jp.github.io/tmlib.js/

• The tmlib library is integrated with three.js.• Today, I will illustrate my method by taking

the rendering of a game map as an example.

Page 18: Ember.js Tokyo event 2014/09/22 (English)

Data transmission of Map Data for Map Rendering

Tool.PlayRoute = Ember.Route.extend model: (params, transition) -> return Ember.RSVP.hash({ map: @store.find('squareGrid3dMap', params['id']) textures: @.store.find('squareGrid3dMapTexture') tiletypes: @.store.find('squareGrid3dMapTileType') uiScreens: @.store.find('uiScreen') uiTables: @.store.find('uiTable') })

trait :as_2 do id 2 name ' デバッグテスト ' width 5 height 5 type_array "1 N,1 W,1 N,1 W,1 W\n" + "1 N,1 W,1 N,1 W,1 W\n" + "1 N,1 N,1 N,1 N,1 N\n" + "1 W,1 W,1 N,1 W,1 W\n" + "1 W,1 W,1 N,1 W,1 W\n"

height_array "0 1,0 1,0 1,0 1,0 1\n" + "0 1,0 1,0 1,0 1,0 1\n" + "0 1,0 1,0 1,0 1,0 1\n" + "0 1,0 1,0 1,0 1,0 1\n" + "0 1,0 1,0 1,0 1,0 1\n" end

RailsMap Data (Factory Girl)

Tool.SquareGrid3dMap = DS.Model.extend name: attr('string') width: attr('number') height: attr('number') type_array: attr('string') height_array: attr('string')

Ember Data

Page 19: Ember.js Tokyo event 2014/09/22 (English)

Data transmission of Map Data for Map Rendering

Tool.PlayIndexRoute = Ember.Route.extend model: -> @modelFor('play')

afterModel: (model, transition)->

window.WrtGS.main(model)

function systemMain(err:any, args:any){

window.WrtGS = new system.System(args);

}

module system { export class System {

public main(model:any) { this.map = new map.Map(model.map.get(‘type_array’), model.map.get(‘height_array’), model.texture.get(‘gametex_url’));

trait :as_2 do id 2 name ' デバッグテスト ' width 5 height 5 type_array "1 N,1 W,1 N,1 W,1 W\n" + "1 N,1 W,1 N,1 W,1 W\n" + "1 N,1 N,1 N,1 N,1 N\n" + "1 W,1 W,1 N,1 W,1 W\n" + "1 W,1 W,1 N,1 W,1 W\n"

height_array "0 1,0 1,0 1,0 1,0 1\n" + "0 1,0 1,0 1,0 1,0 1\n" + "0 1,0 1,0 1,0 1,0 1\n" + "0 1,0 1,0 1,0 1,0 1\n" + "0 1,0 1,0 1,0 1,0 1\n" end

trait :as_1 do id 1 name ' メタル ' gametex_url ‘metal.jpg’

Page 20: Ember.js Tokyo event 2014/09/22 (English)

Since the data is mere text data, the subsequent processes is just to analyze the original text format of map,

create the geometry of Three.js, and assign texture images to Meshes.

// 1 頂点目 geom.vertices.push( new THREE.Vector3(x-1, this.maxCeilingHeight, y) );

// 2 頂点目 geom.vertices.push( new THREE.Vector3(x-1, ceilingHeight, y) );

// 3 頂点目 geom.vertices.push( new THREE.Vector3(x-1, ceilingHeight, y-1) );

// 4 頂点目 geom.vertices.push( new THREE.Vector3(x-1, this.maxCeilingHeight, y-1) );

// 表三角形の1個目 var face1 = new THREE.Face3( verticesStride+0, verticesStride+1, verticesStride+2 ); face1.normal = new THREE.Vector3(1, 0, 0); geom.faces.push( face1 );

geom.faceVertexUvs[ 0 ].push( [ new THREE.Vector2( 0.75, 0 ), new THREE.Vector2( 0.75, this.texcoordOne * (this.maxCeilingHeight - ceilingHeight) ), new THREE.Vector2( 1, this.texcoordOne * (this.maxCeilingHeight - ceilingHeight) ) ] );

Page 21: Ember.js Tokyo event 2014/09/22 (English)

In the data transmission from Ember.js to WebGL (Three.js),I don’t do anything special.

I just extract strings from the data fulfilled in Ember model, analyze them, and transfer them to the function for geometry construction of Three.js.

Transmission of Map Data for Map Rendering

Page 22: Ember.js Tokyo event 2014/09/22 (English)

Ember.js Observer and WebGL

• When an enemy is damaged, the enemy figure is vibrated. For this process, I used the Observer of Ember.js.

• Since the status value of a friend and foe is supervised as an Ember object, when their HPs decrease, the coordinate values of foe polygon of three.js are vibrated by activating the Observer.

Page 23: Ember.js Tokyo event 2014/09/22 (English)

Computation of parameters of Game

character’s

In RPG, there exists many cases where a parameter is calculated from the other parameters.→By applying computed Properties, I solved the problem.

In the present production tools, we can freely create all kind of parameters of characters, and also can describe a mathematical relationship between the character’s parameters freely.

Page 24: Ember.js Tokyo event 2014/09/22 (English)

Affinity between Ember.js and web games

• Optimal for display and update of UI – Since the first version was processed using jQuery only, the development was

a hellish battle. Now, due to Ember.js the process becomes quite simple.– The Ember.js is suitable for RPG with large number of UI. Why not use that

power?

• Two-way binding is useful– In a large scale game, data synchronization between multiple points in app is

required. Ember.js take care whole synchronous processing.

• Observer is also useful– In a game UI, the usage of not only text but also picture often happens. In that

case, we should use the data binding for the recalculation of inner data only, so that we can focus on using another rendering library for animation in observer of Ember.

• The Computed Properties play an active role In a game, such as RPG, that requires a lot of computation between parameters.

Page 25: Ember.js Tokyo event 2014/09/22 (English)

Ember.js is Terrific!

• Finally, what I want to claim is,• Ember.js supports the basis of both the portions of

game and production tools in the present Web service.

• If Ember.js was not available, I could not obtain effective software development and excellent prospect of code.

Thanks! Ember.js!

Page 26: Ember.js Tokyo event 2014/09/22 (English)

Finally• For the person who want to learn Ember.js– I have posted the Japanese translation of the Ember.js

official guide on my github page.https://github.com/emadurandal/emberjs-guides-japanese-translation

– “Series introduction to Ember.js” at Developers.IO is also must-see. (Thank you Watanabe-san for your very fine article!)http://dev.classmethod.jp/series/getting-started%E2%80%8E-emberjs/

Page 27: Ember.js Tokyo event 2014/09/22 (English)

Thank you for your attention !