ちょっといい感じに動くようになった。サーバは Haskell の WebSocket のライブラリからそのままぱくりました。クライアントは EaselJS です。
https://github.com/torus/olive-steel

seen from United States
seen from United States

seen from United States

seen from Malaysia

seen from Germany

seen from Germany

seen from Malaysia
seen from United States
seen from Finland

seen from Türkiye

seen from Türkiye

seen from United States
seen from Malaysia
seen from United States
seen from Russia

seen from Romania

seen from Russia

seen from China
seen from United States
seen from T1
ちょっといい感じに動くようになった。サーバは Haskell の WebSocket のライブラリからそのままぱくりました。クライアントは EaselJS です。
https://github.com/torus/olive-steel
インタラクティブコンテンツ制作講習会【基礎編】を行いました
EaselJSで単純なインタラクティブコンテンツを作ってみよう
ゼノブレイドクロスが発売されて睡眠時間が削られてる福岡です。社内ハッカソン「F-thon」の一環として、インタラクティブコンテンツ制作講習会を行いました(前回、デザインの回の様子はこちら)。あまりプログラムに慣れていない人もいたのでまずインタラクティブとはなんぞやの説明から、身近なインタラクティブなものの説明、そしてWeb技術でインタラクティブなものを制作するためのライブラリをざっと説明したあと、CreateJS(EaselJS)で実際に簡単なコンテンツを作ってもらいました。Processingのような選択肢もありますが、Web制作の人間としてはブラウザで動いた方が嬉しいだろうということでEaselJSを選択しました。
講習に用いたファイルはGithubで公開しています。
消しては書き、消しては書き
講習にあたり簡単なEaselJSの書き方テンプレートを用意しました。
var _canvas; var _stage; function init() { _canvas = document.getElementById("testCanvas"); // Stage生成 _stage = new createjs.Stage(_canvas); // Stage上でのマウスイベントを設定 _stage.enableMouseOver(); _stage.addEventListener("stagemousedown", handleMouseDown); _stage.addEventListener("stagemouseup", handleMouseUp); _stage.addEventListener("stagemousemove", handleMouseMove); createjs.Ticker.timingMode = createjs.Ticker.RAF; createjs.Ticker.addEventListener("tick", tick); } // この関数を繰り返し実行 function tick(event) { //これを実行しないと描画内容が更新されないゾ!😩 _stage.update(); } function handleMouseDown(event) { } function handleMouseUp(event) { } function handleMouseMove(event) { }
すべての土台となるStageの作成、そして各種マウスイベントとTickerを使ったループ処理が書かれています。
では最初に、EaselJSを使って丸を書きます(sample0.html)。ホワイトボードに書いた絵をあとから右に10cm動かすことはできないように、コンピューターの描画も基本的には「消しては書き」です。graphics.clear()で描画内容を消去、丸を描く、を繰り返しています。
var _circlePoint = new createjs.Point(100, 100); var _circleSize = 20; // この関数を繰り返し実行 function tick(event) { _shape.graphics.clear(); // beginFill(色) : 何色で塗りつぶす? _shape.graphics.beginFill("#000000"); // drawCircle(x, y, 直径) : 円を描画 _shape.graphics.drawCircle(_circlePoint.x, _circlePoint.y, _circleSize); //これを実行しないと描画内容が更新されないゾ!😩 _stage.update(); }
系のルールを作る
このままでは “インタラクティブ” とは口が裂けても言えないので、マウスに追従させてみましょう(sample1.html)。丸の現在座標とマウスの座標の差(の何割か)を足し続ける「アキレスと亀方式」です。これでマウスに遅れて丸が付いて行きます。0.1のところをいろいろいじってみても楽しいですね。ゴム紐が付いたような動きにするにはどうすればいいか、とか。
_circlePoint.x = _circlePoint.x + (_mousePoint.x - _circlePoint.x)*0.1; _circlePoint.y = _circlePoint.y + (_mousePoint.y - _circlePoint.y)*0.1;
ではこの系に重力を導入しましょう。丸は重力に引かれてcanvasの底辺まで落ちていき、バウンドします。丸はこれでボールになりました。ついでに左右の辺でもボールがバウンドするようにします。sample2.htmlではマウスでボールが投げられるようにしています。
//バウンドY if(_circlePoint.y >= _stage.canvas.height - _circleSize){ _circleV.y = - _circleV.y * 0.8; //ぴくぴく対策 if(Math.abs(_circleV.y)<3){ _circleV.y = 0; } _circlePoint.y = _stage.canvas.height - _circleSize; }else{ _circleV.y = (_circleV.y+_circleA.y)*0.97; } _circlePoint.y += _circleV.y;
最後はボールを100個に増やしてみます(sample3.html)。たくさんのものを同時に動かすことに長けているのがコンピューター、そしてプログラミングです。マウスダウンでボールが集まって、マウスアップで爆発!単純ながら楽しいです。これだけ複雑に見える系もプログラミングにしてしまうと案外単純なものです。
時間的な制約もあったので基本的には写経スタイルでしたが、自分で書いたものが動く、そしてそのルールを自分で作る面白さ感じてもらえたら嬉しいと思いました。あくまで概念のレベルなので次回はもう少し実践的な手法を解説したいですね。何はともあれ受講した皆さまお疲れ様でした!
A few strange portraits I made at today's PDX Creative Coders meetup: Hack day with uncontext. For the uninitiated, here's uncontext.
EaselJS ,TweenJS,SoundJS
EaselJS
A Javascript library that makes working with the HTML5 Canvas element easy.
EaselJS provides straight forward solutions for working with rich graphics and interactivity with HTML5 Canvas. It provides an API that is familiar to Flash developers, but embraces Javascript sensibilities. It consists of a full, hierarchical display list, a core interaction model, and helper classes to make…
View On WordPress
Introduction to sprites for EMDA 203. Shows you how to draw a sprite in flash and how to package it up for use with CreateJS / EaselJS. Enjoy!
Implementing Client-Side Procedural Textures aka "The Other Web On A Prim"
In the previous post, I talked pretty generally about how Opensim can solve the texture-download bottleneck by treating some textures as "recipes". This post is about digging into the technical bits. To the more tech savvy in the audience, what I'm suggesting is client(viewer)-side procedural textures. Much in the same way that SL/Opensim uses prims to efficiently build basic 3d models, procedural textures would only download the steps needed to make the texture rather than download the full texture itself. Like prims, it would mean faster downloads on the viewer side (meaning less time staring at half-textured objects), and lower costs for grid providers (less data to serve/store). So, how do we go about building this magical system? For a while I was grinding my teeth over the possibility that such a system would require building a procedural renderer from scratch, hardly the kind of thing anyone wants to really think about. Worse, the renderer would need to be portable to any platform, be capable of parsing metadata "recipe" files into textures, *and* have recipe files capable of being easily editable in a user interface. What a mess. Then it occurred to me, this problem has already been solved. Solved elegantly even. For free. EaselJS + Berkelium + JSON = (Almost) Instant Procedural Texture Generator EaselJS is a Javascript library custom made for drawing graphics to a HTML5 Canvas element. Berkelium is a C++ library custom made for rendering web pages onto a texture. JSON is a lightweight data format which works natively with Javascript and is great for describing complex structures like you'd find in a procedural texture recipe. All that's required (on the viewer side anyways) is a subsystem which takes the JSON files from the server, feeds that file into a HTML file consisting of a Canvas element and the EaselJS library, renders that file to a texture using Berkelium, and then applies that texture just like any other to the faces of the destination prim(s). On the server side is a system which listens for requests for the procedural texture recipe and serves them to the requesting viewer. Viewers which don't have the system for rendering textures procedurally will still request the raw texture download. The server would serve a pre-rendered version of the texture to them (most likely generated at the time of upload by the uploading viewer). The advantage of this system are that it still allows those without procedural renderers to view the content, making the improvement transparent to viewers which don't want or can't implement the renderer. This would still be a substantial amount of work on both the server and client side. However, compared with writing it from scratch, this solution would be refreshingly straightforward.
HTML5/Javascript Game Frameworks
I have once again taken up my dream of creating a game. I had an idea for a game about a year ago and it still seems like something that would be fun to try. My idea is a card game, so its 2D and not terribly complicated (I hope). I originally tried to use Unity3D but ran into too many roadblocks and gave up. However, this time around I've decided to stick to my guns and use what I know, web technologies. Fortunately, there are several viable HTML5/Javascript game frameworks available. I've decided to dive in and give a couple of them a spin to see what suits me and my project best.
CraftyJS
CraftyJS is a nice little library that uses the Entity-Component System wrapped up in a jQuery-like syntax. The Entity-Component System will feel very familiar to anyone who has done development in Unity3D as it is essentially the GameObject model. Basically, you create Entities and assign properties to them such as Draggable, Text, or Twoway/Fourway (keyboard movement).
Of the libraries I reviewed Crafty felt the most intuitive and easy to use. An excellent quick start guide is available as well as a number of demo games that can used to help understand how it works. Once I'd started with Crafty I really wish I'd been able to stick with it. Unfortunately, it is currently pretty unstable and I kept running into bugs. The blocker came in the form of major issues in the Draggable component (even after the v0.4.3 update which fixed the most grievous issues in Draggable). I tried posting to the Google Group but did not receive a response. However, I will definitely keeping an eye on this one, it seems to have a lot of potential.
LimeJS
LimeJS is a full-blown framework that is built on top of Google's Closure library. I admit I'd never even heard of the Closure library before I started using LimeJS. It offers lots of built-in utility classes that cover many common tasks. Especially useful to game programming are loads of useful geometry calculations when using Closure types.
It took me a little bit to get started with LimeJS, but once I got rolling things have been pretty smooth. I guess I'd say that LimeJS is event-driven, more like traditional Javascript stuff. You create your Sprites and such and add listeners to them. Thanks to Closure it has pretty strong sub-classing support, so you can easily extend the Sprite class to add game specific functionality.
I am admittedly a little lost as to how I'm supposed to organize my code. Currently, I have been sticking everything in the start() function which feels horribly wrong. There are demo projects which I need to study or perhaps I'll pick up Closure: The Definitive Guide to help me wrap my head around the Closure concepts.
Other libraries
These other libraries looked promising but I mostly passed over them because they either hadn't been updated recently or the documentation/example were lacking.
EaselJS: last updated nearly 5 months ago. I should probably look into this one more, it seems likely to be a solid choice.
Cocos2D Javascript: v0.1 initial release 4+ months ago. Cocos2D has an excellent reputation as a 2D game engine for iPhone. In fact I had looked into during my previous venture into game programming. However, Cocos2D Javascript seems to still be in its infancy. We'll see how it grows up.
GameQuery: I use jQuery regularly, but the way its applied here just doesn't seem to fit. It didn't really offer amazing support for common things you'd want in a 2D game. Overall, I think other options seemed more robust.
Conclusion
For me, LimeJS offered the best balance of stability, features, and ease of use. It has a bit of a learning curve though, hopefully more documentation, examples, quick start guides, and demo games will be created to help new developers ease into it. I'm developing my first game using it and I think it will serve me well.