LoginSignup
6

More than 5 years have passed since last update.

RTS(Real-Time-Strategy)ゲームを何時間で作れるか

Last updated at Posted at 2014-10-03

milkcocoaとjThreeを利用して、リアルタイムストラテジーゲームを何時間で作れるか試してみます。

開始時刻:2014年10月3日午前11時

0時間7分まで

リポジトリ作成

git clone git@github.com:syuhei176/2hour-rts.git
  • gulp導入
  • 画像ファイルなどを入れておきます。
  • 3Dの部分は、jThree( http://jthree.jp/ )を利用
git tag 0h7m

まだ何も表示されません
https://github.com/syuhei176/2hour-rts/tree/0h7m

地面を表示するようにしましょう


  <head>
      <geo id="sky" type="Sphere" param="200 64 64" />
      <txr id="blueSky" src="data/img/sky.png" />
      <mtl id="sky-mtl" type="MeshPhong" param="map: #blueSky; side: 2;"/>
      <geo type="Circle" param="200 64" />
      <txr id="groundTxr" src="data/img/ground.jpg" param="repeat: 50; wrap: 0;" />
      <mtl id="ground-mtl" type="MeshLambert" param="map: #groundTxr;"/>
      <rdr />
  </head>

ではJavaScriptを書き始めます。
milkcocoa( https://mlkcca.com/ )も使っておきましょう。


jThree( function( j3 ) {//j3 === jThree
    var milkcocoa = new MilkCocoa("https://io-hogehoge.mlkcca.com:443");
},function() {//WebGL非対応ブラウザ向け
    alert( "Your browser does not support WebGL." );
} );

0時間53分まで

ユニットをクリックして選択、他の場所をクリックして移動させられるようにしましょう。

ユニットの選択はjThreeのclick関数で行い、移動先は通常のマウスイベントでマウスの座標から計算しています。

rts.js


jThree( function( j3 ) {//j3 === jThree
    var milkcocoa = new MilkCocoa("https://io-hogehoge.mlkcca.com:443");

    var selected = null;

    j3("#unit1").click(function() {
        selected = j3(this);
        j3("#cursor").position(j3(this).position());
    });

    $(window).mousedown(function(e) {
        if(selected) {
            var pos = translateDisplay2World(e.pageX, e.pageY);
            selected.animate({positionX : pos.x, positionY : "+=0", positionZ : pos.z}, 1000);
            selected = null;
            j3("#cursor").position([100, 0, 100]);
        }
    });

    var width = document.body.clientWidth;
    var height = document.body.clientHeight;
    function translateDisplay2World(x, y) {
        return {
            z : -(x - width/2) / 10,
            x : (y - height/2) / 10
        }
    }
},function() {//WebGL非対応ブラウザ向け
    alert( "Your browser does not support WebGL." );
} );

移動できるようになりました。

スクリーンショット 2014-10-03 11.51.58.png

git tag 0h53m
git push origin 0h53m

1時間43分まで

milkcocoaでユニットの移動をリアルタイムに共有できるようにします。

ユニットをクラス化して行きます。

  • PlayerManager
  • Player
  • Unit

ソース:https://github.com/syuhei176/2hour-rts/tree/1h43m

PlayerManagerに新しくユニットを作ることや、移動することを命令します。そして命令自体をmilkcocoaのsend APIで共有します。

player_manager.js


function PlayerManager(dataStore) {
    var self = this;
    this.dataStore = dataStore;
    this.players = {};
    this.units = {};
    this.listeners = {
        "create-unit" : []
    }
    this.dataStore.on("send", function(e) {
        if(e.value.cmd == "player-create") {
            var np = new Player(e.value.pid);
            self.players[e.value.pid] = np;
        }else if(e.value.cmd == "unit-create") {
            var nu = new Unit(e.value.uid);
            self.units[e.value.uid] = nu;
            self.emit("create-unit", {
                unit_id : e.value.uid
            });
        }else if(e.value.cmd == "unit-move") {
            if(!self.units[e.value.uid]) {
                var nu = new Unit(e.value.uid);
                self.units[e.value.uid] = nu;
                self.emit("create-unit", {
                    unit_id : e.value.uid
                });
            }
            self.units[e.value.uid].move(e.value.pos)
        }
    });
}

PlayerManager.prototype.get_unit = function(id) {
    this.units[id];
}


PlayerManager.prototype.on = function(event, l) {
    this.listeners[event].push(l);
}

PlayerManager.prototype.emit = function(event, args) {
    this.listeners[event].forEach(function(l) {
        l(args);
    });
}

PlayerManager.prototype.create_player = function() {
    var player_id = new Date().getTime().toString(36);
    this.dataStore.send({
        cmd : "player-create",
        pid : player_id
    });
    return player_id;
}

PlayerManager.prototype.create_unit = function() {
    var unit_id = new Date().getTime().toString(36);
    this.dataStore.send({
        cmd : "unit-create",
        uid : unit_id
    });
    return unit_id;
}

PlayerManager.prototype.move_unit = function(id, pos) {
    this.dataStore.send({
        cmd : "unit-move",
        uid : id,
        pos : pos
    });
}

Unitクラスは、ユニットの作成(表示)と移動に責任を持ちます。

unit.js


function Unit(id) {
    this.unit_id = id;
    var x = Math.random() * 5 - 10;
    jThree("scene").append('<obj id="unit'+this.unit_id+'" style="rotateY: 0; position: '+x+' -30 0;"><mesh geo="#unit-geo" mtl="#unit-mtl" /></obj>')
     console.log("#unit"+this.unit_id);
}

Unit.prototype.get_id = function() {
    return this.unit_id;
}

Unit.prototype.get_elem = function() {
    return jThree("#unit" + this.unit_id);
}

Unit.prototype.move = function(pos) {
    jThree("#unit" + this.unit_id).animate({positionX : pos.x, positionY : "+=0", positionZ : pos.z}, 1000);
}

rts.js


jThree( function( j3 ) {//j3 === jThree
    var milkcocoa = new MilkCocoa("https://io-fi0i1mtqo.mlkcca.com:443");
    var dataStore = milkcocoa.dataStore("rts");

    var selected = null;
    var manager = new PlayerManager(dataStore);
    var myself_id = manager.create_player();
    var myunit_id = manager.create_unit();


    manager.on("create-unit", function(e) {
        j3("#unit"+e.unit_id).click(function() {
            selected = e.unit_id;
            j3("#cursor").position(j3(this).position());
        });
    });

    $(window).mousedown(function(e) {
        if(selected) {
            var pos = translateDisplay2World(e.pageX, e.pageY);

            manager.move_unit(selected, pos);

            selected = null;
            j3("#cursor").position([100, 0, 100]);
        }
    });

    var width = document.body.clientWidth;
    var height = document.body.clientHeight;
    function translateDisplay2World(x, y) {
        return {
            z : -(x - width/2) / 12,
            x : (y - height/2) / 12
        }
    }

},function() {//WebGL非対応ブラウザ向け
    alert( "Your browser does not support WebGL." );
} );

milkcocoaでユニットの移動をリアルタイムに共有できるようになりました。
ブラウザを開くと、ユニットが増えます。

スクリーンショット 2014-10-03 14.40.43.png

git tag 1h43m
git push origin 1h43m

今日はこのくらいにしておきます、疲れた・・・

ブラウザを2つ開いて、ユニットの位置が同期されるか、確かめてみてください。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6