そらいろさんぽ

個人で開発したアプリやウェブサイトの情報をまとめたブログです

第2回新うさゴヤ公開テストについて

第2回新うさゴヤ公開テストについて

こんばんは。そらのくろうさぎです。
先週の土曜日に第2回新うさゴヤ公開テストを実施いたしました。今日はその時の様子をまとめたいと思います。

負荷テストの様子

f:id:soranokurousagi:20151109184338p:plain
うさぎさんたちに負荷テストまで待機してもらって…  

f:id:soranokurousagi:20151109184353p:plain
よーいどん!みんなで一斉に歩いてもらいました。前回行ったよりも負荷によるカクつきがなくなり、アバターがはまって動けなくなることもなくなりました。

f:id:soranokurousagi:20151109184410p:plain
f:id:soranokurousagi:20151109184431p:plain
負荷テスト前に実装した庭機能もテストして頂きました。公開テストでは目の前にいるうさぎさんの庭にしか遊びにいけませんが、リリース時にはフレンドリストから遊びにいけるようになります。

f:id:soranokurousagi:20151109184445p:plain
f:id:soranokurousagi:20151109184456p:plain
巨大化機能を使った負荷テストの様子です。画面いっぱいにアバターが表示されて可愛いですね〜。巨大化機能はクライアント側の負荷が高くなるため、アバター数が少ないクエスト機能の一部として実装する予定です。

テスト結果について

第2回目の公開テストは今までの負荷テストの中で1番結果が良く、今回のソースでリリースしようかなと思っています。ただ、まだ負荷を改善出来る余地があるため、もう少しソースを手直してから第3回目の公開テストで負荷テストを終わらせたいです。

次回実装予定の機能

f:id:soranokurousagi:20151109184708p:plain
2年前の告知バナーがちょっと不吉ですが…新うさゴヤでやっと正式なフレンド機能を実装します。私の力不足で大変長い間お待たせしてしまい申し訳ございませんでした。今年の8月にやっと技術的な問題を解決し、当時予定していた機能を全て実装出来るようになりました。新うさゴヤリリースまでもう少しお待たせしてしまいますが、どうぞ楽しみにお待ち下さい!

フレンド機能とは

新うさゴヤのコンテンツは全てリアルタイムで操作出来るようになっています。フレンド機能もリアルタイムを活かしたコンテンツになっていて、例えば…

  1. オンライン中のフレンドを確認出来る
    フレンドリストからオンライン状況を確認出来て、フレンドがいるエリアにワープすることが可能。

  2. フレンドチャット機能
    フレンドが他のエリアにいてもフレンド同士でチャットが出来る。

  3. ノック機能
    家のドアをノックすることが出来る。ノックすると相手に通知が届く。

といったリアルタイムならではの機能を楽しむことが出来ます。次回の公開テストで実際にフレンド機能をご利用頂けますので、是非ともフレンド申請して遊んでみてくださいね〜!

第2回新うさゴヤ公開テストにご参加頂いた皆さま、ありがとうございました!第3回目は11月下旬〜12月上旬を予定しています。
次回もどうぞよろしくお願いします。

Red5を使ったチャットサーバー構築

Red5を使ったチャットサーバー構築

こんばんは。そらのくろうさぎです。
去年の始め頃からスマホでもリアルタイムのオンラインゲームが流行り始めましたね〜。node.jsやpeer.jsなどのリアルタイム用のライブラリも充実し、双方向通信がより身近な技術になったように感じます。今日はそんなリアルタイム通信を行うためのチャットサーバー構築手順についてお話したいと思います。

Red5とは

双方向通信といえば一番最初にnode.jsを思い浮かべると思いますが、今回は新うさゴヤに導入しているRed5の構築手順をご紹介します。

Red5はAdobeFlashMediaServerの互換として開発されたオープンソースのメディアサーバーです。元々はFlash用のメディアサーバーでしたが、最近のバージョンではHLSやWebSocketが使えるようになり、HTML5やモバイルアプリケーションにも対応出来るようになりました。サーバーアプリケーションの開発言語はJavaですので、柔軟性の高いチャットサーバーを運用・構築することが可能です。

