アプリケーションが実行中のディレクトリを取得。exeファイルのある場所。
val := ExtractFilePath(Application.ExeName);
アプリケーションが実行中のディレクトリを取得。exeファイルのある場所。
val := ExtractFilePath(Application.ExeName);
ゲームエンジンのGame GuruというソフトウェアでCinema4Dで作成したモデルをインポートしてみようと思ったが上手くいかない。GameGuruは3Dモデルのインポート機能を搭載しているが、cinema4dで作成されたオブジェクトはどうしても受け付けてくれない。cinema4dにはエクスポートする機能で多彩なフォーマットに対応しており、GameGuruが採用しているDirect3Dというフォーマット(.x)形式でもエクスポートすることができるが、ロードすることができない。
ググってみたところ、https://youtu.be/tDXXFDVfnBI この動画がいいところまで行っているように見えるが、最後は何もマップ上で表示されないという結末で終わっている(´Д`;)
他にも色々調べたが、どうもcinema4dはgameguru開発には相性が悪い様子。理由はわからないがうまく行っている人も見当たらない。その他にはAutodesk 3ds Maxというモデリングソフトであれば成功したという人を見つけた。
他にも使えそうな3Dモデリングソフトが見つかったら追記予定
嘘でした。使えます。私の調べ不足と不注意。Cinema4dでモデリングしてDirectX形式でエクスポートしてGameGuruで取り込めば普通にレンダリングされるし、ゲーム内でも表示されることを確認。失敗していたのはそれ以外のファイルタイプでやっていたから。.xタイプのファイル以外にも取り込むことができそうだったけれどそれに失敗していた。
ちなみに同じことが無料の3Dモデリングソフトのblenderでもできる。初期状態ではDirectX形式で出力できないのでユーザー設定からアドオンを追加するだけで出力できるようになる。
色々迷走しながらblenderも試用してみたが、無料なのにcinema4dと同じようなことができるのに驚いた。操作感とUIは大分違うが機能的にはあまり変わらないんじゃないだろうか・・・。有料でそれなりに高価なcinema4dの方が多少は使いやすく洗練されているような気もするが。
npmサーバーをデバッグで起動していて、例のWindowsアップデートで強制再起動をかけられてしまったため妙なことになった。大したことないだろうと思って再度起動してみると下記のようなエラーを吐くようになった。一応サーバーを再起動してみたんだが、同じエラーが出るのは不可解。というのもエラーの内容を見る限りポート80が既に使われているというような内容のようだが、ポート80は私のコードでは使ってないのだが。それに再起動までしたのに。
events.js:165 throw er; // Unhandled 'error' event ^ Error: listen EADDRINUSE :::80 at Server.setupListenHandle [as _listen2] (net.js:1342:14) at listenInCluster (net.js:1383:12) at Server.listen (net.js:1471:7) at Object.(/home/nakahira/nodejs/server.js:52:4) at Module._compile (module.js:649:30) at Object.Module._extensions..js (module.js:660:10) at Module.load (module.js:561:32) at tryModuleLoad (module.js:501:12) at Function.Module._load (module.js:493:3) at Function.Module.runMain (module.js:690:10) Emitted 'error' event at: at emitErrorNT (net.js:1362:8) at process._tickCallback (internal/process/next_tick.js:114:19) at Function.Module.runMain (module.js:692:11) at startup (bootstrap_node.js:194:16) at bootstrap_node.js:666:3
psコマンドで該当するプロセスをkillしてみるかと調べたがよくわからないので、ポート80を使っているかもしれないプロセスを強制的にkill
kill -9 $(lsof -t -i:80)
これでnpm startとしたら起動するようになったが、まだ正常稼働にはいたらない。
追記で、異常終了した場合にnpmのpackage.jsonというファイルが紛失していることを確認した。npm init -yで復帰することはできたが色々とわからない現象が多い。
DirectShowを使いやすくしたライブラリ。動画の再生やウェブカメラ映像の保存などの機能を使いたいときに使うライブラリかもしれない。
画像無しで矩形スプライトを作成する
var sprite = cc.Sprite.create();
sprite.setTextureRect(cc.rect(0,0,100,100));
sprite.setAnchorPoint(0.5, 0.5);
sprite.setPosition(size.width / 2, size.height / 2);
sprite.setColor(cc.color(128,0,0));
currentScene.addChild(sprite, 0);
スプライトの大きさの変更
var sprite = cc.Sprite.create(“ball.png”);
sprite.setTextureRect(cc.rect(0,0,100,100));
アンカーポイント
sprite.setAnchorPoint(0.5, 0.5);
ポジション
sprite.setPosition(size.width / 2, size.height / 2);
カラー
sprite.setColor(cc.color(128,0,0));
シーンに追加
this.addChild(sprite, 5);
英米の時間表記では、12:00 AMという時間は夜の0時を意味している模様。つまり、11:00 PM の次の1時間は、12:00 AMということになる。そしてさらに次の1時間は、1:00 AMということになる。12:00の次が1:00というのは日本式の時間に慣れていると違和感を感じるが、アナログの時計盤をベースにそういう時間表記が生まれたのだとしたらわからなくもない。たしかに時計の文字盤に0という数字は存在しないが。では、日本でいう午前0時に相当する 0:00 AMはどういう扱いになるのかというと、英米式の時間ではそういう時間は存在しない。あくまでも日本式の時間とは別体系としてとらえなくてはならない。逆に日本式の時間表記で言うならば、午前12時という時間は存在しないと言える。昼の12時、夜の12時という言い方はあるかもしれないが、午前12時とは通常は言わない。
こういう時間の午前午後、AMPMの表記の混乱は12時間制でのみ生じる。24時間表記では存在しない様子。
プログラミングの世界ではこの時間表記は扱いづらい印象を受けるが、そういえば今まできにしたことがなかったが、プログラミンの世界では24時間表記が一般的だから問題になることはないのかもしれない。
イベントはシーンまたはレイヤー、スプライトに追加することができる。イベントを定義し、addListnerにてそのイベントと対象オブジェクトを設定することでタッチイベントを受けることができるようになる。
window.onload = function(){
cc.game.onStart = function(){
var MyScene = cc.Scene.extend({
onEnter:function () {
this._super();
var size = cc.director.getWinSize();
var sprite = cc.Sprite.create(“ball.png”);
sprite.setPosition(size.width / 2, size.height / 2);
sprite.setScale(0.8);
sprite.name = “sprite1”;
this.addChild(sprite, 0);
var sprite2 = cc.Sprite.create(“ball.png”);
sprite2.setPosition(size.width / 2.5, size.height / 2.5);
sprite2.setScale(0.8);
sprite2.name = “sprite2”;
this.addChild(sprite2, 0);
var sprite3 = cc.Sprite.create(“ball.png”);
sprite3.setPosition(size.width / 1.5, size.height / 1.5);
sprite3.setScale(0.8);
sprite3.name = “sprite3”;
this.addChild(sprite3, 0);
cc.eventManager.addListener(listener, sprite);
cc.eventManager.addListener(listener.clone(), sprite2);
cc.eventManager.addListener(listener.clone(), sprite3);
}
});
cc.director.runScene(new MyScene());
};
cc.game.run(“gameCanvas”);
};
var listener = cc.EventListener.create({
event: cc.EventListener.TOUCH_ONE_BY_ONE,
onTouchBegan: function (touch, event) {
var target = event.getCurrentTarget();
var location = target.convertToNodeSpace(touch.getLocation());
var spriteSize = target.getContentSize();
var spriteRect = cc.rect(0, 0, spriteSize.width, spriteSize.height);
if (cc.rectContainsPoint(spriteRect, location)) {
cc.log(target.name + ” touched.”);
return true;
}
return false;
},
onTouchMoved: function (touch, event) {
cc.log(“onTouchMoved”);
var target = event.getCurrentTarget();
var delta = touch.getDelta();
target.setPosition(cc.pAdd(target.getPosition(), delta));
}
return false;
}
});
シーンに対してスプライト3つを追加。(sprite1,sprite2,sprite3)
スプライトのイメージは適当なボールの画像とした。(ball.png)
スプライトを定義・追加したあとそれぞにイベントを追加。(cc.eventManager.addListener)
イベントの種類はタッチとムーブ。
スプライトが複数ある場合は、どのスプライトがタッチされたのかを識別する必要があるため、スプライトごとにイベントを設定する。イベント追加時にlistener.clone()とすることでスプライトごとのイベントを受け取れるようになる。
イベントの設定では単にイベントを定義しただけではゲーム画面全体のどこでもタッチするとイベントが受け取れるようになってしまっているため、スプライトのサイズに合わせてイベントを受け取れるように設定する必要がある。その判定がevent.getCurrentTarget()以下の記述である。
cocos2dの構成。cocos2d-jsは下記のような構成要素を持つ。
実行環境やシーンの制御など、ゲームを構成するすべてを管理するオブジェクト。
ゲームの画面を構成する。
シーン上に配置されるオブジェクト。
シーンまたはレイヤーに配置されるオブジェクト。ノード。
ゲームの起動は、ゲームの画面サイズ(キャンバス)を定義して実行する。単純にはキャンバスを定義、シーンを作成、ディレクターにシーンを設定、実行という流れになる。
<canvas id=”gameCanvas” width=”800″ height=”450″></canvas>
<script type=”text/javascript”>
cc.game.onStart = function(){
cc.director.runScene(new MyScene());
};
cc.game.run();
</script>
チュートリアルコード
<canvas id=”gameCanvas” width=”800″ height=”450″></canvas>
<script type=”text/javascript” src=”cocos2d-js-v3.13.js” charset=”UTF-8″></script>
<script type=”text/javascript”>
window.onload = function(){
cc.game.onStart = function(){
//load resources
cc.LoaderScene.preload([“HelloWorld.png”], function () {
var MyScene = cc.Scene.extend({
onEnter:function () {
this._super();
var size = cc.director.getWinSize();
var sprite = cc.Sprite.create(“HelloWorld.png”);
sprite.setPosition(size.width / 2, size.height / 2);
sprite.setScale(0.8);
this.addChild(sprite, 0);
var label = cc.LabelTTF.create(“Hello World”, “Arial”, 40);
label.setPosition(size.width / 2, size.height / 2);
this.addChild(label, 1);
}
});
cc.director.runScene(new MyScene());
}, this);
};
cc.game.run(“gameCanvas”);
};
</script>