トップページgamedev
981コメント424KB

ゲームプログラミング相談室【Part6】

■ このスレッドは過去ログ倉庫に格納されています
0001名前は開発中のものです。04/03/06 01:25ID:d2e/eEyg
ゲームプログラミング全般の質問スレッド。
扱う話題のダイナミックレンジはやや広め。包容力高め。
他の初心者質問スレとの棲み分けを探りつつ
これからもマターリと活用しておくれ。
 
■過去スレ
【Part2】http://pc.2ch.net/tech/kako/985/985540361.html
【Part3】http://pc.2ch.net/tech/kako/1002/10028/1002894129.html
【Part4】http://game.2ch.net/gamedev/kako/1005/10050/1005040025.html
【Part5】http://pc2.2ch.net/test/read.cgi/gamedev/1036410116/
■関連スレなど
>>2-5
06516422006/01/21(土) 11:40:57ID:7OciQh2j
>>650
このようなゲームループにしてるんですが、ここに問題はないでしょうか。
0652名前は開発中のものです。2006/01/21(土) 11:57:20ID:cOBg8t3k
まず描画処理とイベント処理のスレッドを分ける。
0653名前は開発中のものです。2006/01/21(土) 11:59:39ID:7OciQh2j
>>652
返答ありがとうございます。さっそくやってみます。
0654名前は開発中のものです。2006/01/21(土) 12:17:55ID:E5l3VzaB
スレッド
0655名前は開発中のものです。2006/01/21(土) 12:24:15ID:gndLCiDd
>>642
うちはこんな感じ。スレッドなんかいらんw

INTRun()
{
MSG msg;

msg.message = WM_NULL;
PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);

while (WM_QUIT != msg.message)
{
if (PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE))
{
if (GetMessage(&msg, NULL, 0U, 0U))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
//ゲームの処理へ
}
}

return (INT)msg.wParam;
}
0656名前は開発中のものです。2006/01/21(土) 12:41:58ID:nqZd1DMC
駄目な書き方の見本提示乙。
0657名前は開発中のものです。2006/01/21(土) 12:41:58ID:FcJBx5+J
>>650
Paint(); をコメントアウトした場合と
掛かる時間を比較しよう。
劇的に速度が違うなら Paint() の中に問題があるんじゃないのかな。
0658名前は開発中のものです。2006/01/21(土) 12:58:21ID:gndLCiDd
>>656
そうなん?どこが駄目か教えて。
ちなみに少し前のDirectXSDKサンプルのまんまです。
06596422006/01/21(土) 13:08:25ID:7OciQh2j
スレッドを使用してみましたが、多少動作が軽くなった感じはするものの大差はありませんでした。
みなさんありがとうございます。
>>655
うらやましい
>>657
大きな違いはありませんでした。
DirectXを使わなければ問題は起こらないので、初期化の地点で問題があるのかもしれません。
もう少し見直してみます。
06606422006/01/21(土) 13:54:29ID:7OciQh2j
解決しました。
D3DCREATE_MIXED_VERTEXPROCESSING を 
D3DCREATE_SOFTWARE_VERTEXPROCESSING に代えるだけでした。
まさか初期化にミスがあるとは思わなかったもので・・・。
アドバイスを下さった皆さん本当にありがとうございました。
0661名前は開発中のものです。2006/01/21(土) 14:07:21ID:/mV6xXb2
ttp://lacc.biz/cpp/cpp07.html
ここのサンプルを実行してみたのですが
画面消去の命令があるにもかかわらず、
画面が更新されないで指定画像が重なって表示されてしまいます。
ClsDrawScreen() ;だけが効いていないようなのですが、何が問題なのでしょうか。
ClsDrawScreen() ;をコメントアウトしてもしなくても同じ結果になります。
0662名前は開発中のものです。2006/01/21(土) 15:26:20ID:+T+cr/VJ
>>654
SleepしないとCPUの処理時間を占有するからじゃないかなぁ…。
急いで書いたから汚いけど、スレッド分けるとセオリー的にはこんな感じかな?

DWORD WINAPI gMainLoop(LPVOID lpDone){//ゲームのメインループ
  bool* pDone = dynamic_cast<bool *> (lpDone);
  while(!(*pDone));//ここでループ
  ExitThread(0L);
}

class CGameMain{/ゲームクラス
public:
  CGameMain():done(false){CreateThread(NULL, 0, gMainLoop, &done, 0, NULL);}
  ~CGameMain(){done = true;WaitForSingleObject(hThread, INFINITE);}//スレッド終了
  bool CGameMain::IsDone(void){return done;}
  void CGameMain::Kill(void){done=true;}
private:
  bool done;
  HANDLE hThread;
};

