2000万通りのキャラ画像が簡単に作れる!! avatar.enchant.js を使ってサンプルとゲームを作ってみた.

phiary に引っ越しました. 毎日プログラミングやWebに関する情報を発信しています! RSS 登録してたまに覗いたり, tweet やハテブして拡散してもらえると幸いです.

Pocket

先日, 公開された avatar.enchant.js を使って早速ゲームを作ってみました.

そもそも enchant.js って何?って方はこちらをどうぞ. 使い方とかざっくりまとめてあります. 簡単に言うと JavaScript で作られたゲームエンジンです.

avatar.enchant.js で定義されている Avatar, AvatarMonster, AvatarBG クラスそれぞれの使い方とサンプル, そして, 作ったゲームのコードや解説も載っけているのでよかったら参考にしてください.

screenshot

Demo Download GitHub

About

avatar.enchant.js とは enchant.js 上で動くプラグインで, 服装や武器から髪型, 髪の色まで色々と組み合わせて使うことができるので 2000万通り以上のキャラ画像を簡単に生成してゲームに使うことができます.

しかもただの画像ではなくアニメーションとして使えるよう 分割画像として取得できるので一緒に公開された Avatar クラスを使うことで 「走り」アニメーションや「攻撃」アニメーションなんかも簡単に表現することができます.

また, avatar.enchant.js で使える画像はもともと 株式会社ユビキタスエンターテインメント(UEI)が過去に商用サービスとして公開していた「メルルーの秘宝」で使われていた画像ということですべて製品クオリティーです.

私のように絵心のないクリエイタにもってこいなプラグインですね.

avatar.encahnt.js は こちら からダウンロードできます.(今は master リポジトリの方にも avatar.enchant.js は追加されているようです)

作ったゲームは『ヨケモン』. 十字キーでモンスターを避けるシンプルなゲームです. 下もしくは9leap で遊ぶことができます.

Usage

avatar.enchant.js で追加されたクラスそれぞれの使い方です.

それぞれのサンプルは下のボタンで確認, ダウンロードできます.

Demo Download

Avatar クラスの使い方

Avatar クラスの使い方は簡単♪

  • enchant.js, avatar.enchant.js を script タグで読み込む
  • アバターコードを渡して Avatar クラスを生成.
  • rootScene に追加

たったこれだけで使えます. アバターコードはこちらのツールで作成することができます.

あとは生成した Avatar のインスタンスのプロパティ action に “run” や “attak”, “damage” といった 値をセットするとその値に応じたアニメーションが再生されます.

Sample

サンプルコードです. 実際の動作はこちらで見れます.

<!DOCTYPE html>

<html>
    <head>
        <meta charset=UTF-8 />
        <title>Avatar Sample | TM Life</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
        </style>
        <script src="lib/enchant.js/enchant.js"></script>
        <script src="lib/enchant.js/plugins/avatar.enchant.js"></script>
        <script>
            enchant();
            
            window.onload = function() {
                // var code = "2:2:1:2004:21230:22480";
                var code = document.location.search.substr(1);  // クエリでコードを指定
                
                // ゲームクラス生成
                var game = new Game();
                
                // 初期化
                game.onload = function() {
                    var scene = game.rootScene;
                    scene.backgroundColor = "#aaa";
                    
                    // Avatar
                    var avatar = new Avatar(code);  // アバター生成
                    scene.addChild(avatar);         // シーンに追加
                    avatar.action = "run";          // 走りアニメーション再生
                };
                
                game.start();
            };
        </script>
    </head>
    <body>
        
    </body>
</html>

AvatarMonster の使い方

今回の更新で, 見栄えするモンスターの画像が追加されました. その画像を簡単に使えるようにしたのが AvatarMonster クラスです.

使い方は, 使いたいモンスター画像を引数として生成し, シーンに追加するだけです.

Sample

サンプルコードです. 実際の動作はこちらで見れます.

<!DOCTYPE html>

