平成22年3月30日(火) 12時35分01秒
区分
javascript
報告者:
komagata
komagataです。
canvasでウロウロするシリーズも少しコードが汚くなって来たのでリファクタリングしました。
canvasでウロウロする4
コンストラクタの継承が出来なかったのをJavaScript: The Good Parts に載っていた関数型の継承を使って書き直しました。
また、同じく同書に載っている、任意のオブジェクトに任意のイベントを受付け、発火できる機能を追加する、とても便利なeventuality関数を使うように書き換えました。
var eventuality = function(that) {
var registry = {}
that.fire = function(event) {
var array, func, handler,
type = typeof event === 'string' ? event : event.type
if (registry.hasOwnProperty(type)) {
array = registry[type]
for (var i = 0; i < array.length; i++) {
handler = array[i]
func = handler.method
if (typeof func === 'string') {
func = this[func]
}
func.apply(this, handler.parameters || [event])
}
}
return this
}
that.on = function(type, method, parameters) {
var handler = {method: method, parameters: parameters}
if (registry,hasOwnProperty(type)) {
registry[type].push(handler)
} else {
registry[type] = [handler]
}
return this
}
return that
}
eventuality関数はonとfireの二つのメソッドを持ちます。onで任意の名前のイベントを登録し、fireで発火します。
eventuality関数を継承したオブジェクトは全て同機能を持つのでenterframeイベントを持ったspriteオブジェクトなどがとても簡単につくれるようになりました。
var sprite = function(img_src, x, y, width, height) {
var that = eventuality()
that.img = new Image
that.img.src = img_src
that.on('enterframe', function(){
that.game.context.drawImage(
that.img,
that.x,
that.y,
that.width,
that.height
)
})
return that
}
こんな感じで好き勝手なイベントが作れるのが便利です。
コード:4 at master from komagata's canvas-prowler - GitHub
>View Comments
このページの上へ戻る
平成22年3月23日(火) 10時13分33秒
区分
javascript
報告者:
komagata
komagataです。
以前のプログラムで使った、javascriptでプレゼンハムアルゴリズムを使って2点間を結ぶ直線の座標を求める関数を単体で使えるように切り出してみました。
#!/usr/bin/env js
/**
* Build line's path by Bresenham algorithm
*
* @arguments Array src - line source coordinate. (Ex: [12, 32])
* @arguments Array dest - line destination coordinate. (Ex: [41, 55])
* @return Array - builded path array. (Ex: [[12, 32], ... [41, 55]])
*/
var build_path = function(src, dest) {
var next_x = src[0],
next_y = src[1],
delta_x = dest[0] - src[0],
delta_y = dest[1] - src[1],
step_x,
step_y,
step = 0,
fraction = 0,
path = []
if (delta_x < 0) {
step_x = -1
} else {
step_x = 1
}
if (delta_y < 0) {
step_y = -1
} else {
step_y = 1
}
delta_x = Math.abs(delta_x * 2)
delta_y = Math.abs(delta_y * 2)
path[step] = [next_x, next_y]
step++
if (delta_x > delta_y) {
fraction = delta_y - delta_x / 2
while (next_x != dest[0]) {
if (fraction >= 0) {
next_y += step_y
fraction -= delta_x
}
next_x += step_x
fraction += delta_y
path[step] = [next_x, next_y]
step++
}
} else {
fraction = delta_x - delta_y / 2
while (next_y != dest[1]) {
if (fraction >= 0) {
next_x += step_x
fraction -= delta_y
}
next_y += step_y
fraction += delta_x
path[step] = [next_x, next_y]
step++
}
}
return path
}
// print path
var way = build_path([152, 152], [162, 136])
for (var i = 0; i < way.length; i++) {
print(way[i])
}
152,152
153,151
153,150
154,149
155,148
155,147
156,146
156,145
157,144
158,143
158,142
159,141
160,140
160,139
161,138
161,137
162,136
座標には配列を使っています。この辺の基本的な機能はWebGLとかでまとまって実装されればいいなと思います。
>View Comments
このページの上へ戻る
平成22年3月17日(水) 02時01分11秒
区分
OpenGL
報告者:
komagata
飲み屋での一杯目は「水」。komagataです。
canvas上の何も無いも同然なグラフィックAPI上でアプリを書いてきましたが、WebGLというOpenGL ESベースのAPIの実装が始まってるそうなのでまずはOpenGLの勉強を始めました。
デスクトップアプリケーションのGUIツールキット部分はWebとは関係無い(=canvasみたいな感じになるはずな)ので、GLUT(The OpenGL Utility Toolkit)を使って行きます。
とりあえずpngを簡単に読み込みたかったのでglpngというライブラリを使おうとしたのですが、各地でリンク切れ。前世紀にメンテが終わってるっぽい雰囲気ですが、下記(OpenBSDのリポジトリ)に有りました。
ftp://ftp.usa.openbsd.org/pub/OpenBSD/distfiles/glpng-1.45/glpng.zip
どうせWebのためにやるのでOS依存部分で苦労したくないんですが、Macでコンパイルするのに少し修正する必要がありました。
% diff glpng.c glpng.c.org
28,29c28,29
< #include <GLUT/glut.h>
< #include "GL/glpng.h"
---
> #include <GL/glpng.h>
> #include <GL/gl.h>
付属のMakefile.LINUXでmakeすれば静的ライブラリ(libglpng.a)が出来ます。(Makefile.SGIってファイルも付いてるのが古さを感じます)
pngInfoとpngBind関数が使えるようになるので簡単にpngファイルが簡単にテクスチャとして貼れました。
#include <stdio.h>
#include <GLUT/glut.h>
#include "glpng.h"
GLuint texture;
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef(0, 0, 0);
glBindTexture(GL_TEXTURE_2D, texture);
glPopMatrix();
glBegin(GL_QUADS);
glTexCoord2d(0.0, 1.0);
glVertex2d(-1, -1);
glTexCoord2d(1.0, 1.0);
glVertex2d(1, -1);
glTexCoord2d(1.0, 0.0);
glVertex2d(1, 1);
glTexCoord2d(0.0, 0.0);
glVertex2d(-1, 1);
glEnd();
glFlush();
}
void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glColor3d(1.0, 1.0, 1.0);
glEnable(GL_TEXTURE_2D);
pngInfo info;
texture = pngBind("tree.png", PNG_NOMIPMAP, PNG_ALPHA, &info, GL_CLAMP, GL_NEAREST, GL_NEAREST);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
glutInitWindowSize(100, 100);
glutInitWindowPosition(100, 100);
glutCreateWindow("hunter");
glutDisplayFunc(display);
init();
glutMainLoop();
}
Macのframeworkという仕組みがイマイチわかってないんですが、下記でコンパイルできました。
% cc -framework GLUT -framework OpenGL -o game game.c libglpng.a
ソース:10 at master from komagata's glut - GitHub
>View Comments
このページの上へ戻る
平成22年3月9日(火) 04時44分40秒
区分
canvas
報告者:
komagata
身に覚えの無い商品がAmazonから送られてくる。komagataです。
canvasでウロウロするものに衝突判定を追加してみました。
(今回はAndroidエミュレーターで機種はNexus Oneで動作させてみましたが、webkitなのでiPhone用から何の変更も無しに動いたのは楽でした。)
http://komagata.org/canvas-prowler/3/
(iPhoneやAndroidでアクセスしてみて下さい)
自分で作る前に、文系プログラマー的にはゲームプログラムはどういう実装をすればいいのかを言葉で知りたかったので実装のイメージ的なところを以前のモノと合わせて言葉で説明したいと思います。
移動方法の実装イメージ:
まず、キャラクターの描画はフレーム毎に定期的に(30fpsとかで)描画します。描画はキャラクタの現在持っている座標に単に描画するだけです。
それとは別にクリックイベントをトリガーとしてプレイヤーキャラクターとクリック地点をプレゼンハムアルゴリズムで直線を引き(実際には描画しない)、その直線の座標を配列としてプレイヤーキャラクターの移動のためのバッファ(キュー)に格納します。
キャラクターはクリックイベントには感知せず、1フレーム毎に自分の移動バッファに座標があれば一つづつ消費しながら自分の座標を変更していき、バッファに無ければ何もしません。
クリックイベント時には移動バッファが残っていても空にした上で新しい経路を設定するのでクリックした瞬間に進路を変更します。
衝突判定:
何かが有る度に、それぞれのオブジェクト(プレイヤー、背景、障害物など)を全て走査、それぞれのオブジェクトが持つプレイヤーフラグ、障害物フラグを見て処理します。(これは関係無いオブジェクトも毎回走査することになるのでとてもヘボイやり方でした。イベント毎にイベントリスナーを登録するように次は変更したいです。)
プレイヤーキャラクターの移動バッファの次の移動場所が障害物フラグを持つオブジェクトと衝突している場合に移動を中止して以降の移動バッファもクリアします。
シンプルなドット絵を対象にしているので四角形と四角形の衝突を判定するのはとても楽です。
少しハマったのは、衝突した時点で移動バッファをクリアするのではなく、衝突する一歩前で次の移動地点を見てバッファをクリアしなければならないというところです。
衝突した時点でバッファをクリアすると、見た目上は分かり辛いですが、一歩分障害物にめり込んでいるので障害物に接触した瞬間動けなくなります。
この変な動きも面白かったですが、プログラムを見直して、なるほどなあと思いました。
次回もこれに新しい要素を付け加えたいと思います。
>View Comments
このページの上へ戻る
平成22年3月3日(水) 18時31分08秒
区分
canvas
報告者:
komagata
火曜日担当なのに間に合わずに水曜日にアップしている2010生まれてこなかった方が良かった男オブザイヤー候補、komagataです。
canvasでウロウロするのをiPhoneにフィットするように修正しました。
http://komagata.org/canvas-prowler/2/
解像度がファミコンは224x256に対してiphoneは320x480なので細かいですね。
ソース:2 at master from komagata's canvas-prowler - GitHub
>View Comments
このページの上へ戻る
平成22年2月23日(火) 20時44分15秒
区分
canvas
報告者:
komagata
komagataです。
前回は矢印キーでウロウロしたのでマウスクリックでウロウロするものを作りました。
http://komagata.org/canvas-prowler/1/
直線や曲線を整数で高速に描画するプレゼンハムアルゴリズムでクリック地点までの経路を計算して近付きます。
グラフィックのプログラミングは間違えても変な動きをしたりして面白いですね!
>View Comments
このページの上へ戻る
平成22年2月16日(火) 02時08分59秒
区分
テスティング
報告者:
komagata
komagataです。
犯罪的な戦術 - p0t
上記の様な戦術を簡単に防ぐ方法を考えてみました。
リポジトリがsubversionなのでpost-commitのhookを使ってテストを実行し、失敗していたら嫌なメールを送るという方法です。
対象のリポジトリ内のhookファイルに(大抵は/var/lib/svn/#{repost}/post-commit)を以下の様にします。
#!/usr/bin/env ruby
repos, rev = ARGV[0], ARGV[1]
author = `svnlook author #{repos}`
cmd = "cd /var/www/staging/ossuary/current && rake db:migrate:reset && script/spec spec -f progress"
unless system(cmd)
`mail -s '[ossuary] #{author} made a commit-and-run in r#{rev}' error@actindi.net`
end
「komagataはリビジョン256でコミットエンドランを決めた。」
(´・ω・`)・・・。
>View Comments
このページの上へ戻る
平成22年2月9日(火) 05時16分29秒
区分
javascript
報告者:
komagata
火曜日担当のkomagataです。
Metasploitは一回お休みさせていただいてJavascriptのお話しです。
仕事は主にwebプログラミングなので身も蓋も無い言い方をすると「DBに入れたり出したり」しかしてません。
「もう文字列処理はうんざりなんだよ!」
というのは嘘ですが、たまには動きのある見栄えのするグラフィックとかアニメーションとかプログラムしてみたいと思い、HTML5で使えるようになるらしい、グラフィック機能のcanvasと双方向同期通信のWebSocketsを使ってキャラクターがウロウロするだけのプログラムを作ってみました。
WebSocketsを実装しているのは現状Google Chrome 4以降だけなので、動作してる雰囲気を伝えるために動画にしてみました。
【ニコニコ動画】CanvasとWebSocketsのデモ
最近のChromeには実装されているので下記のように簡単にサーバーに接続することができます。
ws = new WebSocket("ws://localhost:8080/")
ws.onopen = function() { console.log('open') }
ws.onclose = function() { console.log('close') }
ws.onmessage = function(evt) { ws.send('Hello!') }
CometなどよりとてもシンプルでたちまちWebSocketsが好きになりました!
Ajaxのように非同期に小さなメッセージをちょこちょこ飛ばすのではなく、1ユーザーに対して1本ガッシリしたラインを繋ぎ、双方向にドカドカ通信するイメージでしょうか。
真っ先にネットゲーム的なものでの利用方法が思い付きますが、これが標準的なブラウザで使えるようになれば、他の新しい使い方で出てきて斬新なUIが生まれれば良いなと思います。
とりあえず現状を下記のURLで動かしています。chromeやsafariのnightlyでは動くみたいです。(windows, mac, linuxどれでも動くことは確認しました。)
http://verdana.komagata.org/prowler/
ソースは下記です。
komagata's prowler at master - GitHub
>View Comments
このページの上へ戻る
平成22年2月2日(火) 02時49分59秒
区分
セキュリティ
報告者:
komagata
火曜日担当のkomagataです。
Gumblerウィルスが猛威を振るっているので流行に乗ってセキュリティネタです。
脆弱性検証(というか実際に脆弱性を突くので悪用厳禁)ツールのMetasploit3 をMacで使ってみました。
Macportsのはrb-railsやrb-rackが普通のgemとぶつかって入りません。(port editで依存性を外せば入りましたが気持ち悪いです。)
なので、svnのtrunkを持ってきました。
% svn co https://www.metasploit.com/svn/framework3/trunk metasploit
今回checkoutしたのはrevision8340でした。
% cd metasploit
% ./msfconsole
/Users/komagata/code/metasploit/lib/msf/core/exploit/mixins.rb:46:in `require': /Users/komagata/code/metasploit/lib/msf/core/exploit/capture.rb:358: syntax error, unexpected ')', expecting kEND (SyntaxError)
/Users/komagata/code/metasploit/lib/msf/core/exploit/capture.rb:375: syntax error, unexpected $end, expecting kEND
from /Users/komagata/code/metasploit/lib/msf/core/exploit/mixins.rb:46
from /Users/komagata/code/metasploit/lib/msf/core/exploit.rb:216:in `require'
from /Users/komagata/code/metasploit/lib/msf/core/exploit.rb:216
from /Users/komagata/code/metasploit/lib/msf/core.rb:52:in `require'
from /Users/komagata/code/metasploit/lib/msf/core.rb:52
from /Users/komagata/code/metasploit/lib/msf/ui/console/driver.rb:1:in `require'
from /Users/komagata/code/metasploit/lib/msf/ui/console/driver.rb:1
from /Users/komagata/code/metasploit/lib/msf/ui/console.rb:10:in `require'
from /Users/komagata/code/metasploit/lib/msf/ui/console.rb:10
from /Users/komagata/code/metasploit/lib/msf/ui.rb:10:in `require'
from /Users/komagata/code/metasploit/lib/msf/ui.rb:10
from ./msfconsole:16:in `require'
from ./msfconsole:16
ところがcoreで読み込んでるファイルがsyntax error。ほぼ全てのコマンドが動きません。
「これは良いコミットエンドラン ・・・(ゴクリ)」
% svn diff
Index: lib/msf/core/exploit/capture.rb
===================================================================
--- lib/msf/core/exploit/capture.rb (revision 8340)
+++ lib/msf/core/exploit/capture.rb (working copy)
@@ -355,7 +355,7 @@
rescue RuntimeError => e
@pcaprub_error = e
print_status("Cannot stat device: #{@pcaprub_error}")
- raise RuntimeError, "Pcaprub error: #{@pcaprub_error}")
+ raise RuntimeError, "Pcaprub error: #{@pcaprub_error}"
end
return my_net
end
取り敢えずこれで動きますのでお急ぎの方は是非。
% ./msfconsole
| | _) |
__ `__ \ _ \ __| _` | __| __ \ | _ \ | __|
| | | __/ | ( |\__ \ | | | ( | | |
_| _| _|\___|\__|\__,_|____/ .__/ _|\___/ _|\__|
_|
=[ metasploit v3.3.4-dev [core:3.3 api:1.0]
+ -- --=[ 176 exploits - 30 auxiliary
+ -- --=[ 104 payloads - 17 encoders - 5 nops
=[ svn r8340 updated today (2010.02.01)
msf >
metasploitはversion3からperlからrubyになったらしく、僕にとっては読みやすくて嬉しいです。でもWebインターフェースがRailsなのは少しアグレッシヴですね。
次回は実際に脆弱性を突いてみようと思います。
>View Comments
このページの上へ戻る
平成22年1月27日(水) 11時11分38秒
区分
lisp
報告者:
komagata
興味のある言語にLispと書いておいたら面接で爆笑された
面接官「Lisp・・・ふははっ!Lisp!」
面接官「Lispやってるんですか?wwwww」
俺「(唖然)は、はい・・まだS式を理解したぐらいですが。。」
面接官「Lisp・・・ニヤニヤ」
Hunchentootで動いてるこのブログを見て弊社に面接に来た方がCommon Lispに興味なかったらメンバー全員がっかりしますね・・・。
>View Comments
このページの上へ戻る