// WinMain側の処理
  MSG msg;
  CgameMain *pGMain = new CgameMain();
  do{
    if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){
      TranslateMessage(&msg);DispatchMessage(&msg);
    }else{
      if (pGMain->IsDone()) DestroyWindow(g_hWindow);
    }
  } while (msg.message != WM_QUIT);
  delete pGMain;
06636622006/01/21(土) 15:26:40ID:+T+cr/VJ
>>668の間違いでした。
06646632006/01/21(土) 15:27:18ID:+T+cr/VJ
さらにまちがい、662は>>658へのレスです。
酔いが回りすぎです。
0665名前は開発中のものです。2006/01/21(土) 16:56:03ID:gndLCiDd
まあ、656は単発IDの煽りでしょう。
スレッドの話をすると荒れるのでやめとこうw
0666名前は開発中のものです。2006/01/21(土) 17:14:45ID:VeQ0DG52
>>665
DirectXのサンプル自体はあくまでサンプルであって、
あくまでDirectXの機能を紹介するために作られただけであのままでは実用出来ない。
理由はサンプルのままだとFlip時にV-Sync相当のウエイトを入れているので、
フレームスキップや、動作が重くなった場合に描画以外の処理だけ先に進めることが出来なくなる。
逆にウエイトを外すと無限にぐるぐるまわすことになり、
ベンチマーク用に能力を測るのなら適切だけど、実際のプログラムとしては不適切。
またループの内側でSleepをすると、その間ウインドウメッセージが処理できなくなる。

だからDirectXの機能紹介と能力測定のサンプルとしては適切なソースでも、
実際のプログラムには不適切な書き方なんだよ。
0667名前は開発中のものです。2006/01/21(土) 18:00:17ID:gndLCiDd
>>666
メッセージ処理のことなら上の3つは同じことだと思うが違うかな。
スレッドのことなら荒れるので(ry
0668名前は開発中のものです。2006/01/21(土) 18:09:01ID:cOBg8t3k
目的の違うサンプルソースをみて、それで正しいと思ってしまうことに問題があるんだろう。
さらに間違ったままそれを広めようとする奴とか。
0669名前は開発中のものです。2006/01/21(土) 18:11:30ID:gndLCiDd
何も考えず変なソース張った俺が悪いなこれはwすまそん
0670名前は開発中のものです。2006/01/21(土) 19:30:15ID:ZH97Dxy8
おし。おれもなにもかんがえずに貼ってみようかな

for( ; ; ) {

MSG msgmouse;
msgmouse.message = WM_NULL;
while(PeekMessage(&msgmouse, NULL, WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE)) Sleep(0);
if(msgmouse.message == WM_MOUSEMOVE) DispatchMessage(&msgmouse);
MSG msg;
while(PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE )) DispatchMessage(&msg);

if(fpstimer.PeekElapsedTime() > MIN_ELAPSED_TIME_FOR_FRAME)
{
 fpstimer.Reset();

 HRESULT hr;
 if( FAILED( hr = Render3DEnvironment() ) ) { break; }
 if(hr == S_OK) m_pd3dDevice->Present( NULL, NULL, NULL, NULL );

 if(msg.message != WM_CHAR && msg.message != WM_KEYDOWN && msgmouse.message == WM_NULL &&
            fpstimer.PeekElapsedTime() + 0.002 < MIN_ELAPSED_TIME_FOR_FRAME)
  MsgWaitForMultipleObjects(0,NULL,FALSE,2,QS_ALLEVENTS); // sleep until messages come
 else
  Sleep(0);
}
}
0671名前は開発中のものです。2006/01/21(土) 21:35:41ID:bEVxbAiq
>>668
そしてしったかしたいだけのオマエとかな
06726612006/01/22(日) 06:34:40ID:4Vf7TlrB
DXライブラリさんのほうのサンプルでも同じ現象がおきたので、
そちらでお伺いさせていただくことにしました。
スレ汚しすいません。
0673名前は開発中のものです。2006/01/23(月) 14:58:01ID:yyObefN6
>> 602-605
閉じられたハンドルにはまた新しいデータが割り当てられますよね。
これって閉じたハンドルを閉じられたとは知らずに保持していて
ハンドルを参照した時に別のデータを取得してしまう危険性は無いでしょうか?
マジックナンバーがラップして同じインデクスに同じマジックナンバーが
割り当てわれる可能性は十分にあると思うのですがどうなんでしょう?

