忍者ブログ

神戸電子専門学校ゲームソフト学科の生徒が運営するGESのブログです。

   

[PR]

×

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

WindowsAPI講座【メモリマップドファイル編】 Part4

昨日は、忙しくて記事が書けませんでしたすいませんー。
克兎です。

前回、本田望結ちゃんのことを書いたけど、
それなら、忽那汐里についても書かないとフェアじゃないと思います。

なんだろう、あの可愛さは、

拍手[0回]


美人とは違うというか、いや、美人なんだよ
でもなんというかそうじゃないんだ。あれは
癒し系に近い可愛さ、身近にいそうで、って
いうか、いても不思議じゃないというか、自
然と周囲に溶け込む可愛さとでも言うべきだ
ろうか、つまり、「自然かわいい」?違う、
何かが違う。そういう表現じゃないんだよ。
その表現じゃまるで森ガールだ。森ガールっ
て何だよ。森にいそうな女の子?お前ら一生
森から出てくんな。樹海に住みやがれ畜生、
あぁ話がそれてしまった。つまり、自然とは
違うんだ、クラスにいそうな感じの、街で歩
いてても嫌味がないというか。森ガールに対
して「学校ガール」?近い!近いぞ!ただ何
かが足りない!もっと「普通」でなければな
らないあの可愛さの表現にはもっと「普通っ
ぽい」表現じゃないとだめなんだ。そう!言
うなれば「普通かわいい」だ!これだ!これ
がまさに忽那汐里の本質に違いないんだよ!


今、俺の心には爽やかな風が吹いている。
まるで悟りを開いたブッダのようだ。
いやブッダの心境とか知らんけど。

さて、
それでは続きを書きますね、
メモリマップドファイルの機能を最大限に生かした、使用法についてでしたね。

端的に言うと、構造体(クラス)のファイル展開です。
前回は、char型ポインタで受け取っていたので、char型として扱うことができました。

今回は、構造体のポインタで受け取ってみます。
すると、バイナリ単位で、ファイルを構造体の実態として扱うことができます。

これを、ゲーム作りに役立てると、ある強力なシステムを作ることができます。
それは、リアルタイムオートセーブとでも言うべき機能です。

簡単にソースを書いてみました。

今回は、事前にデータを作成する必要はありません。

使用する構造体は以下です。

main.cpp

struct Chara{

int Hp;
int Attack;
int Guard;
int x;
int y;

};



これの、説明は不要かと思います。
キャラクターの情報をまとめた構造体ですね。

続いて前準備です。

main.cpp

//ファイルマッピングの流れ*******************************************************************************

HANDLE hFile; //ファイルのハンドル
HANDLE hMap; //マッピングオブジェクトのハンドル
Chara* pPlayer; //マッピングオブジェクトへのポインタ

//Section1:ファイルを開く
hFile = CreateFile( "Player.dat" , GENERIC_READ | GENERIC_WRITE , 0 , 0 , OPEN_ALWAYS , 0 , 0 );
if( hFile == INVALID_HANDLE_VALUE )
{
printf( "ファイルオープン失敗したしー" ); //エラー
return 1;
}

//Section2:メモリ空間上にマッピング
hMap = CreateFileMapping( hFile , 0 , PAGE_READWRITE , 0 , sizeof( Chara ) , "FileMapping_katuusagi" );
if( hMap <= 0 )
{
printf( "ファイルをマッピングできねーしー." ); //エラー
CloseHandle( hFile ); //せっかく開いたけどクローズせざるを得ない(´;ω;`)
return 1;
}

//Section3:マッピングしたデータへのポインタを取得
pPlayer = ( Chara * )MapViewOfFile( hMap , FILE_MAP_ALL_ACCESS , 0 , 0 , 0 );
if( pPlayer == NULL )
{
CloseHandle( hMap ); //せっかくマップしたけどクローズせざるを得ない(´;ω;`)
CloseHandle( hFile ); //せっかく開いたけどクローズせざるを得ない(´;ω;`)
printf( "マップビューが取得できねーしー" ) ; //エラー
return 1;
}



Chara型のマップビューを作成します。

CreateFileMapping関数の第5引数を見てください。
ここは前回説明しましたが、最低限マッピングするサイズを指定します。
構造体を、マッピングオブジェクトとして作成するということは、
構造体のサイズ分必要であるという事ですね。
メモリアロケータなどを作ったことのある方なら、ここらの都合も分かるのではないかと思います。
そのため、sizeof( Chara )を引数として与えています。

あとは、キャストで受け取ればマップビューが出来上がります

続いて内部動作です。

main.cpp

//ファイルの操作****************************************************************************************

printf( "ステータスの表示:\n" );
printf( "HP :%d\n" , pPlayer->Hp );
printf( "Attack:%d\n" , pPlayer->Attack );
printf( "Guard :%d\n" , pPlayer->Guard );
printf( "x :%d\n" , pPlayer->x );
printf( "y :%d\n" , pPlayer->y );

pPlayer->Hp = 100;
pPlayer->Attack = 20;
pPlayer->Guard = 5;
pPlayer->x += 5;
pPlayer->y += 2;


データを吐き出してから値を変更します。
ここは、ゲームメイン部に相当します。

後始末は省略します。

1度目のデータは、すべての値が0になっているかと思います。
が、2度目の実行時には、1度目に入力に変更された値が表示されているかと思います。
3度目の実行では座標が加算されているはずです。

このように、構造体の実態をファイルに持たせることで、
ファイルアクセスオーバーヘッドによるタイムロス無く
リアルタイムでキャラクタのデータを保持させることができます

この機能を実装すれば、
アプリケーションの使用中にPCの電源が落ちてしまった場合や、
他プログラムとの競合による予想できない例外等によって、
プログラムが停止した場合、
再起動時に、停止した時の状態を復元できるようになります。

単なるセーブ機能として使ってもかまいません。
セーブ画面を開かなくても、常にキャラクタの状態が保持されているので、
やはり再起動時に、最後の状態に戻すことができます。

メモリプールを作っている方なら、
その領域をマッピングオブジェクトにすることでゲーム全体の状態を常に保持できます。

ただしポインタなどがあると、実態ではなくアドレスだけが保持されるため、思った通りの実行結果が得られません。
そのあたりを初期化する関数などを作っておくことをお勧めします。

正直、製品にも使えるレベルの機能ではないかと思ってしまうんだけどそうでもないのかな(´・ω・`*)

とりあえず、今回もソースをアップしておきます。

次回は、メモリマップドファイルによるプロセス間通信について書きたいと思います。
そ~れ~で~は~(*´∀`)ノ
PR

COMMENT

NAME
TITLE
MAIL(非公開)
URL
EMOJI
Vodafone絵文字 i-mode絵文字 Ezweb絵文字
COMMENT
PASS(コメント編集に必須です)
SECRET
管理人のみ閲覧できます

ブログ内検索

最新コメント

[01/29 人面犬]
[10/01 8ch]
[09/12 uncle]
[09/10 某卒業生]
[06/07 uncle]

カレンダー

03 2024/04 05
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

テスト

Copyright ©  -- GESブログ --  All Rights Reserved
Design by CriCri / Photo by Geralt / powered by NINJA TOOLS / 忍者ブログ / [PR]