忍者ブログ
個人サークル「のくたん結鼓」の子が、色々書き残すだけの処。梅よろしでも飲みながらのんびり見てやってください
[37]  [36]  [35]  [34]  [33]  [32]  [31]  [30]  [29]  [28]  [27
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

はーい。あい。ちゃんです
先日学校の卒業式が終わりいよいよ完全な社会人になるきっかけとなりましたが
こんな感じで世の中進んでくるんでしょうねぇと思うと
ちょっと怖くなってきます(進歩が






進歩の話が出たところでその進歩のお話。
あい。ちゃんSTG企画ですが一歩二歩進んだり帰ったりしながら
のんびり時間が過ぎていきます。

というのも使っている言語、C++の使い方がよく分かってないというのもあります。

だって最近になってvectorとかスマートポインタとか知りましたからね……

しかも正直言って今回のお話は動的に作る意味というのはないです。
寧ろ重くなる気もしますし、シミュレーションやRPGならまだしも
フレームレートが重要なSTGでやる所業ではないかもしれないです。

じゃあなぜやるかって?

俺カッコいEEEEEがしたいからです。

さて、現在私は敵オブジェクトを
csvで内容データを作りそれをロードして敵オブジェクトを確保しています。

その際、敵はクラス化しているのですが
それだと敵が一種類しか作れないので



ちょっとわかりにくいですが派生クラスで敵の情報を作り
csvのデータ列でどの敵オブジェクトをロード時に読み込むかという仕組みにしてます。

それによって、派生した敵はすべてユニークとなり、
個別のアニメーションができるようになりました。

問題なのはそれをどうやって追加していくのか。

ベースクラスの配列に派生クラスを入れるというのは実体ではできません。
enemy[1] = enemyA;
なんてやってもできないんです。(多分)

そのため、こういう作りでオブジェクトを作っていく場合は
ポインタを使用します。

ポインタは実際よくわかってないですが
とりあえずこんな使い方もできるんだという感じで思っといていいと思います。

Enemy* enemy = new EnemyA();

型宣言とか考えてなかったのでちょっと混乱するでしょうが
申し訳ないです。

とにかく、これによってベースクラスに対して派生クラスを
入れて使えるようになりました。
あとはベースクラスに
更新処理と描画処理をいれて仮装関数にして派生クラスに記述すればちゃんと動きますね。

ですが一つ問題があります。
new演算子を使う決まり事のようなんですが
必ずdeleteを使わないと要素を確保したままになってしまい
PCのメモリ不足。メモリリークが起きるようなんです。
上記の状態ならまだしも、配列になると厄介です。

std::vector<Enemy*> enemy;

for(int i = 0; i < 100; i++){
enemy.pushback(new EnemyA());
// EnemyAというオブジェクトを作り、そのアドレスをenemyにいれる
}

これは動的配列での方法になりますが
絶対にこれはやめてください。

for(int i = enemy.size(); 0 < i; i--){
enemy.erase(enemy.begin() + i); // enemyのアクセスを消去する
}
// 消してるのはあくまでポインタなのでEnemyAというオブジェクトは解放されていない。

これをしてもenemyに入れたnewの内容は解放されず、
vectorでアクセスできなくなっただけでPCに残りっぱなしになるようです。

こうなってしまうともうnewのオブジェクトを読むことはできなくなります。
ちなみに

for(int i = enemy.size(); 0 < i; i--){
Enemy* p = enemy[i];
enemy.erase(enemy.begin() + i); // enemyのアクセスを消去する
delete *p;
}

ってやればたぶん行けると思います。

……

面倒

eraseした時点でオブジェクトも消えて解放してよって思います。

なのでそうしましょう。

C++のstd標準ライブラリ?っていうのには
スマートポインタというものがあるようです。
その中でもstd::shared_ptrというのを使うことによって

eraseで要素を削除したときに同時に解放されようようになるみたいです。
javaのnewしたものを消してくれる機能みたいな感じですね。

std::shared_ptrには内部でカウンタを持っていてそれが
アクセスできる数というのを表してるみたいです。
それが0になったら解放されるっていう機能みたいですね。

なので

sta::vector< std::shared_ptr<Enemy*> > enemy

for(int i = 0; i < 100; i++){
enemy.pushback( std::shared_ptr< EnemyA >( new EnemyA) );
// EnemyAというオブジェクトを作り、そのアドレスをenemyにいれる
}

for(int i = enemy.size(); 0 < i; i--){
enemy.erase(enemy.begin() + i); // enemyのアクセスを消去する
}

これでちゃんと消えるようになったみたいです。

ほとんど駆け足でわかりにくいと思うので
興味があったら調べてみてもらった方がいいと思います。

もっとわかりやすいと思うので……


そういえばこういうコードってブログでうまく書くにはどうすればいいんでしょうか?
なんかブログによってはコード用のスペースみたいなのがあるので
ちょっと調べてみます

ということで今回はここまでです
PR
back
COMMENT
name
title
text
color   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
mail
URL
pass
secret
PREV ←  HOME  → NEXT
カレンダー
11 2017/12 01
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
最新コメント
プロフィール
HN:
あい。
年齢:
23
性別:
非公開
誕生日:
1994/01/09
自己紹介:
仕事でunityしつつ、3Dとかやるので
そろそろどこに向かってるのか分からなくなってきた人

めーるあどれす:
nokutan_aiあっとyahoo.co.jp

このブログはリンクフリーです。
バナーのURL
"http://file.nokutanno.kagome-kagome.com/banner.gif"
になってると思います。






カウンター
リンク
リンク先募集してます!
Copyright (C) 2017 結鼓記録書庫 All Rights Reserved.

Photo by (c)Tomo.Yun   TemplateDesign by kaie
忍者ブログ [PR]