1. AがHというハンドルを持っていたとします。
2. AはBにHを分け与えました。
3. BはHを破棄したくなりその場で破棄(mgr.Release(H))しました。
4. AはHを参照するも無効なハンドルだと知ることが出来ました。
ここまではいいんですよ。生ポインタじゃこのシナリオは書けません。

上の3.と4.の間で大量のハンドルの生成が行われた場合、
4.でAが(閉じているはずの)Hを参照した時にHと同じインデクス/マジックナンバーの
ハンドルの再割り当てが行われるとAは別のデータを参照してしまいます。
0674名前は開発中のものです。2006/01/23(月) 15:33:46ID:EPKLYP2E
>>673
マジックナンバーの値は増加する一方だから
基本的に同じマジックナンバーは割り当てられない。
ただしマジックナンバーを保持する変数には当然上限があるから
ハンドルの生成数にも限りがある。

と俺は思う。
06756732006/01/23(月) 15:55:07ID:yyObefN6
>>674
ハンドル生成数はインデクスの方ですよね?
マジックナンバーは正当性を保証するだけのもので。
ハンドル数に関係なくハンドルの生成/破棄を繰り返せばそれだけでマジックナンバーは増加します。
マジックナンバーはインデクスとは比べ物にならない位インクリメントされるので
意外とすぐ上限に達してしまうような。
0676名前は開発中のものです。2006/01/23(月) 16:00:23ID:EPKLYP2E
>>675
違うんじゃない?
インデックスの方はマジックナンバーがあるお陰でループしても平気だけど
マジックナンバーの方はそうは行かない。
06776732006/01/23(月) 16:24:21ID:yyObefN6
>>676
それだとハンドル数が例え1個でも生成/破棄の回数が決まってしまいますよね?
インデクスは破棄されたハンドルのものを再利用するのでインデクスに16bit割り振れば
65536個持てるわけですよね。

なんだか本題より前の段階で意見の相違があるみたいですね。
実装はgemsの1.6項のものです。
0678名前は開発中のものです。2006/01/23(月) 16:27:52ID:EPKLYP2E
いやいや、参照カウンタではないから
ハンドルをコピーするだけではマジックナンバーは増えないのでは?
06796732006/01/23(月) 16:32:22ID:yyObefN6
>>678
ええ、確かにハンドルのコピーだけではマジックナンバーは増えません。
ですがマネージャにハンドルを要求すればその分マジックナンバーは増えますよね?
ゲームを動かしていて2時間くらいしたら
「マジックナンバーが一杯なので終了します」じゃ話にならないですよね・・・?

gemsのP73 でもマジックナンバーのラップ処理は記述されてるので、
マジックナンバーはラップ前提なはずですよ。
0680名前は開発中のものです。2006/01/23(月) 16:53:58ID:EPKLYP2E
>マジックナンバーはラップ前提なはずですよ。
そうでしたか。今手元にGems無いんで家に帰ったら確認してみます。

>マネージャにハンドルを要求すればその分マジックナンバーは増えますよね?
>ゲームを動かしていて2時間くらいしたら
>「マジックナンバーが一杯なので終了します」じゃ話にならないですよね・・・?
だから種類ごとにハンドルマネージャ作れるようにテンプレートにしてあるのでは。
無限にというのはいくらなんでも無理だからその中で想定最大数を見積もって
バランスよく分けて管理すると。
06816732006/01/23(月) 17:19:16ID:yyObefN6
>>680
>だから種類ごとにハンドルマネージャ作れるようにテンプレートにしてあるのでは。
と言う事はマジックナンバーがラップして同じインデクスに
同じマジックナンバーが割り当てられてしまうのは仕様って事ですかね。

>無限にというのはいくらなんでも無理だからその中で想定最大数を見積もって
ですね。
ですがgemsでは「インデクスの範囲内でユニークを保証する」といった意味で書かれていると解釈したため
ゲームオブジェクトのようなものにハンドルを割り当てようと思ったわけです。
ですがテクスチャやサウンドなどのリソースに割り当てるなら問題ないってレベルなんでしょうね。
0682名前は開発中のものです。2006/01/23(月) 17:30:41ID:EPKLYP2E
16bit-16bit みたいにインデックスとマジックナンバーで半々にしなけりゃ
同インデックス、同マジックナンバーってのはそうそうでないのではないかな
Gemsでも8-24とかになってたような 気のせいだったかな?
記憶があやふやでスマソ。
06836732006/01/23(月) 17:56:28ID:yyObefN6
>>682
>16bit-16bit みたいにインデックスとマジックナンバーで半々にしなけりゃ
>同インデックス、同マジックナンバーってのはそうそうでないのではないかな
でも確立的に低いからといってゲームオブジェクトなどの場合
オブジェクトの摩り替わりは絶対にあってはならない事ですよね。
しかも一番見つけにくい部類のハグになりそうですし。