<html>
    <head>
        <meta charset=UTF-8 />
        <title>AvatarMonster Sample | TM Life</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
        </style>
        <script src="lib/enchant.js/enchant.js"></script>
        <script src="lib/enchant.js/plugins/avatar.enchant.js"></script>
        <script>
            enchant();
            
            // リソース
            var IMAGE_PATH          = "lib/enchant.js/images/";
            var MONSTER1_IMAGE      = IMAGE_PATH + "monster/monster1.gif";
            var MONSTER2_IMAGE      = IMAGE_PATH + "monster/monster2.gif";
            var MONSTER3_IMAGE      = IMAGE_PATH + "monster/monster3.gif";
            var MONSTER4_IMAGE      = IMAGE_PATH + "monster/monster4.gif";
            var MONSTER5_IMAGE      = IMAGE_PATH + "monster/monster5.gif";
            var MONSTER6_IMAGE      = IMAGE_PATH + "monster/monster6.gif";
            var MONSTER7_IMAGE      = IMAGE_PATH + "monster/monster7.gif";
            var BIG_MONSTER1_IMAGE  = IMAGE_PATH + "monster/bigmonster1.gif";
            var BIG_MONSTER2_IMAGE  = IMAGE_PATH + "monster/bigmonster2.gif";
            
            var RESOURCE = [
                MONSTER1_IMAGE,
                MONSTER2_IMAGE,
                MONSTER3_IMAGE,
                MONSTER4_IMAGE,
                MONSTER5_IMAGE,
                MONSTER6_IMAGE,
                MONSTER7_IMAGE,
                BIG_MONSTER1_IMAGE,
                BIG_MONSTER2_IMAGE,
            ];
            
            window.onload = function() {
                var monsterImage = document.location.search.substr(1);  // クエリで使用するモンスター画像を指定
                if (!monsterImage) monsterImage = "BIG_MONSTER1_IMAGE";
                
                // ゲームクラス生成
                var game = new Game();
                game.preload(RESOURCE);
                
                // 初期化
                game.onload = function() {
                    var scene = game.rootScene;
                    scene.backgroundColor = "#aaa";
                    
                    // AvatarMonster
                    var image = game.assets[ window[monsterImage] ];    // 使用する画像を取得
                    var monster = new AvatarMonster( image );           // 画像を渡してAvatarMonsterを生成
                    scene.addChild(monster);                            // シーンに追加
                    monster.moveTo(20, 20);                             // いい感じに移動
                };
                
                game.start();
            };
        </script>
    </head>
    <body>
        
    </body>
</html>

AvatarBG

こちらも今回の更新で追加されたオシャレな背景画像を簡単に使えるようにしたクラスです. AvatarBG の使い方は, 生成時にモード(数値)を渡してシーンに追加するだけです.

そのモードに応じた種類の背景を表示してくれます.

Sample

サンプルコードです. 実際の動作はこちらで見れます.

<!DOCTYPE html>

<html>
    <head>
        <meta charset=UTF-8 />
        <title>AvatarBG Sample | TM Life</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
        </style>
        <script src="lib/enchant.js/enchant.js"></script>
        <script src="lib/enchant.js/plugins/avatar.enchant.js"></script>
        <script>
            enchant();
            
            // リソース
            var IMAGE_PATH      = "lib/enchant.js/images/";
            var BG1 = IMAGE_PATH + "avatarBg1.png";
            var BG2 = IMAGE_PATH + "avatarBg2.png";
            var BG3 = IMAGE_PATH + "avatarBg3.png";
            var RESOURCE = [ BG1, BG2, BG3, ];
            
            game = null;
            
            window.onload = function() {
                // var mode = 1;
                var mode = document.location.search.substr(1);  // クエリで背景モードを指定
                    
                // ゲームクラス生成
                game = new Game();
                game.preload(RESOURCE);
                
                // 初期化
                game.onload = function() {
                    var scene = game.rootScene;
                    scene.backgroundColor = "#aaa";
                    
                    // 背景を無理矢理対応
                    for (var i=1; i<=3; ++i)
                        game.assets&#91;"avatarBg"+i+".png"&#93; = game.assets&#91;IMAGE_PATH + "avatarBg"+i+".png"&#93;;
                    
                    // AvatarBG
                    var bg = new AvatarBG(mode);
                    scene.addChild(bg);
                    bg.y = 50;
                };
                
                game.start();
            };
        </script>
    </head>
    <body>
        
    </body>
