cocos2dでpollingを楽しく

ときどき、どうしてもSubversionリポジトリを比較的短時間にチェックしたい時があります。月額ン万円でホスティングSubversionだけじゃないけど)してもらってるのにhooksは一切いじれないとか、いじれたとしてもこちらがNATで囲まれてて growl の通知が届かないとか。多少のタイムラグがあってもコミットの通知が出ると楽しいのに・・・そんな時はポーリングするしかありません。

とりあえず作ってしまうポーリング

とりあえず動けばいい物は time.sleep() で待ってしまえばいいと思います。でも、せっかく作ったのに、せっかくイカしたコメント付けてコミットしたのに、通知まだー、とかいう気持ちになります。今回、このポーリングしているマシンがみんなの目の届く所にあるので、次回実行までの待ち時間を無駄に分かりやすく表示してみることにしました。

さっそく完成品

とはいってもそんなに凝ったことばかりしても仕方が無いので、シンプルな物にしておきます。

こんな感じで、人が左端に歩いて到達したら1回実行です。素材は FirstSeedMaterial ( http://www.tekepon.net/fsm/ )の物を使わせてもらっています。

# -*- coding: utf-8 -*-
#
import cocos
import pyglet

from pyglet import image

import tiled2cocos

pyglet.clock.set_fps_limit(30)

class PollingLayer(cocos.layer.Layer):
    def __init__(self):
        super(PollingLayer, self).__init__()

        af1 = image.AnimationFrame(image.load('image1.png'), 0.25)
        af2 = image.AnimationFrame(image.load('image2.png'), 0.25)
        af3 = image.AnimationFrame(image.load('image3.png'), 0.25)
        am = image.Animation([af1, af2, af3, af2])

        sprite = cocos.sprite.Sprite(am)
        self.add(sprite)
        self.polling_1(sprite)

        sprite = cocos.sprite.Sprite(am)
        self.add(sprite)
        self.polling_2(sprite)

    def polling_1(self, sprite):
        sprite.position = 320 + 16, 24
        sprite.do(cocos.actions.MoveTo((-16,24), 10) + 
                  cocos.actions.CallFuncS(self.polling_1))

    def polling_2(self, sprite):
        sprite.position = 320 + 16, 24 + 48
        sprite.do(cocos.actions.MoveTo((-16,24 + 48), 6) + 
                  cocos.actions.CallFuncS(self.polling_2))

if __name__ == "__main__":        
    cocos.director.director.init(320, 48 * 2)
    polling_layer = PollingLayer()

    map = tiled2cocos.load_map("8x4.tmx")
    map.set_view(0, 0, map.px_width, map.px_height)

    main_scene = cocos.scene.Scene(map, polling_layer)
    cocos.director.director.run(main_scene)

image1.png〜image3.pngについて

上記サイトからキャラクターのpngファイルを取得し、32x48ピクセルで適切な歩きパターンを切り出して背景色を透明にしたファイルです。正直、画像の加工は gimp の説明を見よう見まねでなぞっただけなので、出来上がったのが不思議です。背景以外の物も透明になっている可能性があるくらいです。

8x4.tmxとtiled2cocosについて

ここが本題?で、サンプルの背景にある殺風景な草原のための物です。素材を公開しているサイトではとても魅力的なイメージがあるのですが、残念ながら当方には使いこなすだけのセンスがありません。

それはともかく、「タイルセット」とされている大きいpngファイルをダウンロードします。
次に使うのは Tiled Map Editor ( http://www.mapeditor.org/ ) です。ここでは新しいマップを幅8タイル、高さ4タイルで作製します。ファイル名はここから来ていますね。サイズは適当に大きければいいと思います。

続いて、「マップ」メニューから「新しいタイルセット」を選択して、先ほどの「タイルセット」のpngファイルを指定します。サイズは32x32です。

あとはノリで何とかなると思いますが、保存する前に設定で出力形式をxmlにしておきます。

ただ、保存するときの拡張子は .tmx じゃないと都合が悪いみたいです。あと、8x4としたからには、8x4のマスを全部何かで埋めて下さい。次の tiled2cocos が動きません。

最後にその tiled2cocos ですが、 https://bitbucket.org/maikg/tiled2cocos/overview にあった物です。ステキですね。

ポーリングの間隔は?

cocos.actions.MoveTo の第二引数です。この「移動する」アクションの次のアクションが「関数を呼び出す」アクションです。呼び出し先でアクションをかけ直すようになっていますが、もしかしたら最初から Repeat とか上手く使えればいいのかもしれません。

最後に

ポーリングという割にはCPUリソースを消費するので、最終的には稼働させない方がいいかもしれません orz

たぶんフレームレートが高すぎるんだと思いますが、COMMAND+xでレートを表示すると 60fps とか出ます。30にしてるつもりなのに。そんなに要らないし、最小化したり他のウインドウで覆うと途端にCPU使用率が跳ね上がり、100fps 以上を記録した形跡が見えます。vsyncか何かかなぁ・・・。