>Gemsでも8-24とかになってたような 気のせいだったかな?
たしか半々だったような。テクスチャリソースの管理ならどんな割合でも問題なさそうですけど。

マジックナンバーを本物のGUIDにしたらどんくらい遅くなるんだろうか。
他に早くて確実なユニークIDって何かないかなぁ。
0684名前は開発中のものです。2006/01/24(火) 01:14:06ID:tH1FX665
アドレスだと確実にユニークです。
0685名前は開発中のものです。2006/01/24(火) 01:23:48ID:TYtG+MJg
>>684
どういうこと?

void* p = malloc(1);
free(p);
void* q = malloc(1);
assert(p != q);

こうは言えないだろ。
0686名前は開発中のものです。2006/01/24(火) 02:27:10ID:tH1FX665
アドレス空間より広いサイズのIDは保持不可能という前提で言ってたんだが。
開放済みのアドレス参照するようなアホはハングアップでもなんでもすればいいんじゃね?
06876732006/01/24(火) 04:33:44ID:YZe4vdms
>>686
685氏はアドレスじゃdangling pointerは防げないよって意味でmallocの例を出したんじゃないんですか?
pを他のやつにばらまいて誰かがpを開放したらpの有効性を誰が保証してくれるんでしょう。

上記のハンドルだと再割り当ての可能性があるし、
スマートポインタじゃオーバースペックだから他にユニーク性を保証するものってないだろうかっていう話ですよ。
でももう面倒だから参照カウンタで管理します。
0688名前は開発中のものです。2006/01/24(火) 05:27:10ID:0JfXcgLd
32bitもあれば、1秒間に1000個生成しても、
一ヶ月プレイし続けたところでラップさせられない。

16bitやそこらでも、
16bit値をラップさせるほどオブジェクトが生成されるほどの時間、
ハンドルを寝かせるようなアルゴリズムにしなければいい。
06896732006/01/24(火) 05:46:51ID:YZe4vdms
>>688
>32bitもあれば、1秒間に1000個生成しても、
>一ヶ月プレイし続けたところでラップさせられない。
1秒間に1000個って60FPSのゲームで1フレ約16個ですよね。
局所的に見ればそれ以上生成される可能性は十分にありますよ。
でもまあIPv6でIPが2^128個以上存在する可能性は
将来的に十分ありえるから心配って言ってるようなもんですかね。

>bit値をラップさせるほどオブジェクトが生成されるほどの時間、
>ハンドルを寝かせるようなアルゴリズムにしなければいい。
確かにこれを厳守すれば確立的に問題ないでしょうが、
人間はミスする生き物です。
他人がどうコーディングするかは他人まかせなので・・・。

実際みなさんはゲームオブジェクト(のポインタ)をどのようにして管理してます?
0690名前は開発中のものです。2006/01/24(火) 06:30:02ID:mDNWO736
理想に燃えて政治運動に傾倒しちゃうタイプだね。
0691名前は開発中のものです。2006/01/24(火) 15:11:47ID:OImDqu0S
ミスしないように気をつけてます。
なぜかミスしてなくても止まったり動かなかったりしますorz