</html>

Code

今回制作したゲーム『ヨケモン』のスクリプト部分の全体コードです. GitHub の方に公開しているので何か良いアイディアとかあれば fork してイジってもらえると嬉しいです.

/**
 * phi
 */

enchant();

// リソース
var IMAGE_PATH      = "lib/enchant.js/images/";

var PAD_IMAGE       = IMAGE_PATH + "pad.png";
var APAD_IMAGE      = IMAGE_PATH + "apad.png";
var START_IMAGE     = IMAGE_PATH + "start.png";
var END_IMAGE       = IMAGE_PATH + "end.png";
var AVATAR_CODE     = "1:3:0:2009:2109:27540";
var BG1 = IMAGE_PATH + "avatarBg1.png";
var BG2 = IMAGE_PATH + "avatarBg2.png";
var BG3 = IMAGE_PATH + "avatarBg3.png";
var BUG_IMAGE       = IMAGE_PATH + "monster/monster1.gif";
var DRAGON_IMAGE    = IMAGE_PATH + "monster/bigmonster1.gif";

var MAIN_BGM        = "http://enchantjs.com/assets/sounds/bgm02.wav";  // メインBGM
var APPEAR_SE       = "http://enchantjs.com/assets/sounds/se3.wav";    // 出現時SE

var RESOURCE = [
    START_IMAGE, END_IMAGE,
    BG1, BG2, BG3,
    BUG_IMAGE,
    DRAGON_IMAGE,
    MAIN_BGM, APPEAR_SE,
];
// nineleap 対応
enchant.nineleap = { assets: [START_IMAGE, END_IMAGE] };
// pad 対応
enchant.ui = { assets: [PAD_IMAGE, APAD_IMAGE] };

// 定数
var BG_Y = 50;
var CHARACTER_BASE_Y    = BG_Y + 20;
var CHARACTER_STEP_Y    = 45;
var PLAYER_SPEED        = 6;

// グローバル変数
var game = null;
var bg   = null;
var player = null;
var monsterList = null;
var timerLabel = null;