ダウンロード

Red5はGitHabからダウンロードします。
Red5 Server

インストール手順

Quartzインストール

$ su -
# yum install quartz

JDKインストール

# yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel

ApacheAntインストール

# cd /usr/local/src/
# wget http://www.apache.org/dist/ant/binaries/apache-ant-1.9.5-bin.tar.gz
# tar xfz apache-ant-1.9.5-bin.tar.gz
# mv apache-ant-1.9.5 /usr/local/ant

ApacheAntのパスを通す

# vi ~/.bash_profile

下記の内容を.bash_profileに追記する

export ANT_HOME=/usr/local/ant
export PATH=${PATH}:${ANT_HOME}/bin

パスを反映する

# source ~/.bash_profile

Red5インストール

# cd /usr/local/src/
# wget https://github.com/Red5/red5-server/releases/download/v1.0.6-RELEASE/red5-server-1.0.6-RELEASE-server.zip
# unzip v1.0.6-RELEASE/red5-server-1.0.6-RELEASE-server.zip
# mv v1.0.6-RELEASE/red5-server-1.0.6-RELEASE-server.zip /usr/local/red5
# chown -R root:root /usr/local/red5/

Red5起動スクリプト作成

# vi /etc/init.d/red5

下記の内容を記述する
起動スクリプト

JAVA_HOMEにJavaのパス、RED5_HOMEにRed5のパスを追記する

#! /bin/sh

# For RedHat and cousins:
# chkconfig: 2345 85 85
# description: Red5 flash streaming server
# processname: red5

# Source function library
. /etc/rc.d/init.d/functions

export JAVA_HOME=/usr/bin/java
if [ -z "$JAVA_HOME" ]; then
    echo -n "need to set JAVA_HOME in red5.init" && failure
    echo
    exit 1
fi

PROG=red5
if [ -z "$RED5_HOME" ]; then
    export RED5_HOME=/usr/local/red5
fi
DAEMON=$RED5_HOME/$PROG.sh
PIDFILE=/var/run/$PROG.pid

[ -r /etc/sysconfig/red5 ] && . /etc/sysconfig/red5

RETVAL=0

case "$1" in
    start)
        echo -n $"Starting $PROG: "
        $DAEMON >/dev/null 2>/dev/null &
        RETVAL=$?
        if [ $RETVAL -eq 0 ]; then
            echo $! > $PIDFILE
            touch /var/lock/subsys/$PROG
        fi
        [ $RETVAL -eq 0 ] && success $"$PROG startup" || failure $"$PROG startup"
        echo
        ;;
    stop)
        echo -n $"Shutting down $PROG: "
        killproc -p $PIDFILE
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$PROG
        ;;
    restart)
        $0 stop
        $0 start
        ;;
    status)
        status $PROG -p $PIDFILE
        RETVAL=$?
        ;;
    *)
        echo $"Usage: $0 {start|stop|restart|status}"
        RETVAL=1
esac

exit $RETVAL

起動スクリプトのパーミションを変更する

# chmod 0755 /etc/init.d/red5

ログ用のディレクトリを作成する

# mkdir /usr/local/red5/log/
# chmod 0755 /usr/local/red5/log/

ログローテーションの設定

# vi /usr/local/red5/conf/logback.xml

logback.xmlのノードを変更する
※maxHistoryで保存ログ数を指定