いろいろなところで、オブジェクト指向のためのプログラミング理論が
展開されてるなあw
0692名前は開発中のものです。2006/01/24(火) 17:03:38ID:/21JgKVE
>>689
32bit型整数でマジックナンバーを表し、
ゲームが60fpsで1fpsごとに100オブジェクト生成することを考えます。
マジックナンバーがオーバーフローするまでには
2^32 / (100個 * 60fps * 60sec * 60min * 24hour) = 8.28日
かかりますので、仕様として「ゲームは連続一週間以上動かさないで下さい。」とするか、
これで満足できない場合は32bit型整数を2つ使いましょう。
ちなみに、この場合(ry
0693名前は開発中のものです。2006/01/25(水) 01:23:31ID:NTRzHP+4
32bitがフローするようなメモリを扱えるのか?アアン?
0694名前は開発中のものです。2006/01/25(水) 01:49:38ID:BOmLnX9t
滅茶苦茶低レベルな話で申し訳ないんだけど、AIを組むには関数できないと無理?
ひたすら条件分岐しまくりだったらやっぱりみっともないの?

0695名前は開発中のものです。2006/01/25(水) 01:55:15ID:5sRU4y71
アイボの制御コードを、NHKの番組でチラッっと見たことがあるが、
swith-case文が何十何百と、滝のように流れていたな。

アドバイス欲しいなら言語かいた方が良いかもよ。どのみち関数は出来ないとだけど。
0696名前は開発中のものです。2006/01/25(水) 10:01:28ID:gmXOMyeO
状態遷移は、switch-caseで切り替えてもいいし
関数ポインタで切り替えする手もあるな。

どの状態のときに何をするのか、ちゃんと管理出来るのであれば条件分岐しまくりでも構わないよ。
みっともなかろうが作りやすい手段を取ればいい。
0697名前は開発中のものです。2006/01/25(水) 10:03:07ID:tn59aU26
>>696 自分ひとりしか読まなくていいなら、という条件付きで頼む。
0698名前は開発中のものです。2006/01/25(水) 13:58:23ID:BOmLnX9t
使ってるのはHSP。
本屋でゲームAIの本を立ち読みしたら、ファジー理論とかって奴が書いてあったからさ。
理屈は分かったんだけど、関数が自分の理解の範疇を超えてたから、
ちょっと不安になった。

やっぱり、条件分岐連発より関数使った方が処理は早いのかな?
だったら関数で出来るかぎりやってみたいんだけど。
それとも、初めて組むプログラムでそこまでやるのは無謀?
0699名前は開発中のものです。2006/01/25(水) 14:30:31ID:7MagqtIT
>>698
条件分岐と関数では、処理速度に大きな違いはない
ただソースコードの読みやすさとか修正のしやすさに大きな違いが出る

基本は関数単位で作るものだと思った方がいい
もちろん>>696案のほうが有効な状況もあるけど
0700名前は開発中のものです。2006/01/25(水) 14:30:38ID:vp/xDrq7
自分は条件分岐を連発した関数を使ってます ><
0701名前は開発中のものです。2006/01/25(水) 22:02:47ID:/k0hXHel
俺らはゲームプログラマだ。
一般アプリのプログラマでもOS屋でもない。
作った者が勝ちだ。
動かした者が勝ちだ。
条件分岐のカルボナーラでいいじゃないか。

ずっと書き続けていれば、いつか自然に条件分岐を捨てる日が来るのさ。
0702名前は開発中のものです。2006/01/25(水) 22:09:14ID:LjkjN1ec
うむ。
後で書き直したってせいぜい3日だよ。
それなのに始める前に何日悩むのかw
0703名前は開発中のものです。2006/01/25(水) 22:42:06ID:5CRuCrfQ
>>700-702を見てやる気が出たよ
0704名前は開発中のものです。2006/01/26(木) 01:35:32ID:p9JhM1p4
>>701
糞コードの量産を正当化するような発言は控えてください。
0705名前は開発中のものです。2006/01/26(木) 02:38:40ID:Id3aznFo
>>704
どうせ晒さないからおk
0706名前は開発中のものです。2006/01/26(木) 02:59:37ID:p9JhM1p4
  ,j;;;;;j,. ---一、 `  ―--‐、_ l;;;;;;   
 {;;;;;;ゝ T辷iフ i    f'辷jァ  !i;;;;;   
  ヾ;;;ハ    ノ       .::!lリ;;r゙
   `Z;i   〈.,_..,.      ノ;;;;;;;;>
   ,;ぇハ、 、_,.ー-、_',.    ,f゙: Y;;f   そんなふうに考えていた時期が
   ~''戈ヽ   `二´    r'´:::. `!   俺にもありました
07076732006/01/26(木) 15:37:38ID:eu4m8wWi
>>692
>32bit型整数でマジックナンバーを表し、
確かにマジックナンバーに多量のbitを割り当てれば問題ないのはわかってるんですが、
ハンドルを32bit(約レジスタサイズ)に収めたいジレンマがあったのでそもそもこんな質問をしたわけです。
しかもその32bitをインデクスと共有するため実用上は最大で20bitほどしか割り当てられません。
単一のインデクスが毎回使いまわされるという最悪なアルゴリズムでは
20bitを消費した直後にハンドルに同じマジックナンバーが割り当てられてしまいます。
均等に12bitのインデクスが使われる確立も低いため、間をとってインデクスの約6bitが平均して使われると仮定すると
26bitですので約3時間で再割り当てが行われる可能性があります。

まぁ32bitにこだわらなくても最近のPCなら(ry
07086732006/01/26(木) 15:47:34ID:eu4m8wWi
間をとって6bitってアホですな。
8bitで12時間ですか。ゲーマーはご遠慮くださいってとこで・・・。
0709名前は開発中のものです。2006/01/26(木) 17:54:38ID:yrvBeKCI
本当に簡単なマリオ風横スクロールRPGみたいなのを作りたいんだけど、ブロック(壁とかのオブジェクト)の表現ってどうするの?
画面表示用の配列を作って、1ブロック分移動するたびにマップデータ配列から新しいブロック列を読み込む
ってのを使ってるんだけどどうも重くて
0710名前は開発中のものです。2006/01/26(木) 18:06:36ID:MnDriWAX
その程度の処理で何で重くなるのかがさっぱり分からん。
0711名前は開発中のものです。2006/01/26(木) 19:19:29ID:yrvBeKCI
Pen4 RadeonVEだからかもしれない
0712名前は開発中のものです。2006/01/26(木) 19:21:36ID:yrvBeKCI
Pen4 1.7GHzだった
そろそろパソコン購入を考えた方がよさそう
0713名前は開発中のものです。2006/01/26(木) 20:53:11ID:R2/Ifoi1
まあさんざん引っ張って悪いんだが、設計ミスです。
0714名前は開発中のものです。2006/01/26(木) 21:07:57ID:yrvBeKCI
正直自分でもなんとなくおかしいと思ってた
マップとか当たり判定の仕方を解説してるサイトとか無いかな
0715名前は開発中のものです。2006/01/26(木) 22:57:30ID:R2/Ifoi1
ミスはシリアルナンバーの方ね。(笑)

マップのサイズってどんなもんよ。 メインメモリをはるかにオーバーしてるんじゃなければ
そうそう重たくならないと思うんだが。

スーパーマリオなんて8bitマシンの4Mhzで普通に動いてたろ。
0716名前は開発中のものです。2006/01/27(金) 14:01:24ID:ZzcOIWPU
RPGゲームの作り方教えちくり
ダブルバッファリング使ってマップ描画したいんだけど
そうすると当たり判定とか訳分からない
0717名前は開発中のものです。2006/01/27(金) 14:23:04ID:vJBgpAN1
>RPGゲーム
ねらって書いただろ?

ダブルバッファリング使ってマップ描画の方法をしりたい。
マップ描画したあとの当たり判定をしりたい。どっち?

どっちにしろ俺はプログラム素人だから知らないがな。
0718名前は開発中のものです。2006/01/27(金) 14:25:00ID:odjJ0rRD
>>717
>どっちにしろ俺はプログラム素人だから知らないがな。

おまい潔いな( ´ー`)y─┛~~
0719名前は開発中のものです。2006/01/27(金) 14:50:59ID:ZzcOIWPU
>>717
>ねらって書いただろ?
恥ずかしくて「はいそうです」としか言いようが無い

どちらも
簡単な横スクロールは作ってみたけどどうもおかしい
普通なプログラマのやり方が知りたい
0720名前は開発中のものです。2006/01/27(金) 14:54:34ID:odjJ0rRD
>>719
>> ねらって書いただろ?
> 恥ずかしくて「はいそうです」としか言いようが無い

おまいも潔いな( ´ー`)y─┛~~
0721名前は開発中のものです。2006/01/27(金) 15:10:22ID:6gofb40N
キーワードは「自作自演」
0722名前は開発中のものです。2006/01/27(金) 16:01:58ID:k5wFytZR
マジレスすると、マップの当たり判定はチップナンバーでするか、
細かく判定したいのなら当たり判定用のマップを別に作る。
0723名前は開発中のものです。2006/01/27(金) 16:07:12ID:ZzcOIWPU
>>722
チップナンバーとは何でしょう?
0724名前は開発中のものです。2006/01/27(金) 16:21:18ID:k5wFytZR
なんか釣り臭い気がするなw

RPG作るなら、マップエディタがいるだろ?
マップチップはわかるな?

マップチップ0=海
マップチップ1=草原
0とか1がチップナンバー。

それを頼りに判定する方法。
海に囲まれた島があったら

0000000000
0011111100
0111111110
0111111110
0011111100
0000000000

こういうマップになるだろ?
で1なら通れるわけだ。

当たり判定にバッファリングは関係ない。
0725名前は開発中のものです。2006/01/27(金) 16:23:55ID:sZghv91r
マップ描画用データはマップ描画用データで処理すればいい。
当たり判定は当たり判定用データで処理すればいい。
難しいことは、単純なことに分解、小分けにしていくことで大抵クリアできるんぽ。
0726名前は開発中のものです。2006/01/27(金) 17:05:37ID:ZzcOIWPU
>>724-725
ごめん、本当に初心者です
バッファリング用のint二次元配列と当たり判定用のint二次元配列を一緒にしようと思ってたので頭がこんがらがってしまって
別々に作ってみます
ありがとうございました
0727名前は開発中のものです。2006/01/27(金) 17:10:51ID:Cddpk7ys
レイヤ使わないなら、判定用に分けなくてもいい気がする。
0728名前は開発中のものです。2006/01/27(金) 18:16:19ID:ZzcOIWPU
BMP読み込み
マップデータ(ブロック種類記述)読み込み
マップデータからマップデータ配列
struct MapData{
  POINT pt;
  int type)
0729名前は開発中のものです。2006/01/27(金) 18:16:51ID:ZzcOIWPU
うっわ恥ずかしミス
0730名前は開発中のものです。2006/01/27(金) 20:46:59ID:IEFBcByl
可愛いよ>>729
その恥じらう姿がたまらなく可愛いよ>>729
0731名前は開発中のものです。2006/01/27(金) 21:24:04ID:Cddpk7ys
>>728
書きかけだし、ミスならアレだけど、
なんで POINT が必要なのかな・・・かな?
0732名前は開発中のものです。2006/01/27(金) 21:48:01ID:ZzcOIWPU
0とか1とかが並んだマップデータファイルからデータを読み込んでtypeに格納、その際POINT型のptに座標(開始0,0)も格納
座標は1チップ読み込む度に座標+=1チップのサイズ
これを100チップx100チップの仮想BMP(マップファイル)に書き出す
キャラクターの座標はクライアント領域内の座標じゃなくマップ内の座標にする
・・ってのをやってみたいと思ってる
マップ作っちゃうと重くなるかな?
0733名前は開発中のものです。2006/01/27(金) 22:41:59ID:Cddpk7ys
おk、把握した。チップ画像の座標てことね。

そんなんでいいと思うよ。
0734名前は開発中のものです。2006/01/27(金) 22:43:08ID:ZzcOIWPU
良かった
がんばってみる
0735名前は開発中のものです。2006/01/27(金) 22:44:24ID:Cddpk7ys
参考までに
http://gamdev.org/w/?%5B%5B%A5%DE%A5%C3%A5%D7%A5%A8%A5%C7%A5%A3%A5%BF%5D%5D
0736名前は開発中のものです。2006/01/27(金) 22:48:15ID:ZzcOIWPU
ありがとう
今エディタ探してたところ
0737名前は開発中のものです。2006/01/28(土) 05:38:41ID:7XpuQXDc
>732
今のPCパワーなら何ら問題無い
メモリの有効利用がキーになるけど
それよりもマップの画像データを
作るほうが大変
0738名前は開発中のものです。2006/01/28(土) 10:21:30ID:oms8+w1B
ttp://ian-albert.com/misc/gamemaps.php

有名どころのマップ集。デザインの参考にはなるんでない?
07397362006/01/28(土) 20:54:31ID:mw6mWgjC
ttp://dream.my-sv.net/upload/src/up0124.zip
ここまでやってみた。画像はマップ作成ツールのサンプル
ただスクロールがなんかおかしい
当たり判定はuser構造体内のPOINT型mptとmapdata構造体配列でやりたいと思ってるけど実装の仕方がわからなくてグダグダ
マップとか画像はセンスが無いからどうにも・・・
0740名前は開発中のものです。2006/01/29(日) 01:48:00ID:UzEuhqPh
ざっとソース見させてもらったけど、気になる点がいくつか。
仮想BMP、まさか本当にマップファイルの大きさのBMPを用意するのはさすがにまずいと思う。
それからマップチップの画像は一枚にまとめておいたほうが扱いやすいと思う。

struct MapChipData {
POINT src; // マップチップ「「画像」」の開始座標を格納
int type;
}

int MapData[MAP_HEIGHT][MAP_WIDTH]; // ここにマップデータをそのまま読んで番号を格納していく

こういうの用意して、例えば0,0からマップを画面に書きたかったら

for (int y = 0; y < 20; y++) { for (int x = 0; x < 15; x++) {
POINT src = MapChipData[ MapData[y][x] ].src; // これでチップの座標取って
// ここらでsrcを使って裏画面にマップを描画。ソースは省略
}}

あと、初心者で普通のRPGのように滑らかな移動を初めから実装するのは無謀だと思う。
まずは、チップサイズ(この場合32ドット)毎にキャラが移動するように作って
それで、仕組みを理解してから滑らかにスクロールするところを作りこんだほうがいいと思う。

当たり判定については、キャラを実座標で扱っているからごちゃごちゃしてるんだと思う。
例えば右に移動するのを+10ドットとするのではなく、右に+1とする。
そのとき、一緒に当たり判定するとか。

// 右に移動したとき呼ばれたとして、typeで判定かな
if ( MapChipData[ MapData[自キャラのY座標][自キャラのX座標 + 1] ].type == 1 )
{ 自キャラのX座標 ++ }

当たり判定用のマップ作りたい場合はマップデータをintじゃなくて構造体にして詰め込めばいい。と思う(´・ω・`)
0741名前は開発中のものです。2006/01/29(日) 15:34:49ID:Pz5ng5yE
Direct Graphics の描画時の同期(Present()の終了待ち)をタイマーの代わりにしていたけど、
それだと、ウインドウモードでFPSが変わると速度の変化があるよね。

60Hzと75Hzで同じような処理を行うには、75のときに5回に一回飛ばせばいいだけなの?
それだとカクカクしない?
0742名前は開発中のものです。2006/01/29(日) 16:01:50ID:38NWeupe
カクカクする。
でもそれは仕方の無いことだとあきらめてる。
解決策教えてエロい人。

速度を一定に保ちたいなら、1秒間でどのくらい動くかということを考えて
フレームごとの移動量を足していくようにすればいい。
0743名前は開発中のものです。2006/01/29(日) 16:16:20ID:Fm34QVYs
>>740
はじめに数枚のマップチップを張り合わせたbmp画像を読み込んでおき、
struct MapChipData {
 POINT src; // マップチップ「「画像」」の開始座標を格納
 int type;
}mapchipdata[読み込むチップ数]
にマップチッブを張り合わせたbmp内の目的チップの座標とタイプを格納して
マップの再描画が必要になったとき(スクロール時等)にマップチップをメモリデバイスに貼り付け
ということでしょうか?

あと当たり判定の
if ( MapChipData[ MapData[自キャラのY座標][自キャラのX座標 + 1] ].type == 1 )
はMapData[自キャラのY座標/チップサイズ][自キャラのX座標/チップサイズ + 1]ですか?

そろそろGDI卒業してDirectGraphic使いと思って本屋で探したけど2Dからの入門書探しても3Dしかない・・
0744名前は開発中のものです。2006/01/29(日) 16:48:30ID:38NWeupe
自キャラの位置をマップ座標で持ってるなら、32で割る必要なしだと思うが。
そのところは好きに実装すればいいんじゃね?

単にキャラの座標を32倍して保持するか、しないかの差だろ。
歩くたびに割り算するのはあんまり好きじゃないけど、今時のPCならどうでもいいことだろうし。

要は短形で判定する必要はないってことじゃないかね。
1ピクセルが一歩なら別の方法取らなければならんが。
0745名前は開発中のものです。2006/01/29(日) 17:05:54ID:Fm34QVYs
MapData[40][40];に自キャラ座標のmapdata[120][130+1]を要求するとおかしくなると思ったので
キャラの1歩を32ドットとして当たり判定は移動先の座標にブロックがあるかないかで判断すると
キャラ移動時のアニメーションが必要になりますね
その辺りも勉強しておかないと
0746名前は開発中のものです。2006/01/29(日) 17:34:55ID:op7RmHi9
判定方法と、移動時のアニメーションの必要性の有無に因果関係はない。
07477242006/01/29(日) 17:36:03ID:38NWeupe
俺は740のソースしか見ていないから違ってるかもしれんが
「自キャラの座標」は適当に直して使えということではないかな?
俺だったら32倍して持たないけど。

745の二行目以降はよく意味が解らん。アニメーション関係あるか??
0748名前は開発中のものです。2006/01/29(日) 17:50:53ID:Fm34QVYs
>>746-747
ポケモンとかのゲームは1歩が1マスで移動時にアニメーション
同じように1歩を1マスにするとアニメーション使わないと見栄えが悪くなるかなと思って
まだまだそんなこと言ってられるレベルじゃないけど
>「自キャラの座標」は適当に直して使えということではないかな?
なるほど。自キャラの座標は実座標で扱ってたのでマスとして扱ってみます
0749名前は開発中のものです。2006/01/29(日) 17:53:21ID:38NWeupe
勘違いしてほしくないので補足。

/ 32 自体が間違ってるから不要と言ってるのではなくて
まぁ初心者だから、好きなようにやってみるといいんじゃね?
あとから仕組みがわかるだろうさ、という意味。
0750名前は開発中のものです。2006/01/29(日) 18:12:51ID:vc0WpJnf
なんかRPG作りたくなってキターよ
■ このスレッドは過去ログ倉庫に格納されています