window.onload = function() {
    game = new Game(320, 320);
    game.preload(RESOURCE);
    game.keybind('Z'.charCodeAt(0), 'a');
    
    game.onload = function() {
        // 背景を無理矢理対応
        for (var i=1; i<=3; ++i)
            game.assets["avatarBg"+i+".png"] = game.assets[IMAGE_PATH + "avatarBg"+i+".png"];
        game.assets["start.png"]    = game.assets[START_IMAGE];
        game.assets["end.png"]      = game.assets[END_IMAGE];
        game.assets["pad.png"]      = game.assets[PAD_IMAGE];
        game.assets["apad.png"]     = game.assets[APAD_IMAGE];
        
        
        // セットアップ
        var scene = game.rootScene;
        game.rootScene.backgroundColor = "#444";
        game.monsterInterval = 120;
        game.dragomRate = 0;
        var pad = new Pad();
        pad.y = 223;
        pad.backgroundColor = "white";
        pad._element.style.borderRadius = "16px";
        scene.addChild(pad);
        
        // 背景
        bg = new AvatarBG(1);
        bg.y = BG_Y;
        scene.addChild(bg);
        
        // プレイヤー
        player = new Player();
        scene.addChild(player);
        player.y = CHARACTER_BASE_Y;
        
        scene.onenter = function() {
            // 初期化
            game.frame = 0;
            
            // アバターモンスター
            monsterList = [];
            
            // タイマー表示
            timerLabel = new Label();
            scene.addChild(timerLabel);
            timerLabel.moveTo(10, 10);
            timerLabel.color = "white";
            timerLabel.text = "";
        };
        
        scene.onenterframe = function() {
            // モンスター生成
            if (game.frame % game.monsterInterval == 0) {
                var monster;
                var r = Math.floor(Math.random()*100);
                if (r < game.dragonRate) {
                    monster = new Dragon();
                }
                else {
                    monster = new Bug();
                }
                monster.x = 240;
                scene.addChild(monster);
                monsterList.push(monster);
                
                // 出現 SE 再生
                game.assets[APPEAR_SE].clone().play();
            }
            
            // プレイヤーとモンスターを衝突判定
            var playerX = player.x;
            var playerX2= player.x+player.width
            for (var i=0,len=monsterList.length; i= TITLE_TABLE.length) ? TITLE_TABLE.length-1 : tIndex;
    var title = TITLE_TABLE[tIndex];
    var score = time * 100;
    var msg   = "あなたのスコアは" + score + "です. 称号「" + title + "』";
    console.log(score, msg);
    game.end(score, msg);
};

// プレイヤー
var Player = Class.create(Avatar, {
    initialize: function() {
        Avatar.call(this, AVATAR_CODE);
        
        this.speed = PLAYER_SPEED;
        this.posIndex = 0;
        this.updateY();
    },
    
    up: function() {
        --this.posIndex;
        this.updateY();
    },
    down: function() {
        ++this.posIndex;
        this.updateY();
    },
    onenterframe: function() {
        var input = game.input;
        if (input.pressUp && this.posIndex > 0) {
            this.up();
        }
        if (input.pressDown && this.posIndex < 2) {
            this.down();
        }
        
        // 左右移動
        if (input.left && this.x > 0) {
            this.x -= this.speed;
            this.action = "run";
            this.left();
        }
        else if (input.right && this.x < 250) {
            this.x += this.speed;
            this.action = "run";
            this.right();
        }
        else {
            this.action = "stop";
            this.right();
        }
    },
    
    updateY: function() {
        this._element.style.zIndex = this.posIndex;
        this.y = CHARACTER_BASE_Y + CHARACTER_STEP_Y*this.posIndex;
    },
});

// モンスター
var BaseMonster = Class.create(AvatarMonster, {
    initialize: function(img) {
        AvatarMonster.call(this, img);
        
        this.action = "appear";
        this.posIndex = Math.floor(Math.random()*3);
        this.offsetY = 0;
        this.speed   = 2;
        this.update = this.appear;
        
        this.updateY();
    },
    
    onenterframe: function() {
        if (this.update) this.update();
        
        // 画面外に出たら削除
        if (this.x < -100) {
            this.parentNode.removeChild(this);
        }
    },
    
    updateY: function() {
        this._element.style.zIndex = this.posIndex;
        this.y = CHARACTER_BASE_Y + CHARACTER_STEP_Y*this.posIndex + this.offsetY;
    },

    appear: function() {
        if (this.action == "stop") {
            this.update = this.advance;
        }
    },
    
    advance: function() {
        this.x -= this.speed;
    },
});


// 虫
var Bug = Class.create(BaseMonster, {
    initialize: function() {
        BaseMonster.call(this, game.assets[BUG_IMAGE]);
        
        this.speed = 4;
    }
});


// ドラゴン
var Dragon = Class.create(BaseMonster, {
    initialize: function() {
        BaseMonster.call(this, game.assets[DRAGON_IMAGE]);
        
        this.speed = 6;
        this.offsetY = -20;
        this.updateY();
    },
});

[/code]

いやぁ~素材に困らないってのはプログラマを学んでいる人にとっては助かりますね. 見栄えが良いとモチベーションも上がりますし. 今の学生さんがうらやま~. あとは BGM や SE がもっと充実すると嬉しいなぁ~.

最近は CoffeeScript にハマってたりします. Git や GitHub の使い方に早くなれて色々と作っていこうと思ってます

近々 CoffeeScript について書いたエントリーを連投するので よかったらまた覗きにきてくださいな♪

TRACK BACK URL

POST COMMENT

メールアドレスが公開されることはありません。

COMMENT