<appender class="ch.qos.logback.core.FileAppender" name="FILE">
  <File>log/red5.log</File>
  <Append>false</Append>
  <encoder>
    <pattern>%d{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern>
  </encoder>
</appender>

↓下記に変更

<appender class="ch.qos.logback.core.rolling.RollingFileAppender" name="FILE">
  <File>log/red5.log</File>
  <Append>false</Append>
  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>red5.%d{yyyy-MM-dd}.log</fileNamePattern>
    <maxHistory>30</maxHistory>
  </rollingPolicy>
  <encoder>
    <pattern>%d{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern>
  </encoder>
</appender>

WebSocketの設定

# vi /usr/local/red5/conf/red5.xml

red5.xmlに下記のノードを追記する

<!-- websocket -->
<bean id="webSocketTransport" class="org.red5.net.websocket.WebSocketTransport">
  <property name="port" value="8081"/>
</bean>

Red5を起動する

# /etc/init.d/red5 start

Red5のログ確認

# tail -f /usr/local/red5/log/red5.log

動作確認

設置したサーバーのURLにポート番号5080を指定してブラウザからRed5デモページを開きます。ドメインがxxxx.comならxxxx.com:5080でアクセスします。

f:id:soranokurousagi:20151017203528p:plain
Red5が問題なくインストールされていれば、上の図のようなデモページが表示されます。

おわりに

現在のRed5はコンパイルを行わなくてもサーバーに設置するだけで動作するようになりました。設置に手間がかからず、容易にチャットサーバーを構築することが可能です。これからリアルタイムコンテンツを開発しようと考えている方はRed5も選択肢の1つとして検討してみてはいかがでしょうか。

次回はRed5のサーバーアプリケーション開発についてお話したいと思います。
ではでは!

湯の児温泉「山海館」

湯の児温泉「山海館」

今年の8月に行った九州旅行で見つけた廃屋です。水俣資料館に立ち寄った帰りにこのホテルの洞窟温泉でゆっくりする予定だったのですが、訪問した時には既に廃屋化していました…。今年の4月に破産したそうです。
(破産に関するニュース)

訪問日

2015年08月12日

場所

熊本県水俣市「湯の児温泉」
新水俣駅から水俣市内の温泉街に行く場合はタクシーチケットを使うとお得です。移動距離に関係なくタクシー料金が1000円になります。タクシーチケットは新水俣駅や旅館などでもらえます。
湯の児・湯の鶴1000円タクシー

写真

f:id:soranokurousagi:20151008124147p:plain
瓦屋根の和風な建物がいいですね。普通に撮ってもモノクロ写真のような重みのある絵になりました。

f:id:soranokurousagi:20151008124319p:plain
両隣には新館らしき建物がありました。

f:id:soranokurousagi:20151008124359p:plain
破産からたった4ヶ月でこんなになっちゃうんですね〜。もう立派な廃屋です。

第1回新うさゴヤ公開テストについて

第1回新うさゴヤ公開テストについて

f:id:soranokurousagi:20150928211823p:plain

こんばんは、そらのくろうさぎです。
9月上旬からスタートした新うさゴヤの開発が順調に進み、先週の土曜日に第1回目の新チャットサーバー公開テストを行うことができました。ご参加頂いた皆さま、大変ありがとうございます。今回の公開テストの目的は多人数で同時にアバターが動かせるかどうかということと、通信状況のモニタリングの2点でした。人数は少なかったものの、非常に安定してアバターが動いてくれて嬉しかったです。

次回のテストについて

第2回目のテストは10月下旬〜11月中旬頃を予定しています。次回はいよいよ探索(クエスト)のテストです。フィールドとボス戦がワンセットになったコンテンツ1点をテストプレイ出来るようになると思いますので、是非とも楽しみにしてくださいね。テストプレイ参加希望の方はうさゴヤのメッセージに「第2回新うさゴヤ公開テスト参加希望」と書いてご連絡頂きますようお願いします。

ではでは〜。

うさゴヤ大改修計画

うさゴヤ大改修計画

f:id:soranokurousagi:20150902205613p:plain

こんばんは、くろうさぎです。
今日は私がライフワークとして運営しているうさゴヤの改修計画についてお話したいと思います。

うさゴヤは2011年12月にリリースしてもう少しで4周年目を迎えます。2013年頃から仕事のシステム開発や調査等を優先していたため、うさゴヤ開発にリソースが回せず、現在はほぼ休止状態になっています。今年はそんなうさゴヤにテコ入れしようと内部システムの大幅改修作業を計画しています。

改修のきっかけ

うさゴヤのチャット機能には自作のチャットサーバーを組み込んでいます。このチャットサーバーが非常に曲者で、想定を超える大量のコネクションが発生するとプログラムが通信処理をさばききれず、TCP/IPにTIME_WAITが増加してしまうという問題を抱えていました。この問題が原因でマイルームやオンラインゲームの開発が行き詰まってしまい、チャットサーバーの改修を検討せざるを得ない状況になってしまいました。

一言に改修といっても今までのチャットサーバーとは全く別の仕組みを導入することになりますから、クライアント(Flash)側も新チャットサーバーに合わせて改修作業を行わなければなりません。今年の1月末に先行してお絵描きとチャット部分を新チャットサーバーに入れ替えましたが、突貫工事を続けてきた現行のシステムはメンテナンス性が非常に悪く、今回の改修作業を機にクライアントのプログラムも1から作り直すことにしました。

チャットサーバーの切り替え

新チャットサーバーは無料であることとサーバーアプリケーションがJavaで開発出来るという理由からred5を選びました。red5は本来、動画や音声などを配信するためのメディアサーバーという位置付けですが、ActionScript3のNetConnection.call()を使うことでチャットサーバーとしても運用することが出来ます。red5を導入することにより、大量のコネクションを効率良く安定的に処理することが可能となり、マイルームやオンラインゲームの運用にも十分に耐えられるようになります。

クライアントの最適化

現行のうさゴヤは下記の通信処理を行ってリアルタイムでアバターを動かしています。

f:id:soranokurousagi:20150902205657p:plain
アバターが移動を開始する前に移動座標をチャットサーバーに送信することにより、チャットサーバーへのアクセスを最小限に抑え、TCP/IPのTIME_WAIT増加によるチャットサーバーダウンを防いでいました。自分のアバターを操作した場合であってもサーバーからのレスポンスを待ってからアバターを歩かせていたため、ネットの通信速度が遅い環境ではアバター操作が快適に行えなくなることがありました。

f:id:soranokurousagi:20150902205714p:plain
新クライアントはチャットサーバーのレスポンスを待たずアバターを動かします。チャットサーバーのレスポンスを待つ必要がなくなり、アバターの操作感が今までとは比べ物にならないほど良くなります。アバター移動中の座標をチャットサーバーに送り続けることにより、各クライアントとのより厳密的な同期処理も行えるようになりました。

お絵描き機能

ソラシルの開発ソースをうさゴヤに組み込みます。以前のお絵描きよりも描きやすくなります。

せっかくなので…

サイトデザインもチャットルームを中心としたデザインにしたいと思っています。今のデザインはサイトの内容が伝わりづらいですので…

おわりに

現行のシステムから流用出来るソースがいくつか存在しますが、基本的には1から作り直すことを前提として改修作業を進めています。出来れば4周年記念に合わせてリリースしたいですね〜。(作業量的にちょっと厳しそうですが…)
もう少し時間がかかってしまいますが、気長にお待ち頂けると嬉しいです。今後ともうさゴヤをよろしくお願いします。

tmhOAuthを使ったTwitter認証について

[PHP]tmhOAuthを使ったTwitter認証について

f:id:soranokurousagi:20150824220700p:plain
こんばんは。そらのくろうさぎです。
公式のTwitter開発者用サイトで紹介されている「tmhOAuth」の使い方を備忘録としてまとめます。

tmhOAuthについて

GitHub:https://github.com/themattharris/tmhOAuth

アプリ登録

Twitter Application Management:https://apps.twitter.com

Twitterアプリ管理サイトでアプリを登録し、Consumer KeyとConsumer Secretをコピーします。

ソース

<?php
include_once 'library/tmhOAuth/tmhOAuth.php';

session_start();
$callback = 'http://xxxxxxxx.com/twitter_oauth.php';
$consumers = array(
    'consumer_key' => 'Consumer Key',
    'consumer_secret' => 'Consumer Secret',
);

if (!empty($_SESSION['access_token'])) {
    $tmhOAuth = new tmhOAuth(array(
        'user_token' => $_SESSION['access_token']['oauth_token'],
        'user_secret' => $_SESSION['access_token']['oauth_token_secret'],
    ) + $consumers);
    $code = $tmhOAuth->request('GET', $tmhOAuth->url('1.1/statuses/user_timeline', 'json'));
    if ($code == 200) {
        $responses = json_decode($tmhOAuth->response['response'], true);
        print_r($responses);
        exit;
    }
} else if (!empty($_SESSION['request_token'])) {
    $tmhOAuth = new tmhOAuth(array(
        'user_token' => $_SESSION['request_token']['oauth_token'],
        'user_secret' => $_SESSION['request_token']['oauth_token_secret'],
    ) + $consumers);
    $tmhOAuth->config['user_token'] = $_SESSION['request_token']['oauth_token'];
    $tmhOAuth->config['user_secret'] = $_SESSION['request_token']['oauth_token_secret'];
    unset($_SESSION['request_token']);

    $code = $tmhOAuth->request('POST', $tmhOAuth->url('oauth/access_token', false), array(
        'oauth_verifier' => $_GET['oauth_verifier']
    ));
    if ($code == 200) {
        $_SESSION['access_token'] = $tmhOAuth->extract_params($tmhOAuth->response["response"]);
        header('Location: '.$callback);
        exit ;
    }
} else {
    $tmhOAuth = new tmhOAuth($consumers);
    $code = $tmhOAuth->request('POST', $tmhOAuth->url('oauth/request_token', false), array(
        'oauth_callback' => $callback
    ));
    if ($code == 200) {
        $requests = $tmhOAuth->extract_params($tmhOAuth->response["response"]);
        $_SESSION['request_token'] = $requests;
        $authUrl = $tmhOAuth->url("oauth/authorize", false)."?oauth_token=".$requests['oauth_token'];
        header('Location: '.$authUrl);
        exit ;
    }
}
die('Twitterの認証に失敗しました');
?>

解説

認証のためのセッションを開始します

session_start();

Twitter認証後のコールバックURLを記述します。Twitterのアプリ認証が終わるとこちらのURLにリダイレクトされます。

$callback = 'http://xxxxxxxx.com/twitter_oauth.php';

$consumers変数にアプリ登録でコピーしたConsumer KeyとConsumer Secretをコピーします。

$consumers = array(
    'consumer_key' => 'Consumer Key',
    'consumer_secret' => 'Consumer Secret',
);

Twitter認証後に取得したアクセストークンをtmhOAuthに設定します。tmhOAuth::request()からはHTTPステータスコードが返されます。

$tmhOAuth = new tmhOAuth(array(
    'user_token' => $_SESSION['access_token']['oauth_token'],
    'user_secret' => $_SESSION['access_token']['oauth_token_secret'],
) + $consumers);
$code = $tmhOAuth->request('GET', $tmhOAuth->url('1.1/statuses/user_timeline', 'json'));

Twitter認証前に取得したリクエストトークンをtmhOAuthに設定します。

$tmhOAuth = new tmhOAuth(array(
    'user_token' => $_SESSION['request_token']['oauth_token'],
    'user_secret' => $_SESSION['request_token']['oauth_token_secret'],
) + $consumers);
$tmhOAuth->config['user_token'] = $_SESSION['request_token']['oauth_token'];
$tmhOAuth->config['user_secret'] = $_SESSION['request_token']['oauth_token_secret'];

アクセストークンをセッションに保存します。

$_SESSION['access_token'] = $tmhOAuth->extract_params($tmhOAuth->response["response"]);

リクエストトークンを取得します。tmhOAuth::request()からはHTTPステータスコードが返されます。

$tmhOAuth = new tmhOAuth($consumers);
$code = $tmhOAuth->request('POST', $tmhOAuth->url('oauth/request_token', false), array(
    'oauth_callback' => $callback
));

セッションにリクエストトークンを保存します。

$requests = $tmhOAuth->extract_params($tmhOAuth->response["response"]);
$_SESSION['request_token'] = $requests;

Twitter認証用のURLを生成します。

$authUrl = $tmhOAuth->url("oauth/authorize", false)."?oauth_token=".$requests['oauth_token'];

以上、tmhOAuthを使ったTwitter認証でした。ではでは〜。

CorelPainterLiteでお絵描き

CorelPainterLiteでお絵描き

こんにちは。そらのくろうさぎです。
先日、新しい作業用MacBookにもお絵描き環境を作ろうと思い、久しぶりにCorelPainterXのインストールディスクを起動しました。ところが、CorelPainterXのインストーラーがYosemiteに対応しておらず、インストールの途中でエラーが出てしまいました。Lion時代にインストールしたCorelPainterXはYosemiteにバージョンアップした後でも問題なく動くんですけどね…。仕方がなくAppStoreで代替のアプリを探していたら、CorelPainterLiteというアプリをみつけました。

CorelPainterLite

f:id:soranokurousagi:20150804172724p:plain
AppStoreで販売出来ます。価格は8,400円。
今すぐPainterが欲しかったので何の迷いもなく購入しました。

早速起動

f:id:soranokurousagi:20150804172745p:plain
見た目は通常版のCorelPainterにそっくりです。Lite版にも関わらず、ブラシも一通り揃っていて驚きました。

いつものうさぎを描いてみました

f:id:soranokurousagi:20150804172804p:plain
f:id:soranokurousagi:20150804172807p:plain
安いのにとても描きやすいです。レイヤー管理やPSDの書き出しも問題なく行えました。絵を描くだけならCorelPainterLiteでも十分かもしれませんね。これからはこのアプリをどんどん活用していきたいと思います。

画面共有で自宅のMacを操作する

画面共有で自宅のMacを操作する

こんにちは。そらのくろうさぎです。
皆さんは外出先で自宅のPCにあるデータが必要になったことはありませんか。自宅で考えたサンプルスクリプトや参考資料など、今すぐ手元に欲しいデータが外出先から取り出せたらとても便利ですよね。MacOSX同士ならiCloudと画面共有で簡単にデータの送受信やリモート操作が行えます。

自宅用Macの設定

  1. 「システム環境設定」の「省エネルギー」を開きます。
    f:id:soranokurousagi:20150731162831p:plain

  2. 「ネットワークアクセスによるスリープ解除」にチェックを入れます。
    f:id:soranokurousagi:20150731162940p:plain

  3. 「システム環境設定」の「iCloud」を開きます。
    f:id:soranokurousagi:20150731162844p:plain

  4. 「どこでも My Mac」にチェックを入れます。
    f:id:soranokurousagi:20150731162958p:plain

  5. 「システム環境設定」の「共有」を開きます。
    f:id:soranokurousagi:20150731162921p:plain

  6. 「画面共有」にチェックを入れ、「アクセスを許可」を選択します。
    デフォルトはAdministerです。
    +ボタンを押すとユーザーを追加することが出来ます。 f:id:soranokurousagi:20150731163013p:plain

作業用Macで画面共有を行う

  1. 「Finder」から共有しているMacを選択し、「画面を共有」ボタンを押します。
    サイドバーの共有に共有しているMac名が表示されます。
    f:id:soranokurousagi:20150731163024p:plain

  2. 自宅用Macのユーザー名とパスワードを入力します。
    f:id:soranokurousagi:20150731163038p:plain

  3. 自宅用Macの画面が共有されました。
    「クリップボード」の「共有クリップボードを使用」にチェックを入れるとドラッグアンドドロップでファイルを送受信出来ます。
    f:id:soranokurousagi:20150731163053p:plain

最後に

このようにMacOSXの画面共有を使うと自宅用Macをリモートで操作することが可能になります。作業用Macにフォントがない場合にフォントがある自宅用Macでテキストのアウトラインデータを作成して転送するという使い方も出来ます。画面共有は仕事でも使えそうな便利な機能ですが、セキュリティ的に少々問題がありますので、重要な情報や第三者のデータを含まない個人的な用途として使った方が良いかもしれません。

過去のお絵描きライブイラスト

過去のお絵描きライブイラスト

こんにちは。そらのくろうさぎです。
MacBookのデータを整理していたら4年前に描いたお絵描きライブのイラストが出てきました。懐かしいです〜。当時はUStreamを使ってお絵描きをライブ配信していました。一部のフォロワーさんは見たことがあるイラストかもしれませんね。

f:id:soranokurousagi:20150730211959p:plain
f:id:soranokurousagi:20150730212025p:plain
f:id:soranokurousagi:20150730212014p:plain

また時間に余裕が出来たらお絵描きライブをやってみたいです。今度はもちろんソラシルで!

アバターアニメーション(スプライトシート)

アバターアニメーション(スプライトシート)

こんにちは。そらのくろうさぎです。

前回の連番PNGアニメーションに続き、今回はスプライトシートを使ったアバターアニメーションを作成しました。

スプライトシートを使うことでアニメーションのコマを1枚の画像にまとめられるため、keyframesで背景画像の表示領域を更新するだけでアニメーションのコマ画像を切り替えられます。 前回の力技とは違い、今回はCSS3の仕様に沿ったコードでアバターアニメーションになりますので、現行のぼほすべてのブラウザで動作を確認することが出来ます。

動作ブラウザ

Safari(快適)
Chrome(快適)
InternetExplorer10以降(快適)
Firefox(快適) AndroidChrome(等倍は快適)
Android標準ブラウザ(等倍は快適)
※PC・モバイルどちらもほぼ快適に動作します。

スプライトシート

f:id:soranokurousagi:20150722172859p:plain
上のスプライトシートを使います。

アニメーションの設定

animationプロパティを設定します。
前回の連番PNGと同じ設定を使用します。

-webkit-animation: AvatarAnimation 1.5s step-start infinite 0s normal;  
-webkit-animation-play-state: running;

/* Firefoxのベンダープレフィックスを追加 */
-moz-animation: AvatarAnimation 1.5s step-start infinite 0s normal;
-moz-animation-play-state: running;

/* CSS3のプロパティを追加 */
animation: AvatarAnimation 1.5s step-start infinite 0s normal;
animation-play-state: running;

キーフレームの設定

アニメーションのキーフレームを設定します。
background-positionでコマごとの表示領域を設定します。

@-webkit-keyframes AvatarAnimation {
    0% { background-position: 0px 0px; }
    3% { background-position: -200px 0px; }
    6% { background-position: -400px 0px; }
    ・
    ・
    ・
    100% { background-position: 0px 0px; }
}

/* Firefoxのベンダープレフィックスを追加 */
@-moz-keyframes AvatarAnimation {
    0% { background-position: 0px 0px; }
    3% { background-position: -200px 0px; }
    6% { background-position: -400px 0px; }
    ・
    ・
    ・
    100% { background-position: 0px 0px; }
}

/* CSS3のプロパティを追加 */
@keyframes AvatarAnimation {
    0% { background-position: 0px 0px; }
    3% { background-position: -200px 0px; }
    6% { background-position: -400px 0px; }
    ・
    ・
    ・
    100% { background-position: 0px 0px; }
}

HTMLタグの定義

連番PNGと同じタグを使用します。

<div id="Avatar">
    <p>
        AvatarView
    </p>
</div>    

動作確認

まとめ

スプライトシートはとても汎用性が高く、webブラウザだけではなくアプリケーションにもアニメーションを組み込むことが出来ます。 アニメーション処理も非常に軽く、モバイルブラウザ用のアバター表示にも最適かもしれません。 ただ、Androidの場合は機種ごとに動作が異なることがありますので、実機での検証は十分に行いましょう。 Android標準ブラウザではCSSよりもJavascriptの方が処理が軽くなることが多いようです。