C言語何でも質問掲示板


Total hit  今日  昨日  

必ずお読み下さい → 規約と注意事項  アンケートはこちら  エラーで投稿できない方はこちら  過去ログ検索はこちら

 
   格闘ゲームのCPUについ ....   
     ・[54506] パコネコ 
     ・[54515] パコネコ 
     ・[54542] TKOZ 
     ・[54548] Dixq (管理人) 
     ・[54550] Dixq (管理人) 
     ・[54554] パコネコ 
     ・[54558] パコネコ 
     ・[54560] TKOZ 
     ・[54561] パコネコ 
     ・[54566] Dixq (管理人) 
     ・[54567] スキマ妖怪 
     ・[54573] パコネコ 
     ・[54574] パコネコ 
     ・[54586] パコネコ 
     ・[545051276955060] パコネコ 
   音楽が流れない   
     ・[54446] Justy 
     ・[54499] X 
     ・[54559] 夕暮 
   ST-patch   
     ・[54549] ぽこ 
   batファイルの作り方   
     ・[54528] ookami 
     ・[54531] シエル 
     ・[54535] へろり 
     ・[54538] T.O 
   PC-9821Ra40のBIOS部分 ....   
   ポーカーで質問です。   
     ・[54510] たいちう 
     ・[54517] jay 
     ・[54521] しろ 
     ・[54522] toyo 
     ・[54523] toyo 
     ・[54524] しろ 
   野球の得点入力、勝敗 ....   
     ・[54296] MK 
     ・[54298] MK 
     ・[54299] MK 
     ・[54301] たいちう 
     ・[54303] MK 
     ・[54304] シエル 
     ・[54308] たいちう 
     ・[54425] MK 
     ・[54480] MK 
     ・[54481] たいちう 
     ・[54482] シエル 
     ・[54483] たいちう 
     ・[54511] MK 
   マリオ風アクションゲ ....   
     ・[54250] kazuoni 
     ・[54288] TKOZ 
     ・[54289] TKOZ 
     ・[54314] TKOZ 
     ・[54315] TKOZ 
     ・[54491] TKOZ 
     ・[54492] wing 
     ・[54494] TKOZ 
   リプレイデータでキー ....   
     ・[54126] Dixq (管理人) 
     ・[54127] スキマ妖怪 
     ・[54128] Dixq (管理人) 
     ・[54130] シエル 
     ・[54132] Dixq (管理人) 
     ・[54133] Dixq (管理人) 
     ・[54134] Dixq (管理人) 
     ・[54160] スキマ妖怪 
     ・[54161] Dixq (管理人) 
     ・[54163] Dixq (管理人) 
     ・[54167] スキマ妖怪 
     ・[54168] Dixq (管理人) 
     ・[54170] スキマ妖怪 
     ・[54171] Justy 
     ・[54172] Dixq (管理人) 
     ・[54173] Dixq (管理人) 
     ・[54174] スキマ妖怪 
     ・[54175] Justy 
     ・[54176] Dixq (管理人) 
     ・[54177] Justy 
     ・[54179] スキマ妖怪 
     ・[54185] Dixq (管理人) 
     ・[54188] スキマ妖怪 
     ・[54191] レイ 
     ・[54229] Dixq (管理人) 
     ・[54252] レイ 
     ・[54284] スキマ妖怪 
     ・[54489] レイ 
   1つのプロジェクトに2 ....   
     ・[54459] たかぎ 
     ・[54461] たいちう 
     ・[54462] シエル 
     ・[54471] Ultimate 
     ・[54485] softya 
     ・[54486] たかぎ 
     ・[54487] softya 
     ・[54488] たいちう 
   受信時のスピンロック ....   
     ・[54433] シエル 
     ・[54434] shiro4ao 
     ・[54441] Justy 
     ・[54442] shiro4ao 
     ・[54443] Justy 
     ・[54477] shiro4ao 
   パソコン画面を動画で ....   
     ・[54259] fatens 
     ・[54328] Ultimate 
     ・[54333] Dixq (管理人) 
     ・[54346] Ultimate 
     ・[54474] Ma 
     ・[54475] Dixq (管理人) 
   DirectXのウィンドウ切 ....   
     ・[54421] fr 
     ・[54422] toyo 
     ・[54453] 夏天 
   無題   
     ・[54186] Dixq (管理人) 
     ・[54187] Tatu 
     ・[54198] たろう 
     ・[54203] Tatu 
     ・[54243] たろう 
     ・[54269] たろう 
     ・[54283] Tatu 
     ・[54310] たろう 
     ・[54313] たろう 
     ・[54317] たいちう 
     ・[54322] たろう 
     ・[54329] たろう 
     ・[54332] たろう 
     ・[54363] Tatu 
     ・[54371] たろう 
     ・[54372] たろう 
     ・[54374] たろう 
     ・[54383] Tatu 
     ・[54393] たろう 
     ・[54395] Tatu 
     ・[54397] たろう 
     ・[54415] Tatu 
     ・[54424] たろう 
     ・[54426] Tatu 
     ・[54439] たろう 
     ・[54444] Tatu 
     ・[54445] たろう 
   ifやswitchを使わない ....   
     ・[54399] たかぎ 
     ・[54400] なんちゃってプログラマ 
     ・[54406] YuO 
     ・[54431] なんちゃってプログラマ 
     ・[54436] Justy 
   画像が表示されない   
     ・[54414] a 
     ・[54429] シエル 
   コマンドラインからス ....   
     ・[54143] たかぎ 
     ・[54146] shiro4ao 
     ・[54151] たかぎ 
     ・[54164] shiro4ao 
     ・[54182] shiro4ao 
     ・[54183] シエル 
     ・[54184] shiro4ao 
     ・[54233] シエル 
     ・[54428] shiro4ao 
   C++の質問です。   
     ・[54292] シエル 
     ・[54293] TKOZ 
     ・[54302] softya 
     ・[54419] suz45 
   10個の配列から被らな ....   
     ・[54367] たかぎ 
     ・[54369] MNS 
     ・[54370] シエル 
     ・[54376] ideyan 
     ・[54378] シエル 
     ・[54385] ideyan 
     ・[54413] めるぽん 
   2D格闘のアニメーショ ....   
     ・[54409] JIN 
   if文などの条件式につ ....   
     ・[54323] たいちう 
     ・[54331] しろ 
     ・[54356] Ultimate 
     ・[54362] MNS 
     ・[54377] しろ 
     ・[54391] たいちう 
     ・[54392] ぽこ 
     ・[54394] box 
     ・[54404] しろ 
   C言語のリストで分から ....   
     ・[54386] たいちう 
     ・[54387] Roi 
     ・[54390] たいちう 
   C++についての質問   
     ・[54350] シエル 
     ・[54351] y 
     ・[54353] 初級者 
     ・[54355] シエル 
     ・[54361] Dixq (管理人) 
     ・[54373] 組木紙織 
     ・[54379] たかぎ 
     ・[54382] 組木紙織 
     ・[54389] たかぎ 
   スーパーマリコ3を作 ....   
     ・[54325] wing 
     ・[54365] ぽこ 
     ・[54366] wing 
     ・[54368] Tatu 
     ・[54380] wing 
   三角関数で弾幕(3)   
     ・[54335] シエル 
     ・[54336] Ultimate 
     ・[54338] シエル 
     ・[54339] シエル 
     ・[54340] Ultimate 
     ・[54341] Ultimate 
     ・[54342] Ultimate 
     ・[54343] シエル 
     ・[54344] ROM 
     ・[54345] ROM 
     ・[54347] シエル 
     ・[54348] シエル 
     ・[54349] Ultimate 
     ・[54352] Ultimate 
     ・[54354] Ultimate 
     ・[54357] シエル 
     ・[54360] Ultimate 
   DXライブラリの通信関 ....   
     ・[54297] 白い時空 
     ・[54300] 山崎 
     ・[54359] みかみ 
   GetHitKeyStateAll_2と ....   
     ・[53935] fatens 
     ・[53939] Dixq (管理人) 
     ・[53971] kiri 
     ・[53973] fatens 
     ・[53978] kiri 
     ・[54047] fatens 
     ・[54088] Dixq (管理人) 
     ・[54260] kiri 
     ・[54262] fatens 
     ・[54285] kiri 
     ・[54291] fatens 
     ・[54358] kiri 
   アクションゲームの移 ....   
     ・[54294] TKOZ 
     ・[54307] たろう 
     ・[54309] たいちう 
     ・[54311] たろう 
     ・[54312] たいちう 
     ・[54316] シエル 
     ・[54318] たろう 
     ・[54321] たいちう 
     ・[54324] たろう 
     ・[54326] softya 
     ・[54330] dic 
   同時に複数録音するに ....   
     ・[54319] 爺プログラマー  
   みょん弾幕で見られる ....   
     ・[54280] jay 
     ・[54281] y 
     ・[54286] Justy 
     ・[54305] ft 
   メッセージボックスに ....   
     ・[54201] シエル 
     ・[54205] kai 
     ・[54207] シエル 
     ・[54209] シエル 
     ・[54213] kai 
     ・[54217] シエル 
     ・[54266] kai 
     ・[54270] 白い時空 
     ・[54271] シエル 
     ・[54275] kai 
     ・[54277] シエル 
     ・[54278] シエル 
     ・[54279] kai 
   ポインタ変数について   
     ・[54261] prester 
     ・[54263] box 
     ・[54276] シエル 
   メニューバー   
     ・[54050] a 
     ・[54054] 深黒 
     ・[54152] a 
     ・[54154] シエル 
     ・[54156] Justy 
     ・[54165] 深黒 
     ・[54180] Justy 
     ・[54220] 深黒 
     ・[54222] シエル 
     ・[54234] Justy 
     ・[54240] a 
     ・[54246] 深黒 
     ・[54249] はね 
     ・[54257] Justy 
     ・[54258] 白い時空 
     ・[54264] 深黒 
     ・[54265] はね 
     ・[54272] fatens 
     ・[54273] シエル 

Name: パコネコ  ..かけだし(1,025ポイント)   Date: 2010/06/16(水) 23:35   No:54505       
Title: 格闘ゲームのCPUについて    
スタディCというものを使ってC言語でゲームを作っているのですが・・・
グラフィックは友達に頼んでいるのですが、
自分のジャンプと攻撃1と2(1はコンボ3まで、2は遠距離)と移動
というところまでは作りました。
ですが敵の行動を決めることがなかなかできません
条件として思い浮かぶのはHPの量を比べること、相手との位置関係(近いか遠いか)ぐらいです。
プログラムについてというより、今は考え方についてが知りたいです。
というのもプログラムの形に仕上げれるところまで今のままでは持っていけないからです。
どなたか助けていただけませんか?


261ポイント を手に入れた。


Name: パコネコ  ..かけだし(1,184ポイント)   Date: 2010/06/16(水) 23:40   No:54506     
Title: Re:格闘ゲームのCPUについて    
まだできてませんがガードについてもいいですか?
自分が攻撃してから相手はガードをするのでしょうか?
でもそれだとすべてガードされることになる気がします。
ランダムに攻撃をうけさせればいいのでしょうか?
だいたいの確率もお聞きしてもよろしいでしょうか?
たとえば:50%もしくは2回に一回ぐらい
だいたいで結構ですので参考のために教えてください


159ポイント を手に入れた。

Name: パコネコ  ..かけだし(1,196ポイント)   Date: 2010/06/17(木) 00:41   No:54515     
Title: Re:格闘ゲームのCPUについて    
上のもの以外でも
「格闘ゲームならこういうものが必要」などもありましたら
よろしくお願いします。
連続でどんどん質問増やしてすいません
余談ですが
ちなみにキャラが小さいサイズでやっているのでヨコスクのアクションに近い形になってます。
ワイはそう思わないけど友達に言われて・・・


12ポイント を手に入れた。

Name: TKOZ  ..熟練のプログラマー(63,773ポイント)   Date: 2010/06/17(木) 18:26   No:54542     
Title: Re:格闘ゲームのCPUについて    
まず、格闘ゲームを作るなら、確率を計算する関数が必要ですね。

int GetPersent(int per,int num);//per%の確率でnumが出る

あと、格闘ゲームなら入力コマンドを判定する関数が必要ですね。
#define COUNT 200
#define MAX_KEY 9

typedef struct Comm{
   int type;//種類
   int usechara;//使うキャラ
   unsigned char commbuff[COUNT];//入力バッファ
   unsigned char time;//時間
   unsigned char key[MAX_KEY];
}Comm;

void CheckCommand(Comm k);//入力構造体からコマンドを判定する関数

それから、キャラクター同士の当たり判定をする関数が必要です。
typedef struct NRECT{
    int left;
    int top;
    int right;
    int bottom;
}NRECT;

int CheckHitAttack(NRECT attackA,NRECT diffenceA,NRECT attackB,NRECT diffenceB);
//1Pキャラの攻撃矩形ゾーンと防御矩形ゾーン、2Pキャラの攻撃矩形ゾーンと防御矩形ゾーン
//の当たり判定


あと、なんといっても2Dの格闘ゲームはアニメーションです。
キャラがアニメーションする関数を作ると良いかもしれません。

typedef struct ANIM{
   Comm A;//入力キーのバッファーなど
   double time;//経過時間
   int counter;//カウンター
   //...他に必要なのあるかな?
}ANIM;

int CharacterAnimationWorks(ANIM chara);//アニメーション用関数

以上、必要な関数の定義しか書いてませんが、参考になれば幸いです。


337ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,214,766ポイント)   Date: 2010/06/17(木) 20:21   No:54548     
Title: Re:格闘ゲームのCPUについて    
Study C!
懐かしい・・。
これ私が高校の頃からありました。



まずどの程度のクオリティを求めるかですよね。
まだ経験が無いなら単純に確率のみで決定してもいいんじゃないでしょうか。

でもそれだと面白くなくなってくると思います。
例えばストリートファイターでたとえるなら、
ジャンプで入ってきた相手の対空用に昇竜拳を出そうとしたのに、コマンドがうまく入らなくて波動拳になってしまったとか、そういう時は楽にそのまま飛び込んで連続技に繋げられますよね。
飛び込んだら何かしら対空策を施してくるだろうに確率で計算していたら「そこで棒立ち?」とか「そこでその技?」みたいな違和感が出てきてしまうと思います。
そうではなく、「クク・・昇竜拳出し損ねたな!」みたいに思える"人間とプレイしている感"を出したいですよね。

しかし、その全てのパターンに違和感無く条件分岐させることもまた困難だと思います。
こういう場合はゴリゴリプログラムを書く方法より、沢山のサンプルから学習させる方が手っ取り早かったりするかもしれません。
ものすごい量のサンプルが必要ですが、何度もプレイして、そのプレイデータからプレイヤーはどう動き、コマンドするかを覚えさせてそれに合ったコマンドをさせるとか、
そうすると自然な動きになるかもしれません。
自然な動きになるように学習させるのは難しいかもしれませんが。

まずは条件分岐でどこまで出来るかやってみて、それで自然な動きにならなければ学習という方面を視野にいれて制作をしてみてはいかがでしょう。


2倍のポイントを手に入れた! 1,030ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,214,718ポイント)   Date: 2010/06/17(木) 20:22   No:54550     
Title: Re:格闘ゲームのCPUについて    
後、自然界の現象に正規分布は欠かせませんよね。
確率を計算する関数と一緒に、正規分布で確率を計算する関数も作ると良いと思います。


48ポイント を落としてしまった。

Name: パコネコ  ..かけだし(1,359ポイント)   Date: 2010/06/17(木) 20:45   No:54554     
Title: Re:格闘ゲームのCPUについて    
ありがとうございます
かくりつを使うものは「rand()%」でランダム&if文を使うと言った方法しか知りません…
TKOZさんのやつってスタディCで使えますか?
あ、使えなくても勉強になるのでありがたいんですがとりあえず使えるかだけ…確認してもいいですか?
サンプルの使用&記憶はどのようにすればいいと思いますか?
ファイルに保存していくとかですかね。
ファイルはあまり得意ではないですがこの機会に使いたいですね。
他にも応用が効きそうですし…


163ポイント を手に入れた。

Name: パコネコ  ..かけだし(1,310ポイント)   Date: 2010/06/17(木) 21:12   No:54558     
Title: Re:格闘ゲームのCPUについて    
サンプルの使用と書いてますが学習させるにはどうさせればいいのか?という意味です
言葉が足りなくてごめんなさい


49ポイント を落としてしまった。

Name: TKOZ  ..熟練のプログラマー(63,799ポイント)   Date: 2010/06/17(木) 21:57   No:54560     
Title: Re:格闘ゲームのCPUについて    
学習というのは、パコネコさんがC言語を学習するという意味でしょうか?
それとも、他の意味でしょうか?


26ポイント を手に入れた。

Name: パコネコ  ..かけだし(1,364ポイント)   Date: 2010/06/17(木) 22:03   No:54561     
Title: Re:格闘ゲームのCPUについて    
>こういう場合はゴリゴリプログラムを書く方法より、沢山のサンプルから学習させる方が手っ取り早かったり>するかもしれません。 
>ものすごい量のサンプルが必要ですが、何度もプレイして、そのプレイデータからプレイヤーはどう動き、コ>マンドするかを覚えさせてそれに合ったコマンドをさせるとか、 
これについてですね
難しそうです・・・


54ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,216,299ポイント)   Date: 2010/06/17(木) 23:18   No:54566     
Title: Re:格闘ゲームのCPUについて    
とりあえず単純な確率で動くAIから作ってみてはどうでしょう?
studyCを使った事は無いので、よく知りませんが、
C言語として使えるべき物が使えないコンパイラなら使うのをやめた方がいいと思います。

出来るかどうか試しに書いてみてはどうでしょう。


#include <stdio.h> 
#include <stdlib.h>
#include <time.h>

int main(){
    srand((unsigned) time(NULL));
    printf("%d",rand());
    return 0; 
}


・・って今見てみたらインタプリタなのですね。
C言語をきちんと勉強するならVisualC++などのコンパイラでコンパイルした方がいいのではないでしょうか?
画像や音楽を簡単に扱いたいならうちのHPでも紹介しているDXライブラリを使うという手があります。


211ポイント を手に入れた。

Name: スキマ妖怪  ..かけだし(1,698ポイント)   Date: 2010/06/17(木) 23:18   No:54567     
Title: Re:格闘ゲームのCPUについて    
たぶん機械学習のことですね。
この中の遺伝的アルゴリズムとか、ニューラルネットワークとか

http://ja.wikipedia.org/wiki/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92


…で機械学習って何ぞ?となると思います。
面白いものを見つけたのでペタリ

体験できるサンプルです。
Trainingモードで何週かしてあげると(少ないと壁にぶつかったりします)
AIモードでしっかり学習してうまく移動できることが確認できると思います。

http://kusaimeshi.vs.land.to/html/gocap.html


> 難しそうです・・・

かなり難しい部類に入ると思います。


229ポイント を手に入れた。

Name: パコネコ  ..かけだし(1,481ポイント)   Date: 2010/06/18(金) 00:02   No:54573     
Title: Re:格闘ゲームのCPUについて    
基本的には使えるはず…使えないのはほかのやつの固有のやつ
できないことはワイが知ってる範囲では、画像の回転や縮小拡大
ですね
ただワイが知らなかったのでお聞きしました。
DXライブラリはここの?やつで勉強させてもらってます。
ただ今はまだノートに書き写している段階です。
移し終わってからゲームなどのプログラムを作りたいです
今は基礎編を写し終わったとこでしょうか…


117ポイント を手に入れた。

Name: パコネコ  ..かけだし(1,509ポイント)   Date: 2010/06/18(金) 00:04   No:54574     
Title: Re:格闘ゲームのCPUについて    
>#include <stdio.h>  
>#include <stdlib.h> 
>#include <time.h> 

>int main(){ 
>    srand((unsigned) time(NULL)); 
>   printf("%d",rand()); 
>    return 0;  
>} 
はきちっと使えました


28ポイント を手に入れた。

Name: パコネコ  ..かけだし(1,575ポイント)   Date: 2010/06/18(金) 00:29   No:54586     
Title: Re:格闘ゲームのCPUについて    
スキマ妖怪さんに見せていただいた
AIのやつ(車の学習であってますかね?)すごく面白いですね
こんなプログラム作りたいな〜と思いました。
今は、まだ難しそうなのでもっといろんな関数覚えてからになりそうです。


66ポイント を手に入れた。

Name: パコネコ   Date: 2010/06/19(土) 22:44   No:545051276955060 解決!     
Title: Re:格闘ゲームのCPUについて    
確率による行動選択にします
皆さんありがとうございました
また困ったことがありましたら皆さんの力を貸してもらいたいと思います。




Name: X  ..かけだし(1,330ポイント)   Date: 2010/06/15(火) 20:50   No:54435       
Title: 音楽が流れない    
こんにちは、Xです。
今回RPGを頑張って作っているところですが、PlaySoundMem関数を使って、再生しようとしたところ、
PlaySoundMemを先にすると画像が表示されなく、
DrawGraphを先にすると音楽が流れません。
どうすればいいでしょうか? 何かあれば教えてくださいm(__)m

OS:WindowsXP HomeEdition

Visual C++ 2008 ExpressEdition

↓-------ソースです-------↓

#include "DxLib.h"
#include "../head/struct.h"
#include "../head/function.h"
#include "../head/define.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        

    int ben[16];
    char Key[256];
    ch_t ch;
    back_t bc;
    music_t ms;

    bc.x = 0;
    bc.y = 0;


    ch.x = 320;
    ch.y = 320;
    ch.walking_flag = 0;
    ch.muki = 3;

    

    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; 
 
  
    SetDrawScreen( DX_SCREEN_BACK ) ;                                             
    LoadDivGraph("dat/img/ben.png",16,4,4,32,32,ben);

    ms.music = LoadSoundMem("dat/bgm/field_01.mp3");
    bc.img = LoadGraph("dat/img/bk_ground.png");

    while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){

                


if(ch.x%32==0 && ch.y%32==0){        
            ch.walking_flag=1;       
            if     ( Key[ KEY_INPUT_UP   ]  == 1 )  
                    ch.muki=0;     
            else if( Key[ KEY_INPUT_LEFT ]  == 1 ) 
                    ch.muki=1;         
            else if( Key[ KEY_INPUT_DOWN ]  == 1 )  
                    ch.muki=2;        
            else if( Key[ KEY_INPUT_RIGHT]  == 1 )  
                    ch.muki=3;         
            else                           
                    ch.walking_flag=0; 

            if      (ch.walking_flag == 1)
                if(can_or_cannot(ch.x,ch.y,ch.muki)==1)//行き先が歩けないなら
                    ch.walking_flag=0;                  //歩かないフラグを立てる。

}
        if(ch.walking_flag==1){      
            if     (ch.muki==0)   {    
                    ch.y--;
                    bc.y++;
            }
            else if(ch.muki==1)  {      
                    ch.x--;
                    bc.x++;
            }
            else if(ch.muki==2)   {   
                    ch.y++;
                    bc.y--;
            }
            else if(ch.muki==3)    {    
                    ch.x++;
                    bc.x--;
            }
        }

        ch.img = ben[(ch.x % 32 +  ch.y % 32)/8 + ch.muki * 4];
        

        PlaySoundMem(ms.music,DX_PLAYTYPE_BACK);

        DrawGraph( bc.x , bc.y ,bc.img ,FALSE);
        DrawGraph( GetCenterX, GetCenterY, ch.img,TRUE);
      
        
        ScreenFlip();
          
    }
 
    DxLib_End();
    return 0;
編集済み


803ポイント を手に入れた。


Name: Justy  ..伝説なるハッカー(545,838ポイント)   Date: 2010/06/15(火) 22:14   No:54446     
Title: Re:音楽が流れない    
 PlaySoundMemを毎ループ呼び出さないで、再生を開始したいそのタイミングのみ呼び出すよう修正してみて下さい。

16ポイント を手に入れた。

Name: X  ..かけだし(1,370ポイント)   Date: 2010/06/16(水) 20:41   No:54499     
Title: Re:音楽が流れない    
Justyさんの言われたとおりに、毎ループ呼び出さないようにしてみると、
うまく画像も音楽も流せました^^
Justyさん、ありがとうございました!!


40ポイント を手に入れた。

Name: 夕暮  ..かけだし(1,033ポイント)   Date: 2010/06/17(木) 21:12   No:54559     
Title: Re:音楽が流れない    
解決したのでしたら良かったのですが
if(読み込んだ音が流れていなかったら) ならす
といった風にしてみてはいかがでしょうか?

DXライブラリに判定する関数があったはずです。 


69ポイント を手に入れた。



Name: taka  ..ぴよぴよ(1ポイント)   Date: 2010/06/17(木) 17:55   No:54540       
Title: ST-patch    
ST-patch特徴量を抽出するプログラムを作りたいのですが、どのようにすればよいのでしょうか。

1ポイント を手に入れた。


Name: ぽこ  ..上級者(15,436ポイント)   Date: 2010/06/17(木) 20:22   No:54549     
Title: Re:ST-patch    
> ST-patch特徴量を抽出するプログラムを作りたいのですが、どのようにすればよいのでしょうか。

サラッと調べてみましたが、画像認識系のアルゴリズムですかね?
この質問内容ですと、「ST-patch特徴量を抽出する処理をソースコードに落として、
コンパイルすれば良いんじゃないですか?」としか答えようが無いですよ。

も少しまともな答えを期待するなら、少なくとも
「ST-patch特徴量とは何か?」「入力データの形式は何か?」「期待する出力は何か?」を
「takaさんの言葉」で説明する必要がありますよ。


141ポイント を手に入れた。



Name: T.O  ..ぴよぴよ(104ポイント)   Date: 2010/06/17(木) 11:39   No:54527       
Title: batファイルの作り方    
あるフォルダの中に(たとえばc:\AB)
C++のソースプログラム(.cpp)が20個とコンパイラ(bcc32.exe)があるとします。
コンパイラ (bcc32.exe)を使って一度にコンパイルするために  
batファイル作ってみましたがうまい具合に動作しません。
どこを手直しすればよいのでしょうか。
------------------------------------------------
@  echo  off
c:
:ZZ
while  (x<=20)   /*ファイル数20個に達するまで*/
start  /b /wait  c:\AB\bcc32.exe   *.cpp  /*コンパイル*/
x=x+1
goto  ZZ   /*ZZへ飛ぶ*/
end


104ポイント を手に入れた。


Name: ookami  ..上級者(24,671ポイント)   Date: 2010/06/17(木) 12:15   No:54528     
Title: Re:batファイルの作り方    
いろいろと不明点がありますがとりあえず、
バッチで繰り返し処理なら for 文だと思います。
http://ykr414.com/dos/dos05.html#07


34ポイント を手に入れた。

Name: シエル  ..中級者(9,511ポイント)   Date: 2010/06/17(木) 13:27   No:54531     
Title: Re:batファイルの作り方    
バッチってwhile文って使えたかな?(忘れた)

うまい具合に動作しないとは、どのような動作になってしまうのですか?


35ポイント を手に入れた。

Name: へろり  ..中級者(9,625ポイント)   Date: 2010/06/17(木) 14:05   No:54535     
Title: Re:batファイルの作り方    
質問の趣旨に反しますが、makeコマンド使えばいいんじゃないんですか?
確かBCCにも付属しているはずです。

便利ですよ。


44ポイント を手に入れた。

Name: T.O  ..ぴよぴよ(53ポイント)   Date: 2010/06/17(木) 15:40   No:54538 解決!     
Title: Re:batファイルの作り方    
ookamiさん、シエルさん、へろりさん各氏に感謝します。
FORを使ってなんとかできそうです。
ありがとうございました。


53ポイント を手に入れた。



Name:  ..ぴよぴよ(389ポイント)   Date: 2010/06/17(木) 13:29   No:54532       
Title: PC-9821Ra40のBIOS部分の質問    
 PC-9821Ra40のITFの解析を行っています。そして、PC-98シリーズは全てサポートが
無くなると思い、システムの立ち上げからプログラムを作ってゆけばよいと思い、特に
windowsアクセラレータの部分がビデオチップの制御の仕方が分からないので、この二つの意味で
BIOSとITFそしてドライバの解析を行っています。やっとちらほらフラッシュROMのソフト的焼き方
の方法の一部分も公表しかけています。最終的にROM焼きまで行いたいと思っていますが、その前に
BIOS開発が必要だと考えています。
 そこで質問しますが、ITFの解析で、システムがリセットして立ち上げて、FD80:0000に飛んで、PCI
の一部を初期化してITFに移行したら直ぐにF800:4000に飛ぶとの話を伺っています。そして、
バンクメモリ4のITFROMから動くとの話となっています。まず一つはこの認識が正しいかどうかと
言う事と、そして、まりもさんのGETITFソフトを使ってバンク4のITFバイナリファイルを保存し、
そのバイナリファイルを上の4000番地を解析したら、CPUの命令が正しく動くかどうかの確認から
始まり、そして画面表示のグラフィックを98グラフィックにし、そしたら、IOアドレスが0A09h,
0A0Ah, 18F0h, 18F2hが出てきます。0A09hでレジスタを設定し、0A0Ahそのレジスタにデータの
出し入れをしている感じのアセンブラ命令です。同じように18F0hにもレジスタを設定し、そして
18F2hによってデータの出し入れを行っています。レジスタの内容の意味と制御内容が分からない
のですが。HPを見ると0A09hで解析した内容が出てきますが、その設定レジスタ番号とBIOSの内容と
違います。それ以外は、資料を探しても見つかりません。更にIOアドレス610hの意味も分からない
のです。一応、exdeb等のデバッガを使ってITFに書いてある内容と同じ事をして見たが、見た目では
変化がありませんが、何を起こしたのかちょっと分からないのです。
 このあたりに詳しい人から回答を頂きたいが。


389ポイント を手に入れた。




Name: しろ  ..中級者(12,435ポイント)   Date: 2010/06/16(水) 21:02   No:54500       
Title: ポーカーで質問です。    
知り合いがポーカー作ると勉強になるよ、教えてくれたのでポーカーのプログラムを作っています。

とりあえずジョーカーなし、交換なしでカードが出て、役を判定させるプログラムを作ったのですがうまく動作しません。(役を判定させるif文の中に入りません)

以下そのプログラムですが、プログラムを記載する前に注意点としていくつか述べておくと

@現状すべてmain関数の中に書いています。
(あとあと全体像ができてきたら、役を判定させる関数などは外部関数にする予定です。いまはとりあえず頭から書いています)

A長いプログラムを全部ここに乗せるのもあれなので、ワンペアの部分だけ取り出しています。

Bカード5種類をp[j]=rand()%52としていますが、これだとカードがかぶるおそれがあるので、もしかぶった場合はやり直し、というプログラムを組んでいます。ただ、無限にやり直しをしてしまうと、プログラムが先に進まないので、2000回繰り返した場合(2000回連続で5種類のカードのうちいずれかが被った場合)自動的にプログラムが終了するようにしています。5種類取り出した場合、1回の試行で約0.18くらいの確率で数字がかぶってしまうので、2000回連続で数字がかぶる確率は(0.0324)^1000となりはほぼ0になるので、とりあえずはこれで放置しています。(計算は概算です。有効数字とか考えてないので、実際は結構異なると思います)以下プログラムです。

C役の判定は、カードを小さい順にソートをして、隣り合う数字をもとに判定しています。

---------------------


#include<stdio.h>
#include<stdlib.h>
#include<time.h>

typedef struct Poker{

    int card[52];
    char mark[52];

}Poker;


int main(void){

    Poker num;
    int i=0;    //for文用
    int j=0;    //for文用
    int k=0;    //for文用
    int l=0;    //for文用
    int m=0;    //for文用
    int n=0;    //for文用
    int tmp;    //配列ソート用
    int p[5];    //カード選択用
    int max=1;    //error防止用
    int yaku=0;    //カードの役ループ用
    
    srand((unsigned)time(NULL));

    for(i=0;i<13;i++){    

        num.card[i]=i+1;
        num.card[i+13]=i+1;
        num.card[i+26]=i+1;
        num.card[i+39]=i+1;
        num.mark[i]='s';
        num.mark[i+13]='d';
        num.mark[i+26]='h';
        num.mark[i+39]='c';
    }

    for(j=0;j<5;j++){

        p[j]=rand()%52;
        max++;    //for文無限回繰り返しを防ぐ
        
        if(j==4){
            if(p[0]==p[1]||p[0]==p[2]||p[0]==p[3]||p[0]==p[4]||p[1]==p[2]||p[1]==p[3]||p[1]==p[4]||p[2]==p[3]||p[2]==p[4]||p[3]==p[4]){
                j=-1;//同じカードかあれば、j=0となりやりなおし(j=-1なのはループの最後にj++があるから)
            }
        }
        if(max==10000)
            break;
    }

    if(max!=10000){
    
        for(k=0;k<5;k++){

            printf("%c-%d\n",num.mark[p[k]],num.card[p[k]]);
    
        }    


    

    for(l=0;l<4;l++){    //カードのソート
        for(m=l;m<5;m++){
            if((p[m]%13)<=(p[l]%13)){
                tmp=p[m];
                p[m]=p[l];
                p[l]=tmp;
            }
        }


    }//カードのソートを終了


    if((yaku=0)&&(((p[0]%13)==(p[1]%13))||((p[1]%13)==(p[2]%13))||((p[2]%13)==(p[3]%13))||((p[3]%13)==(p[4]%13)))){
        yaku=1;
        printf("ワンペア\n");
    }//ワンペア

    }    //if(max!=10000の終了)


    return 0;
}

------------------------

質問としては
@なぜif文の中に入らないのか?
(あるいは入ってはいるが条件式などに誤りがある)

Aはじめにカードを5種類だす際に、もっとうまいプログラムはないのか?(上のプログラムは無限ループを防止するための苦肉の策なので)

B5種類のカードがの中に同じものが含まれることが、そもそもずっと続くなどありえない(確率的にはありえるが、0に収束するので)無限ループを防止するプログラムなど書く必要がない?

他のプログラム等は全く見ないで挑戦していて、かなりへたくそなプログラムだとは思いますが、いろいろと教えてもらえるとうれしいです。

よろしくお願いいたします。


1,514ポイント を手に入れた。


Name: たいちう  ..比類無きプログラマー(96,552ポイント)   Date: 2010/06/17(木) 00:03   No:54510     
Title: Re:ポーカーで質問です。    
if ((yaku=0)&& ... ){
    yaku=1;
    printf("ワンペア\n");
}//ワンペア

丁寧に見てないですが、これでは永久に無理でしょう。
もしかしてyaku == 0ではないですか?

初心者がこれに自分で気付くには、「デバッグ」という事をすると良いかもしれません。


2ポイント を手に入れた。

Name: jay  ..上級者(17,186ポイント)   Date: 2010/06/17(木) 01:28   No:54517     
Title: Re:ポーカーで質問です。    
安価ミスですね、もっと注意深くコードを見ることと
もう少し見やすいコードを意識するといいですよ

とりあえず間違いの指摘をば


if((yaku=0)&&...
となっていますが、
yaku=0
だと”yaku”に”0”を代入する結果になりますね。

if((yaku==0)&&...

にすればif文は動き出すと思います、他に問題がなければのお話ですけどね。


139ポイント を手に入れた。

Name: しろ  ..中級者(12,558ポイント)   Date: 2010/06/17(木) 06:02   No:54521     
Title: Re:ポーカーで質問です。    
そうですね。直すとうまく動作しました。

こんなことで質問するのは情けない……

回答をしてくださったお二方、ありがとうございました。

5種類のカードを最初に出すところも、もっとうまいプログラミング法があればご教授よろしくお願いいたします。


123ポイント を手に入れた。

Name: toyo  ..熟練のプログラマー(49,548ポイント)   Date: 2010/06/17(木) 06:26   No:54522     
Title: Re:ポーカーで質問です。    
カードのシャッフルは文字通りシャッフルアルゴリズムを使えばいいですよ
0-51まで連続した配列を用意して乱数で2つの数値を取得
その2つの数値をインデックスとする配列の中身を入れ替える
以上の操作を何回か繰り返す
何回繰り返すのが適当かがわからないのですが100回もやればいいでしょう
配列の最初の5個を取り出して終わり


139ポイント を手に入れた。

Name: toyo  ..熟練のプログラマー(49,614ポイント)   Date: 2010/06/17(木) 07:51   No:54523     
Title: Re:ポーカーで質問です。    
適当ではいけないなと検索しましたがこの方法も良くないようですね
http://ray.sakura.ne.jp/tips/shaffle.html
こちらに解説があるのでどうぞ


66ポイント を手に入れた。

Name: しろ  ..中級者(12,614ポイント)   Date: 2010/06/17(木) 08:08   No:54524 解決!     
Title: Re:ポーカーで質問です。    
>toyoさん

ご回答とうもありがとうございます。

URL先を読んでみます。もしわからなかったらまた質問させていただきます。よろしくお願いいたします。


56ポイント を手に入れた。



Name: MK  ..ぴよぴよ(763ポイント)   Date: 2010/06/14(月) 09:41   No:54295       
Title: 野球の得点入力、勝敗出力    
現在野球の9回表裏まで得点を入力し、それを計算させて勝敗またはドローを出力するプログラムを作成しましたが、より細かくしようと
1.得点を横に並べ(スコアボード)、9回表の時点で後攻が勝っていたら9回裏はなし。
2.延長をありにする(一定回でも同得点だとドロー)
3.コールドあり
を加えたいのですが「1.」のスコアボードでは数値を横に並べるのはprintfではゴチャゴチャしたプログラムになってしまいますし、9回裏をなしにするのは表の時点で先攻<後攻で裏の回だけループから外す。
など、正しいかはわかりませんが頭では浮かんでもプログラムに直せません;;;
組み立て方の説明をしていただけないでしょうか。よろしくお願いいたします。


307ポイント を手に入れた。


Name: MK  ..ぴよぴよ(804ポイント)   Date: 2010/06/14(月) 09:47   No:54296     
Title: Re:野球の得点入力、勝敗出力    
余計な関数もあるかと思いますが
ssum 先攻
ksum 後攻
inn   イニング
です。


41ポイント を手に入れた。

Name: MK  ..ぴよぴよ(833ポイント)   Date: 2010/06/14(月) 10:29   No:54298     
Title: Re:野球の得点入力、勝敗出力    
9回裏をなしにするプログラムをやっていますが1回表を入力しただけで出力がおかしくなってしまいます 編集済み

29ポイント を手に入れた。

Name: MK  ..ぴよぴよ(860ポイント)   Date: 2010/06/14(月) 10:43   No:54299     
Title: Re:野球の得点入力、勝敗出力    
先攻<後攻の場合9回裏をなしにするプログラムは完成しました^^

27ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(94,816ポイント)   Date: 2010/06/14(月) 11:08   No:54301     
Title: Re:野球の得点入力、勝敗出力    
> 「1.」のスコアボードでは数値を横に並べるのはprintfではゴチャゴチャしたプログラムになってしまいますし、

ゴチャゴチャしててもいいので、まずは作って添付してください。
全部できないならできるところまでを。
それからならゴチャゴチャをどう整理したら良いかを答えられると思います。


69ポイント を手に入れた。

Name: MK  ..かけだし(1,022ポイント)   Date: 2010/06/14(月) 12:14   No:54303     
Title: Re:延長    
スコアの表示はなんとかできました
次に18回までの延長をやっています。

9回裏(inn 18)の時点で先攻後攻が同点なら新たに18回(inn 36)までを繰り返せばできると思ったので
while(inn<18)のループが終わり、同点なら更にwhile(inn<36)を繰り返そうとやってみましたが詰ってしまいました。
どういった手順を踏めば延長の表示ができるのでしょうか


162ポイント を手に入れた。

Name: シエル  ..初心者(8,047ポイント)   Date: 2010/06/14(月) 12:16   No:54304     
Title: Re:延長    
サヨナラ勝ちはないのかぁ

9ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(94,925ポイント)   Date: 2010/06/14(月) 13:07   No:54308     
Title: Re:延長    
18回まで扱いたいならば、runの配列の宣言で要素数を増やさないと。

> どういった手順を踏めば延長の表示ができるのでしょうか

どのような表示をしたいのかわかりませんが、
本来野球は18回まで行われると考えてはどうでしょうか?
その上で、9回以降に点差があればそこで試合終了とする、と。


109ポイント を手に入れた。

Name: MK  ..かけだし(1,051ポイント)   Date: 2010/06/15(火) 18:45   No:54425 解決!     
Title: Re:延長    
>>たいちうさん
できました^^
少し深く考え過ぎていたようです。
ありがとうございました


29ポイント を手に入れた。

Name: MK  ..かけだし(1,161ポイント)   Date: 2010/06/16(水) 11:15   No:54480     
Title: Re:延長    
解決としてしまいまいたが、完成したプログラムの確認をしていただけないでしょうか。
もしオカシイ部分やプログラムをもっと簡潔にできるようでしたらご指摘お願いいたします。


・先攻後攻の順で得点を入力し、合計の計算やスコアボード、勝敗の表示
・9回裏、延長は18回まで
・10点差でコールド



110ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(96,333ポイント)   Date: 2010/06/16(水) 11:39   No:54481     
Title: Re:延長    
好みの問題でもありますが、私ならばinnは1〜18の範囲とします。
そしてforループにします。
for (inn = 1; inn <= 18; inn++) { ... }
当然runの添え字として使うときは1を引きます。

実際の野球でのイニングの扱いに合わせるか、
配列の添え字の都合に合わせるかですが、
この場合は前者のほうがプログラムを理解しやすいと思いますので。
(配列を0〜18まで用意して0を使わないという方法もあります。お好みでどうぞ。)

動作確認は面倒なので私はパス。個人的には甘えすぎじゃないかと思います。
その他気付いた点は、、、
・配列を初期化する
・演算子+=を使う
・absを使う
・インデントをそろえる

これらが直ったら、更に指摘したくなることもあるかもしれません。


203ポイント を手に入れた。

Name: シエル  ..中級者(9,355ポイント)   Date: 2010/06/16(水) 11:48   No:54482     
Title: Re:延長    
数字以外の文字を入力したら試合終了しちゃうことかな。

15ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(96,414ポイント)   Date: 2010/06/16(水) 12:59   No:54483     
Title: Re:延長    
甘えすぎという表現は、きつすぎました。申し訳ありません。
自分では間違いに気付きにくいものですからね。
私にテスト(or コードの精査)する気がなかったというだけの話でした。


81ポイント を手に入れた。

Name: MK  ..かけだし(1,292ポイント)   Date: 2010/06/17(木) 00:03   No:54511 解決!     
Title: Re:延長    
>>シエルさん
数字ばかりを入力していたので気が付きませんでした。ありがとうございます

>>たいちうさん
どうしても自分だけでは不安だということや、コールドの意味も確かになっておらずお聞きしてみましたが確かに頼り過ぎていたところもあります。今度からはもう少し本やネットで調べ努力をします。ありがとうございます


131ポイント を手に入れた。



Name: TKOZ  ..熟練のプログラマー(61,417ポイント)   Date: 2010/06/13(日) 16:47   No:54225       
Title: マリオ風アクションゲームのブロックとの当たり判定    
ネットカフェから書き込みです。
マリオ風横スクロールアクションゲームをC/C++で作成中なのですが、
ブロックとの当たり判定で思ったようにプレイヤーキャラが壁やブロックで止まらなかったり、
プレイヤーの位置が急に変わったりして困っています。
誰か助けてください。
当たり判定部分のソースを載せます。

typedef struct HITBG{
    int x;
    int y;
    int width;
    int height;
    int kind;
}HITBG;

class CBG{
public:  

HITBG HBG[14][16];

//void CBG::HitCheck()メンバ関数、引数にはプレイヤーキャラを入れる
void HitCheck(int &x,int &y,int width,int height)
{
        int i,j;

        for(i=0;i<14;i++)
        {
            for(j=0;j<16;j++)
            {
                if(HBG[i][j].kind!=5)//背景番号5番は空
                {
                if(y+height>=HBG[i][j].y &&
                    y<=HBG[i][j].y+32)//チップは32ドット
                {
                    if(x+width>=HBG[i][j].x &&
                        x+width<=HBG[i][j].x)
                    {
                        //左に接触
                        x=HBG[i][j].x+width;
                    }
                    if(x<=HBG[i][j].x+32 &&
                        x>=HBG[i][j].x+32)
                    {
                        //右に接触
                        x=HBG[i][j].x;
                    }
                    if(x+width>=HBG[i][j].x &&
                        x<=HBG[i][j].x+32)
                    {
                        if(y+height>=HBG[i][j].y &&
                            y+height<HBG[i][j].y)
                        {
                            //下
                            y=HBG[i][j].y+height;
                        }
                        if(y>=HBG[i][j].y+32 &&
                            y<HBG[i][j].y+32)
                        {
                            //上
                            y=HBG[i][j].y-32;
                            if(HBG[i][j].kind==2)
                            {

                            }

                        }
                    }

                }
                }
            }
        }
    }
};

CBG BG;

void Init()//DxLib_Init()後に呼ぶ関数
{
    //省略
    int i,j;

    for(i=0;i<14;i++)
    {
        for(j=0;j<16;j++)
        {
            BG.HBG[i][j].kind=BGTbl[i][j];
            BG.HBG[i][j].x=j*32;
            BG.HBG[i][j].y=i*32;
            BG.HBG[i][j].width=32;
            BG.HBG[i][j].height=32;
        }
    }
編集済み


617ポイント を手に入れた。


Name: kazuoni [URL]  ..ハッカー(143,200ポイント)   Date: 2010/06/13(日) 20:26   No:54250     
Title: Re:マリオ風アクションゲームのブロックとの当たり判定    
一番は、実行できる環境を用意する事かと思いますが・・・

パッと見た感じですが

if(y+height>=HBG[i][j].y && y<=HBG[i][j].y+32)//チップは32ドット

if(y+height>=HBG[i][j].y && y+height<=HBG[i][j].y+32)//チップは32ドット

if(x+width>=HBG[i][j].x && x<=HBG[i][j].x+32)

if(x+width>=HBG[i][j].x && x+width<=HBG[i][j].x+32)


あと、
if(HBG[i][j].kind==2){
}

となっていますが、この条件の時は何もしなくていいのでしょうか?

ただ、コメントが最小限なので、なんとも言えないかと思います。


179ポイント を手に入れた。

Name: TKOZ  ..熟練のプログラマー(61,452ポイント)   Date: 2010/06/14(月) 05:47   No:54288     
Title: Re:マリオ風アクションゲームのブロックとの当たり判定    
ソースと画像ファイルの入った圧縮ファイルをアップロードします。
どうか、よろしくお願いします。


35ポイント を手に入れた。

Name: TKOZ  ..熟練のプログラマー(61,555ポイント)   Date: 2010/06/14(月) 06:50   No:54289     
Title: Re:マリオ風アクションゲームのブロックとの当たり判定    
>あと、 
>if(HBG[i][j].kind==2){ 
>} 
>となっていますが、この条件の時は何もしなくていいのでしょうか? 
コインかハテナブロックの判定です。
まだ実装してません。
あと、背景の画像の関係でマップチップ番号を全体で+1しました。


103ポイント を手に入れた。

Name: TKOZ  ..熟練のプログラマー(62,004ポイント)   Date: 2010/06/14(月) 13:54   No:54314     
Title: Re:マリオ風アクションゲームのブロックとの当たり判定    
//その1です

#include"DxLib.h"

#define CHIP_SIZE 32

enum object{DOKAN};

int ScrollX;
int ScrollY;
int BGTbl[14][16]={
    5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5,
    5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5,
    5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5,
    5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5,
    5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5,
    5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5,
    5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5,
    
    5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5,
    5,5,5,5, 5,1,1,5, 5,5,5,5, 5,5,5,5,
    1,1,5,1, 1,5,5,1, 1,1,1,1, 1,2,1,1,
    5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5,
    5,5,5,5, 5,5,5,5, 5,5,5,5, 5,5,5,5,
    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
    0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0
};

typedef struct HITBG{
    int x;
    int y;
    int width;
    int height;
    int kind;
}HITBG;

class CBG{
public:
    
    //配列BGデータ
    int num;
    //BG番号
    HITBG HBG[14][16];
    int objectnum;
    //オブジェクト番号

    int table[16*14];
    CBG()
    {
        
    }
    ~CBG()
    {
        //特になし
    }
    void DrawChip(int num,int x,int y)
    {
        DrawGraph(x,y,table[ num ],TRUE);
    }
    void DrawBG_Object(int x,int y,int objectnum)
    {
        
    }
    void DrawBG()
    {
        int StartX=ScrollX/32,StartY=ScrollY/32;
        int EndX=(ScrollX+512-1)/32,EndY=(ScrollY+448-1)/32;

        for(int i=StartY;i<=EndY;i++)
        {
            for(int j=StartX;j<=EndX;j++)
            {
                DrawChip(BGTbl[i][j],j*32-ScrollX,i*32-ScrollY);

            }
        }
    }
    void HitCheck(int &x,int &y,int width,int height)
    {
        int i,j;

        for(i=0;i<14;i++)
        {
            for(j=0;j<16;j++)
            {
                if(HBG[i][j].kind!=6)
                {
                if(y+height>=HBG[i][j].y &&
                    y+height<=HBG[i][j].y+32)
                {
                    /*
                    if(x+width>=HBG[i][j].x &&
                        x+width<=HBG[i][j].x)
                    {
                        //左に接触
                        x=HBG[i][j].x+width;
                    }
                    if(x<=HBG[i][j].x+32 &&
                        x>=HBG[i][j].x+32)
                    {
                        //右に接触
                        x=HBG[i][j].x-32;
                    }
                    */
                    if(x+width>=HBG[i][j].x &&
                        x+width<=HBG[i][j].x+32)
                    {
                        if(y+height>=HBG[i][j].y &&
                            y+height<HBG[i][j].y)
                        {
                            //下
                            y=HBG[i][j].y+height;
                        }
                        if(y>=HBG[i][j].y+32 &&
                            y<HBG[i][j].y+32)
                        {
                            //上
                            y=HBG[i][j].y-32;
                            if(HBG[i][j].kind==2)
                            {
                                
                            }

                        }
                    }

                }
                }
            }
        }
    }
};

CBG BG;

class Character{
public:
    int GraphHandle;
    float x,y;
    int width,height;
    void Show()
    {
        DrawGraph(x,y,GraphHandle,TRUE);
    }
    Character()
    {
        //特になし
    }
    Character(char str[])
    {
        GraphHandle=LoadGraph(str);
    }
    ~Character()
    {
        //特になし
    }
};

enum Dir{RIGHT,LEFT,UP,DOWN};
enum Kind{SMALL,BIG,FIRE};



308ポイント を手に入れた。

Name: TKOZ  ..熟練のプログラマー(63,392ポイント)   Date: 2010/06/14(月) 13:55   No:54315     
Title: Re:マリオ風アクションゲームのブロックとの当たり判定    
//その2です。
class Mario : public Character{
public:
    unsigned char kisuu;
    bool muki;
    int joutai;
    int vx,vy;
    unsigned char hosuu;
    void Show()
    {

        hosuu=hosuu%2;
        switch(joutai)
        {
        case SMALL:
            DrawRectGraph(x,y,
                hosuu*32, 0, 32, 32,
                GraphHandle, TRUE, muki*1 ) ;
            
            break;
        case BIG:
            DrawRectGraph(x,y,
                0,32,64,64,
                GraphHandle ,TRUE,muki*1);
            break;
        case FIRE:
            DrawRectGraph(x,y,
                0,64,64,64,
                GraphHandle ,TRUE,muki*1);
            break;
        }
    }
    void Jump()
    {
        static bool jump=false;
        float jump_speed = vx==2 ? -14.0: -20.0;
        float jump_kasoku=1.0f;
        float groundy=448-96;
        float speed=0.2f;
        if(!jump)
        {
            
            if(CheckHitKey(KEY_INPUT_X)){
                jump=true;
                vy=jump_speed;
            }

        }else{
            vy+=jump_kasoku;
            y+=vy;

            if(vy>0 && y>=groundy){
                jump=false;
                y=groundy;
            }

            if(vy<0 && !CheckHitKey(KEY_INPUT_X)){
                vy=0;
            }
        }
        
        if(x<0) x=0;
        if(x>512-1)x=512-1;

    }
    void SayuuMove()
    {
        if(CheckHitKey(KEY_INPUT_RIGHT))
        {
            if(CheckHitKey(KEY_INPUT_Z))
            {
                vx=5;
            }else{
                vx=2;
            }
            AutoMove(RIGHT,vx);
            muki=RIGHT;
            hosuu++;
        }
        if(CheckHitKey(KEY_INPUT_LEFT))
        {
            if(CheckHitKey(KEY_INPUT_Z))
            {
                vx=5;
            }else{
                vx=2;
            }
            AutoMove(LEFT,vx);
            muki=LEFT;
            hosuu++;
        }
        if(!CheckHitKey(KEY_INPUT_RIGHT) && !CheckHitKey(KEY_INPUT_LEFT))
        {
            hosuu=0;
        }
    }
    void AutoMove(int muki,int speed)
    {
        switch(muki)
        {
        case RIGHT:
            x+=speed;
            break;
        case LEFT:
            x-=speed;
            break;
        case UP:
            y-=speed;
            break;
        case DOWN:
            y+=speed;
            break;
        }
    }
    Mario()
    {
        kisuu=3;
        muki=RIGHT;
        joutai=SMALL;
        x=(512-32)/2;
        y=448-96;
        hosuu=0;
        vx=2;
        vy=0;
    }
};

Mario P;

void Init()
{
    P.GraphHandle=LoadGraph("./mario.png");
    ScrollX=0;
    ScrollY=0;
    LoadDivGraph( "./BG.png" , 16*14 ,
            16 , 14 ,
            32 , 32 , BG.table ) ;

    int i,j;

    for(i=0;i<14;i++)
    {
        for(j=0;j<16;j++)
        {
            BGTbl[i][j]=BGTbl[i][j]+1;
            BG.HBG[i][j].kind=BGTbl[i][j];
            BG.HBG[i][j].x=j*32;
            BG.HBG[i][j].y=i*32;
            BG.HBG[i][j].width=32;
            BG.HBG[i][j].height=32;
        }
    }
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hP,LPSTR lpC,int nC)
{
    
    SetGraphMode(512,448,32);
    ChangeWindowMode(TRUE) ;
    SetMainWindowText("SuperMarioBrothers"); //ウィンドウのタイトル
    if(DxLib_Init() == -1) return (-1);    //DXライブラリ初期化
    
    //データ読み込み中と表示する
    DrawString( 0 , 0 , "データ読み込み中" , GetColor(255,255,255) );

    //各種変数の初期化など
    Init();
    //乱数の初期化
    srand((unsigned)GetTickCount());
    //メインループ
    while( ProcessMessage()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0){
        
        ProcessMessage();
        ClsDrawScreen();            //画面を初期化
        
        BG.DrawBG();
        P.SayuuMove();
        P.Jump();
        int a,b;
        a=(int)P.x;
        b=(int)P.y;
        BG.HitCheck(a,b,32,32);
        P.x=a;
        P.y=b;
        P.Show();
        
        //DrawFormatString(0,40,GetColor(255,255,255),"angle=%f",angle);
        //DrawFormatString(0,60,GetColor(255,255,255),"angle2=%f",angle2);
        
        ScreenFlip();                //フリップする
    }
    
    DxLib_End();    //DXライブラリ終了処理
    return (0);        //終了
}


1,388ポイント を手に入れた。

Name: TKOZ  ..熟練のプログラマー(63,417ポイント)   Date: 2010/06/16(水) 15:02   No:54491     
Title: Re:マリオ風アクションゲームのブロックとの当たり判定    
ネットカフェから書き込みです。
誰か分かる方いたら、よろしくお願いします。


25ポイント を手に入れた。

Name: wing  ..中級者(11,135ポイント)   Date: 2010/06/16(水) 16:16   No:54492     
Title: Re:マリオ風アクションゲームのブロックとの当たり判定    
私は初心者なので適切なことは言えないですが、
ざっと見たところ、常にすべてのブロックのx、y座標で
当たり判定をしようとしているようですが、もっと
簡単でいいんじゃないでしょうか。

つまり、当たり判定専用の1と0のマップを作って、
キャラのX+vxがマップの1だったらvx=0とかです。

プログラミングのスタイルも違うし、HBGって何の略だらう
なんて考えるとサンプルを作るのが億劫になるので、
とりあえず、DXライブラリ置き場のサンプルプログラムの
「アクションゲームにおけるマップとの当たり判定基本」
を参考にしたらどうでしょうか。

あと過去のログにも似たような質問がたくさんあります。


180ポイント を手に入れた。

Name: TKOZ  ..熟練のプログラマー(63,436ポイント)   Date: 2010/06/16(水) 18:49   No:54494 解決!     
Title: Re:マリオ風アクションゲームのブロックとの当たり判定    
ありがとうございます。wingさん、
解決しました。
下記のページを参考にしました。
http://hakuhin.jp/as/block.html#BLOCK_05 編集済み


19ポイント を手に入れた。



Name: レイ  ..かけだし(1,070ポイント)   Date: 2010/06/12(土) 17:30   No:54123       
Title: リプレイデータでキー入力の変化を記録する方法    
はじめまして、レイと申します。

龍神録でリプレイを保存して再生するのはできているのですが、
サイズがとても大きくて困っております。

圧縮しようと思ったのですが、zlibとかランレングス圧縮のプログラムは
自分にとって難解だと感じたため、

過去ログの方法の

「全てのキーの入力状態を記憶せず、キーの入力に変化があったフレーム番号とその変化を記憶させれば、リプレイデータが軽量化出来る」

という方法を行ってみたいと思ったのですが、まず何を行えばいいのか分からないという現状です。

どんな感じの手順を踏めばいいのかだけでも
教えて頂けないでしょうか。

未熟者ですみません。
どうかよろしくお願いします。


168ポイント を手に入れた。


Name: Dixq (管理人) [URL]  ..ウィザード(1,206,958ポイント)   Date: 2010/06/12(土) 19:35   No:54126     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
特に難しくはないと思います。
書いてある通りですが、キー入力の状態が変わった時に、どのボタンが何フレーム目で変わったのかを記録すればいいと思います。

まず、ゲームが始まった瞬間のキーの入力状態を記録しておきます。
そして、リプレイの瞬間それを再現します。

後は「キーの入力状態が変わった」情報を元に変更して行けばいいのです。
例えば、Zキーが押されているかどうか、ではなく、
最初のキーの入力状態がわかれば、「○○フレーム目でXXキー」という情報さえあれば再現出来るのです。

例えばですが、

No.   ボタン
0  … 下キー
1  … 上キー
2  … 左キー
3  … 右キー
4  … ショットキー
5  … ボムキー
6  … 低速移動キー
7  … ストップキー
8  … ボス会話スキップキー

とか事前に決めておいて、キーの入力状態に変化があった時、

・何フレーム目か(unsigned shot int(2バイト))
・どのボタンか(unsigned char(1バイト))

を記録すれば良いです。
キーの入力状態は必要ありません。
データがあるということは、この時入力状態が変わった事がわかるのですから。

とりあえず全部一気に作ろうとすると難しいのでまずは

「キーの入力状態が変わった時、そのキー番号とフレーム数を記録するプログラム」

を作ってみてはどうでしょう。
読み込み、再現はそれが出来てからということで。


576ポイント を手に入れた。

Name: スキマ妖怪  ..ぴよぴよ(83ポイント)   Date: 2010/06/12(土) 19:42   No:54127     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
圧縮とかの前に記録する情報量を減らすことを考えてみてはいかがですか?
もしかして、全ての変数をintとかでファイルに書き込んでないですか。


以下的外れかもしれませんが例えば、

キー入力の場合、上下左右+4ボタンしか使わないのなら1バイト分ですみます。(各キーにbitを割り当てる)
フレーム情報の場合も、2バイト分など必要な分だけ書き込めば、その分容量を減らせます。
1Byte(キー) + 3Byte(フレーム) = 4Byteの方がキリがよさそうですかね。


その上で、

>「全てのキーの入力状態を記憶せず、キーの入力に変化があったフレーム番号とその変化を記憶させれば、
> リプレイデータが軽量化出来る」 

をすればさらに減らせるんじゃないですか。(試してないのでどの程度かは分かりませんけど…;)
手順については、…書いてある通りなんですけどね。

ゲームプレイ時は、
(前のフレームと比べて)キーの変化がある毎にそのときのフレーム(ゲーム内時間)を記録
これで変化があったモノだけになるはず。

リプレイ時は、
読み込んだリプレイデータを元に記録されたフレームがきたら記録された値にキーを変更
これでキー入力に関しては、再現できるはず。

という感じですね。


…ところで、サイズが大きいって具体的にどのくらいですか?
100KByte程度だったら許容範囲だと思いますよ(^^




投稿迷ってたらDixqさんが…
まぁ、せっかくなんで書き込みます(かぶっちゃってますけどorz)


83ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,207,126ポイント)   Date: 2010/06/12(土) 19:55   No:54128     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
なんか被ったようですみません^^;

[修正:23:06]
(すみません、秒に分を掛けていませんでした・・。
1時間のフレーム数は2バイトでは計算しきれませんので、普通のintが必要ですね。
以下2バイトの話は読み飛ばして下さい・・)


おさらいすると、、

  ・何番のボタンか(1バイト)
  ・何フレーム目か(2バイト)

さえあれば良いということですね。

上の通りならば3バイトなのですが、むちゃをして詰め込もうとすれば、2バイトでもいけるかもしれませんね。

  ・リプレイは2^12フレーム(1時間ちょっと)までしか保存しない。
  ・ボタンは16種類しか使用しない

とすれば、
例えば16ビットの内、上位4ビットはボタンの種類を表し、下位12ビットはフレーム数を表すことで、
容量が2/3になると思います。

まぁここまでして軽量化したければですが^^;

※ボタンが8種類でいいのなら、2.2時間位記録できます。


ちょっとサンプル作ってみました。
実行中に適当にキーボードを押してみて下さい。
変化のあったキー番号とフレーム数が表示されます。
重ねて言いますが、押したか離したかは記録する必要ありませんので、
変化のあったキー番号とフレーム数のみ表示しています。

#include "DxLib.h"

//キーの入力状態の変化を計算して変化があると表示する
void CalcKeyState( int FrameNum ){
            char nowKeyState[256];    //今現在の入力状態
    static    char oldKeyState[256];    //過去の入力状態
    GetHitKeyStateAll( nowKeyState );    //入力状態を取得

    for( int i=0; i<256; i++ ){
        if( nowKeyState[i] != oldKeyState[i] ){    //過去の入力状態と違えば
            printfDx("Frame = %4d, KeyNo.=%d\n", FrameNum, i);    //表示
        }
    }
    memcpy( oldKeyState, nowKeyState, 256 );    //現在の入力状態を過去のものに
}
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    int FrameCount=0;
    if(ChangeWindowMode(TRUE)||DxLib_Init()||SetDrawScreen(DX_SCREEN_BACK))return -1;
    while(!ScreenFlip()&&!ProcessMessage()&&!ClearDrawScreen()&&!CheckHitKey(KEY_INPUT_ESCAPE)){

        CalcKeyState( FrameCount );
        
        DrawFormatString(500,0,GetColor(255,255,255),"Frame=%d",FrameCount);//フレーム数表示
        FrameCount++;
    }
    DxLib_End();return 0;
}
 


168ポイント を手に入れた。

Name: シエル  ..入門者(3,740ポイント)   Date: 2010/06/12(土) 20:32   No:54130     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
ゲーム等のリプレイデータって、動画形式でそのまま保存してると思ってました…
キー情報を保存して、後からその情報を読み込んで動かせば、
確かにリプレイになりますね。
勉強になりました。ド素人のつぶやきですので、スルーして下さい。


74ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,207,355ポイント)   Date: 2010/06/12(土) 20:51   No:54132     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
私も最初はどうやって保存すればいいのかな〜と思っていました。
動画なんてキャプチャしようものなら、圧縮しないと何十GBなんてことになってしまいますからね;

キーの入力状態を再現すればいいっていう方法は
一般的な方法かどうかはわかりませんので、参考程度にお聞きください。

ただ、一般的にもきっとこんな方法でプレイを再現しているのだとは思います。


229ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,209,151ポイント)   Date: 2010/06/12(土) 20:54   No:54133     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
なんかどれ位圧縮できるのか興味あったので、作ってしまいました。
エラー処理云々は改善しないといけないでしょうけど、試作ということで。
本当にゲームに組み込む時はstatic変数とかを綺麗にやり変えて下さい。

デフォルトのままだとプレイ状態です。キーの入力状態を随時記録していきます。
最初に動作させる時はこの状態でまずデータを作って下さい。

作ったら、

メイン関数の最初にある
ReplayFlag=0;//リプレイフラグ



ReplayFlag=1;//リプレイフラグ

にして下さい。プレイを再現する処理に変わります。
1にすると、ファイルからキーの変化のあった情報を読み込み、リアルタイムでキーの入力状態を再現します。
サンプルということで、何か参考になればどうぞ。


#include "DxLib.h"

/***********************  リプレイデータ保存   ****************************/

//キーの入力状態の変化を計算して変化があると表示する
void SaveKeyChangeState( unsigned short FrameNum, FILE *fp ){
            char nowKeyState[256];    //今現在の入力状態
    static    char oldKeyState[256];    //過去の入力状態

    GetHitKeyStateAll( nowKeyState );    //入力状態を取得

    if( FrameNum == 0 ){    //最初ならキーの入力状態全てを保存
        fwrite( nowKeyState, 256, 1, fp );
    }

    for( int i=0; i<256; i++ ){
        unsigned char KeyNum = (unsigned char)i;
        if( nowKeyState[i] != oldKeyState[i] ){    //過去の入力状態と違えば
            fwrite( &FrameNum, 2, 1, fp );    //フレーム数記録
            fwrite( &KeyNum,   1, 1, fp );    //キー番号録
            printfDx("Frame = %4d, KeyNo.=%d\n", FrameNum, KeyNum);    //表示
        }
    }
    memcpy( oldKeyState, nowKeyState, 256 );    //現在の入力状態を過去のものに
}

/***********************  リプレイデータ読み込み   ****************************/

//変化のあったフレーム数とキー番号を読み込み
int ReadData( unsigned short *FrameRem, unsigned char *KeyNum, FILE *fp ){
    if( !fread( FrameRem, 2, 1, fp ) ) return -1;
    if( !fread( KeyNum,   1, 1, fp ) ) return -1;
    return 0;
}

//リプレイデータからキーの状態を再現
int ReadKeyChangeState( unsigned short FrameNum, FILE *fp ){
    static char KeyState[256];    //過去の入力状態
    static unsigned short FrameRem;    //変化のあったフレーム番号
    static unsigned char  KeyNum;    //変化のあったキー番号

    if( FrameNum == 0 ){    //最初なら
        if( !fread( KeyState, 256, 1, fp ) )        //キーの入力状態をセット
            return -1;
        if( ReadData( &FrameRem, &KeyNum, fp ) )    //次にキーの状態が変わる情報を読み込み
            return -1;
    }

    if( FrameRem > FrameNum ){    //キーの状態が変わるのがまだ先ならもう帰る
        return 0;
    }
    if( FrameRem < FrameNum ){    //こんなことはあってはいけないのでエラー
        return -1;
    }

    for( int i=0; i<256; i++ ){    //ここに来た時点で0-255のどれかが変わるはず
        if( i == KeyNum ){    //変わるのがこれなら
            KeyState[i] = KeyState[i] ? 0 : 1;    //1なら0を、0なら1を代入
            printfDx("Frame = %4d, KeyNo.=%d\n", FrameNum, KeyNum);    //表示
            if( ReadData( &FrameRem, &KeyNum, fp ) )    //次にキーの状態が変わる情報を読み込み
                return -1;
            if( FrameRem > FrameNum ){    //キーの状態が変わるのがまだ先ならもう帰る
                return 0;
            }
        }
    }
    return 0;
}

/***********************  メイン   ****************************/

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    int FrameCount=0, ReplayFlag=0;//リプレイフラグ
    FILE *fp;
    if(ChangeWindowMode(TRUE)||DxLib_Init()||SetDrawScreen(DX_SCREEN_BACK))return -1;
    
    if( ReplayFlag == 0 ){    //リプレイ中じゃなければ書き込み
        if( (fp=fopen("000.rpy","w")) == NULL )
            goto LAB_EX;
    } else {                //リプレイ中なら読み込み
        if( (fp=fopen("000.rpy","r")) == NULL )
            goto LAB_EX;
    }

    while(!ScreenFlip()&&!ProcessMessage()&&!ClearDrawScreen()&&!CheckHitKey(KEY_INPUT_ESCAPE)){

        if( ReplayFlag == 0 ){        //リプレイ中じゃないなら
            SaveKeyChangeState( FrameCount, fp );    //キーの変化状態を保存
        } else {
            if( ReadKeyChangeState( FrameCount, fp ) )    //キーの変化状態を読み込み・適用
                break;
        }

        DrawFormatString(500,0,GetColor(255,255,255),"Frame=%d",FrameCount);//フレーム数表示
        FrameCount++;
    }

    fclose( fp );

LAB_EX:
    DxLib_End();return 0;
}
 


1,796ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,209,426ポイント)   Date: 2010/06/12(土) 21:15   No:54134     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
連投になりますが・・。

ちょっと気になったので、龍神録の1面でリプレイデータ取ってみました。

1.4KBでした。
先ほどの理論で圧縮すれば900バイトになりますね。

プレイ時間が4分でしたので、普通なら60フレーム×240秒で14400フレーム。

今まで単純に、龍神録の館で紹介しているキーの状態

typedef struct{
        int left,up,right,down,shot,bom,slow,start,change;
}configpad_t;

をそのまま記録していたとすると

14400フレーム*4バイト*9個=514[KB]

ですから、1/500位に圧縮できたことになりますね。


[修正:23:12]
1時間は60*60*60フレームで、unsigned short intで扱える数を超えるので、unsigned intが必要ですね。
詰め込んだとしてもキー番号と合わせて4バイト必要ですから、圧縮率は1/250ですね。


275ポイント を手に入れた。

Name: スキマ妖怪  ..ぴよぴよ(297ポイント)   Date: 2010/06/12(土) 23:20   No:54160     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
時間記録用の変数が2バイトって微妙じゃないですか?
サンプルだからいいんですが、

2バイトだと65535

65535 / 60(秒) / 60(フレーム) = 約18分

東方風のSTGだとして(竜神録等)

6ステージだとすると

18分 / 6ステージ = 3分
道中1分、各弾幕平均1分として(クリア時間でなくタイムリミット)


道中、ボス戦込みで1ステージあたり3分しか使えないことになります。
遊ぶ側は、最短・平均クリア時間を目指すと思いますが(稼ぎプレイとかはとりあえず省いて)
作る側は、最長クリア時間を考慮しないとまずいと思います。(3、4バイト分くらい必要だと思います。)


実際はこうでないかもしれませんが、結構シビアだと思います。




…と思ったんですが記録方法を工夫すればいけますかねえ。
(例えば、直前の時間との差分とか)


> ですから、1/500位に圧縮できたことになりますね。これはやらなきゃですねw

それでも2バイト計算で1/500ってすごいですねw(すっごいコンパクトw)



以下追記--------------------
またカブッテシマッタ( ̄Д ̄;)
(ハズカシイ…)

> (例えば、直前の時間との差分とか)

ものすごいケチって1バイトで記録とかw

 編集済み


214ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,209,734ポイント)   Date: 2010/06/12(土) 23:26   No:54161     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
えぇ、、、秒に分を掛けるの忘れていましたよorz
記事を修正したのですが、私が修正すると修正マークが付かないんですよね・・。
赤字で修正してあるので、よければもう一度ご覧ください;

前回変化があったフレーム番号からの差分って考えとてもいいですね。
完全なシステムを作りたいならそれはちょっと危ない設計かもしれませんが仰る方法は良い発想だと思うので、
なんとか2バイトに抑えてみたいものですw

如何にデータを小さくするか・・・。
なんかテーマ的に燃えますねw


174ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,210,000ポイント)   Date: 2010/06/12(土) 23:37   No:54163     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
最上位ビットは桁が溢れたかどうかを表すフラグにしてみてはどうでしょう。
溢れていたらもう1バイトフレーム数を表す領域だと判定して1バイト余分に読みこむのです。

2^12フレームとは4096フレーム。
その最上位ビットを使うので、

2*11=2048フレーム
これは30秒に相当しますね。
30秒間何のキー入力も無い事などほとんどないと思います。

もしあれば最上位ビットを1にして、もう1バイト余分に領域を確保し、フレーム数の保存に使います。
こうすれば「普段2バイト、時々必要なら3バイト」みたいな事が可能にならないでしょうか?

図にしてみました。



恐らく30秒以上何もキーを押さないなんてことはないでしょうから、ほとんど2バイトで計算出来るのではないかと思いまがどうでしょうね?


追記:
東方には
「音楽」「弾幕」「システム」「計算速度」「美しさ」「魅力」・・・∞
何一つ勝てないので、せめて「リプレイデータのサイズ」位は勝てないかと躍起になっています(笑


266ポイント を手に入れた。

Name: スキマ妖怪  ..ぴよぴよ(585ポイント)   Date: 2010/06/13(日) 00:25   No:54167     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
自分なら節約もいいですが、(製作者として)使いやすい構造にしますね。
どうせサムネ画像とか、記録日時とか、飾りが入ると思うので(となると努力が…)


#pragma pack(push,1)    // ←入れた方がいいんですかね?(すごい適当)
typedef struct {
    int     keys : 8;
    int        frame : 24;
} SAV_DAT;
#pragma pack(pop)

とでもしておいて、出し入れのしやすさをとっちゃうんですけどね。
(バグになりそうな要素を入れたくない、シンプルにしたい)


> 30秒間何のキー入力も無い事などほとんどないと思います。 

事実上、成立すると思いますよ。
(自機狙いなどの)弾幕の中で無傷(に近い状態)はゲームとしてアレですからね。


> もしあれば最上位ビットを1にして、もう1バイト余分に領域を確保し、フレーム数の保存に使います。 

フラグを使って、切り替えをする仕組み。
面白そうですね。ただ、バグらせる自信がありますw(そして飽きるorz)


ん?
図おかしくないですか

キー番号用のビット最低5ビットは必要じゃないですか?(上下左右+ショット、これ以上はゲーム仕様による)
だとするとデフォで15秒…
可変式なんで関係ないですけどねw


すみません。上レスで2バイトといっているのは、フレーム時間のみのことで、
実際は2(フレーム)+1(キー)=3バイトです。
紛らわしくてすいません。


> 東方には 
> 「音楽」「弾幕」「システム」「計算速度」「美しさ」「魅力」・・・∞ 
> 何一つ勝てないので、せめて「リプレイデータのサイズ」位は勝てないかと躍起になっています(笑

そんなことないですよ。
細部に作りこまれていて面白かったです。(ここに来たのも竜神録経由だったと思うし。いいサイトです(^^


では、対抗してシリーズ展k(ry



288ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,210,595ポイント)   Date: 2010/06/13(日) 00:40   No:54168     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
今のリプレイってサムネ画像とか入ってるんですか?・・・知りませんでした。

>キー番号用のビット最低5ビットは必要じゃないですか?

いえ、キーの入力状態を保存する必要はなく、「何番のキーか」を保存すればいいと思います。

上に書いたとおりですが例えば

No.   ボタン 
0  … 下キー 
1  … 上キー 
2  … 左キー 
3  … 右キー 
4  … ショットキー 
5  … ボムキー 
6  … 低速移動キー 
7  … ストップキー 
8  … ボス会話スキップキー 

みたいに予め決めておきます。
そうすれば、16種類もキーがあれば十分でしょうから、2^4=16で4ビットあればいい事になります。

後は差分フレームというわけです。


これらのデータの他のリプレイデータの最初に入れるものとしては

・名前(16[b])
・乱数の初期値(4[b])
・日付(年・月・日・時・分=10[b])
・プレイキャラ(1[b])
・ステージ(1[b])
・処理落ち率など?(4[b])

位ですかね。まぁ100[b]あれば何でも保存できそうな気がします。
画像とかがあれば別ですが・・。


所で、この圧縮が東方と比較してどの程度な物か調べてみました。

常に左右に移動し、ショットを90秒撃ち続けるというプレイを東方風神録1面で行うとリプレイデータは4.7[KB]でした。
上の理論を龍神録に実装して、同じ条件でショットを90秒撃ち続けると、リプレイデータは0.7[KB]でした。ヘッダ情報を0.1[KB]追加したとしても0.8[KB]。

しかし東方のリプレイデータに実質的なリプレイデータ以外に何がくっついているのか解らないので何とも言えません・・。
何か暗号化的な事がしてあるとか改竄検出出来るようにしてあるとか何かあるかもしれませんね。

短時間のリプレイと長時間のリプレイで差分を取ればヘッダにどれ位の容量があるのか推測できますが、
長時間龍神録と風神録で全く同じプレイをするってことが出来ないので難しいですね・・。


>細部に作りこまれていて面白かったです。

ありがとうございます^^
いや〜龍神録をやって東方をやると公開をやめたくなるような気持ちに今でもなります^^;
時間があればまた作りたいんですが・・・。
2を作りかけたものの、社会人になると作ってる時間はあまりないですねぇ;
こうしている間にもZUNさんは毎年着々と新作を出して離れていく(最初から近づいてないけど)
どういう時間の使い方をしていらっしゃるのでしょう^^;


737ポイント を手に入れた。

Name: スキマ妖怪  ..ぴよぴよ(712ポイント)   Date: 2010/06/13(日) 00:58   No:54170     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
> 今のリプレイってサムネ画像とか入ってるんですか?・・・知りませんでした。 

いえ、本家には入っていません。(本当、分かりづらくてすいません)
自分が作るなら…と深く考えずに書いたんですがよく考えたらいらないですね。
(使う方向で考えるなら、ボムやハイスコア弾幕等の映える場面を撮影…面倒ですね)


> 短時間のリプレイと長時間のリプレイで差分を取ればヘッダにどれ位の容量があるのか推測できますが、 
> 長時間龍神録と風神録で全く同じプレイをするってことが出来ないので難しいですね・・。

処理落ちを考慮した厳密な記録をしているのでは?


127ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(543,795ポイント)   Date: 2010/06/13(日) 01:02   No:54171     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
>こうすれば「普段2バイト、時々必要なら3バイト」みたいな事が可能にならないでしょうか
 可能にはなりますけど、整合性の検証とかデバッグとか面倒になりそうですし、
理論的には3バイトを越えたことも考えて3バイト目の最終フラグを桁あふれフラグにして
4バイト目も見にいくようにしないとだめかと。

 シンプルに考えるなら、キー番号 0か何かを無効扱い(何も押されていない)にして
前とのフレーム差が 2^X-1を超えそうになったら無効扱いで書き込んでしまえばいいかと。


94ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,211,099ポイント)   Date: 2010/06/13(日) 01:04   No:54172     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
>処理落ちを考慮した厳密な記録をしているのでは? 

そうえいば「処理落ちを再現してリプレイ」みたいな機能もありましたね・・。
FPS制御ツールでいかさましたリプレイでも解ってしまう仕様・・確かに必要ですね。

後は「ボスまで高速再生」とか。
単なるキーの入力状態以外にも色々付いてそうですね〜。
やっぱリプレイデータすら勝てないかも・・。
まぁ神様と勝負しようとするのがそもそもの間ちg(ry

======

今回の件せっかくなので、ゲームプログラミングの館にソース載せたいなと思うのですが、
スキマ妖怪さんに頂いた「差分を保存」理論紹介させて頂いても良いでしょうか?


後、上の5bit無いといけないのでは?の件はどうでした?
何か私に勘違いがあれば教えて頂けると幸いです。


298ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,211,145ポイント)   Date: 2010/06/13(日) 01:07   No:54173     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
> Justyさん

確かに理論上可能な圧縮をすればいいというものではないですね。
メンテナンスやデバッグのしやすさを考慮した圧縮も必要ですね。

む〜どの辺で妥協すべきか。
東方もその辺良い辺りで手を打ってあるのですかねぇ・・。


> 4バイト目も確かめる必要性

確かに。今のままでは145分放置すると3バイト目も溢れますね。
まぁ2時間半近くリプレイ取る人はいないだろうと言う事で、2時間しか記録できないように決め打ちしてもいいかもしれませんが
拡張性や汎用性を考えると4バイト目を見に行くようにするべきですね。


46ポイント を手に入れた。

Name: スキマ妖怪  ..ぴよぴよ(815ポイント)   Date: 2010/06/13(日) 01:13   No:54174     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
> 今回の件せっかくなので、ゲームプログラミングの館にソース載せたいなと思うのですが、 
> スキマ妖怪さんに頂いた「差分を保存」理論紹介させて頂いても良いでしょうか? 

書いてる途中でぱっと思いついただけのものなんでどうぞ自由にしちゃってくださいw


> 後、上の5bit無いといけないのでは?の件はどうでした?

書き忘れていましたw
アレは、同時押しを考慮したら必要かなと思ったので。(可能性は0じゃないので。ずれますよね)


慣れてないので、削除キーをよく忘れます(ついでに打つのが遅い)



103ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(543,880ポイント)   Date: 2010/06/13(日) 01:14   No:54175     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
>リプレイデータの最初に入れるものとしては 
 データの破損チェック用のハッシュはどこかに入れておいた方がいいかも。



 ところで会話シーンにおけるリプレイってどうするんでしょ?
 会話のところも忠実にリプレイするのでしょうか?


85ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,211,503ポイント)   Date: 2010/06/13(日) 01:20   No:54176     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
>> スキマ妖怪さん
>アレは、同時押しを考慮したら必要かなと思ったので。

一応私の上のプログラムは同時押しも考慮してあります。
同時に押しても、キーの番号順にループするので、同じフレーム内で同時押しが起こっても大丈夫なはずです。
再現する時もキーの番号順にチェックしますから。

>書いてる途中でぱっと思いついただけのものなんでどうぞ自由にしちゃってくださいw 

ありがとうございます。
このご恩は必ず・・・・!・・・・何で返そう?;


>> Justyさん
>データの破損チェック用のハッシュはどこかに入れておいた方がいいかも。 

なるほど、上の理論で実装すると、実装が間違うと
フラグミスで読み取るバイトがずれたりする危険性もありますしね・・。

>会話のところも忠実にリプレイするのでしょうか?

必要は無いのでしょうが、場合分けせずに全部同じ要領でリプレイした方が簡単そうかなとは思います^^;


358ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(544,076ポイント)   Date: 2010/06/13(日) 01:44   No:54177     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
>実装が間違うとフラグミスで読み取るバイトがずれたりする危険性もありますしね・
 そうですね。
 データを書き込んだ後、読み出されるまでの間に壊れてしまう可能性は少なからずありますから、
一応読み出した段階で何らかのチェックは必要になるかと。
 このあたりはセーブデータと同じですね。


>場合分けせずに全部同じ要領でリプレイ
 なるほど。
 だとすると、会話シーンで2、3時間以上放置される可能性もあり、それも忠実に再現すると
そのままでは3バイトでは足らなくなることもあるわけですね。


196ポイント を手に入れた。

Name: スキマ妖怪  ..かけだし(1,095ポイント)   Date: 2010/06/13(日) 02:03   No:54179     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
> データの破損チェック用のハッシュはどこかに入れておいた方がいいかも。
こういうのは、分かりませんorz(使ってこなかった…いや、避けてきたのかな)


> 一応私の上のプログラムは同時押しも考慮してあります。 
> 同時に押しても、キーの番号順にループするので、同じフレーム内で同時押しが起こっても大丈夫なはずです。 
> 再現する時もキーの番号順にチェックしますから。 

という事は、

(キー+差分0)+(キー+差分フレーム数)+追加分
=2バイト+2バイト+追加分

て事ですよね。(違ったらすいません;)
これどのくらいの頻度で出るんでしょうねえ。(多いと努力の甲斐が…)
多くはないと思いますが…


> このご恩は必ず・・・・!・・・・何で返そう?; 

ソンナオンナンテシッピツチュウノホンガホシイナンテ
冗談ですw真に受けないでくださいね。
ついでにいつもなら忘れてそのままになるので、役立つのならそれだけで十分です。


>>会話のところも忠実にリプレイするのでしょうか? 
>必要は無いのでしょうが、場合分けせずに全部同じ要領でリプレイした方が簡単そうかなとは思います^^;

東方だと、分けてなかったと思います。(うろ覚えですが)


280ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,211,925ポイント)   Date: 2010/06/13(日) 09:14   No:54185     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
>> Justyさん

> なるほど。だとすると、会話シーンで2、3時間以上放置される可能性もあり、それも忠実に再現すると 
> そのままでは3バイトでは足らなくなることもあるわけですね。 

そういう事になりますが、リプレイデータの軽量化は、友達同士で交換する、
もしくは自分の自慢のプレイを見て欲しくてHPなどにアップする事を容易にする為に必要であり、
自分のPCにおいておくだけなら別に容量が1.5倍程度になる事は十分許容範囲だと思います。

そして、会話で2〜3時間放置するようなリプレイデータを友達同士で見せ合うだろうかと考えれば否なので、
こんなリプレイデータにおいて少々データサイズが増えることは考慮しなくても大丈夫かなと思います。

スキップが必要なら、リプレイ再生中に押せる「高速処理ボタン(描画スキップボタン)」を用意すればいいと思いますし。


>> スキマ妖怪さん
> (キー+差分0)+(キー+差分フレーム数)+追加分

う〜んと、仰っている意味が良く解らないです、ごめんなさい;
データは、キー番号と差分フレーム数が連続して記録されているわけですから例えば

2,30,(キー番号:2、差分フレーム:30)
1,40,
3,30,

みたいに入ってるわけですよね、2,3,4キーの同時押しだと

2,0,
3,0,
4,0,

のようになるので、バイト数は2バイトから増えないと考えています。

> 本

なるほど、たかぎさんがされたようなイベント検討させて頂きます^^;


422ポイント を手に入れた。

Name: スキマ妖怪  ..かけだし(1,307ポイント)   Date: 2010/06/13(日) 09:53   No:54188     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
> (キー+差分0)+(キー+差分フレーム数)+追加分 

すいません;
明らかに説明足らないですね…(我ながらヒドイ;)

自分はよく、書いたつもり、言ったつもりで肝心な所が抜けたりしますorz



> 2,3,4キーの同時押しだと 
> 2,0, 
> 3,0, 
> 4,0, 
> のようになるので、バイト数は2バイトから増えないと考えています。 

仮にこういうのが頻繁に発生するなら、
1バイトで上下左右+各種ボタンにする方が(つまり最初のヤツにもどr)
トータルで容量が少なくて済むんじゃないかと
チラッと思ったんですがそんなこと微塵も書いてなかったですねorz



>> 本 
>なるほど、たかぎさんがされたようなイベント検討させて頂きます^^;

書いてみたかっただけですのでw
自分のことは気になさらず。



212ポイント を手に入れた。

Name: レイ  ..かけだし(1,696ポイント)   Date: 2010/06/13(日) 11:07   No:54191     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
うおぉ…私のいない間にすごいレス数…
みなさん、こんなに真剣にレスして下さって頂いて本当に感謝いたします…

>全ての変数をint
自機情報や、ステージ情報などはintで保存しています。
キー情報はunsigned charで保存しています。
重くなっている原因はたぶん次のことが原因だと思います。

東方だと「パッドのあそび」というゲームパッドのアナログスティックの感度を
敏感にしたり鈍感にしたりする項目がありますよね。
私もコンフィグでそれを行っており、DXライブラリの関数で
GetJoypadAnalogInput( int *XBuf , int *YBuf , int InputType) ;
を使って、パッドのスティックの敏感度を再現しています。
しかし、そのままだと-1000〜1000の範囲なので
これを10で割って-100〜100の範囲にして、
signed charで1フレームずつ、リプレイのキー情報と同じようにして保存しています。
これがあるためサイズが大きいのです。


そこで質問なのですが

管理人さんの描かれた有難い図の
「桁あふれフラグ」は、みなさんが仰っているリプレイの放置時間が
2ビットで納まらなかったら3ビットにするためのフラグでしょうか。
もしくは、2ビットから溢れた場合にフラグを立てるためのものでしょうか。



管理人さんのソースについてなんですが、
龍神録だとパッドとキーボード両方を監視しているので
それを試みようと思いましたが、メモリエラーを起こしました。

まずパッド版を作成しようと考えたのが
添付したソースです。

両方監視はパッド版ができてからにしようと思いまして…。
パッドのみなのでキーボード部分をコメントアウトしています。

最後にもう一つです。すみません…。

2,30,(キー番号:2、差分フレーム:30)
という方法で保存していくということですが
同時押しすると

2,30,(キー番号:2、差分フレーム:30)
3,30,(キー番号:3、差分フレーム:30)
4,30,(キー番号:4、差分フレーム:30) 

この3つが一気に保存されるということで合ってますでしょうか?
そして、再生中はこれらが一気に30フレーム中で再現される。
という感じで解釈しています。
もし間違っていたらご指摘頂けるとありがたいです。 編集済み


626ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,213,236ポイント)   Date: 2010/06/13(日) 17:15   No:54229     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
なんか読むのもダルくなるほど書き込んじゃいましたね、ごめんなさい;

====

ビットとバイトという言葉がごっちゃになってしまっているので、ここで一度整理してみましょう。

情報量の最小単位はビットと言います。
これは0か1かという2種類の信号しか識別出来ない最小単位です。
これが一つで1ビットです。
二つで2ビットになると、

00
01
10
11

の4種類の信号が識別出来るようになります。
3ビットなら8、8ビットなら256です。
全ての情報を1ビット単位で計算すると無駄があるので、8ビットずつ計算しましょうという決まりがあり、
この単位が1バイトです。

つまり1バイトは8ビットであり、256種類の信号が識別出来ます。
私が描いた図は00〜15までビットがありますが、これはunsigned short int(2バイト)で扱う16ビットを示しています。
65536種類の信号が識別出来ます。

この最上位ビットをフラグに、その下の4ビットをキー番号に、残りのビットを差分フレーム番号に使おうというわけです。
しかし、ビット単位でデータを詰め込むような事はややこしく、バグの元なので、よっぽどやりたいということで無ければやめておいた方が良いと思います。

>「桁あふれフラグ」は、みなさんが仰っているリプレイの放置時間が 
>2ビットで納まらなかったら3ビットにするためのフラグでしょうか。

そうです。何かのフラグが無いと、3ビット目がどういうデータなのか解らないので、可変長にする為にフラグを用意しています。
最上位ビットに「次の1バイトも同じくくりのフレームのデータなので、連続で読み込んでね」という信号をいれておくのです。

>龍神録だとパッドとキーボード両方を監視しているので 

キーボードの入力状態もパッドの入力状態も分ける必要はありません。
キーボードのZも、パッドの○も「ショットボタン」を表すのであれば、ゲーム側からしてみたら、
それがZキーであろうが、○ボタンであろうがどうでもいいのです。
必要なのは、どういう役割のボタンかということです。
龍神録だと9種類しか使っていないので、4ビットで十分ですね。

>同時押しすると 
>2,30,(キー番号:2、差分フレーム:30) 
>3,30,(キー番号:3、差分フレーム:30) 
>4,30,(キー番号:4、差分フレーム:30)  
>この3つが一気に保存されるということで合ってますでしょうか?

いえ、差分なので、同時だと差分フレームは0になるはずです。
私が最初に書いたプログラムは、ゲームが始まってからのフレーム数なので、次第に増えますが、
差分フレームは、前に変化があったフレーム数から何フレームかということなので、
同時なら0です。

ですから、フレーム数を数える処理が必要ですね。
まずは、データを小さくするより解りやすい方法で一度実装してみてはどうでしょう。

差分フレームの話はひとまずおいておいて、
まず私が最初に書いたようにフレーム番号で管理してみて下さい。

添付ファイルはまだザッとしか見ていませんが、
nowKeyStateは押している間加算される仕様ですか?
それならchar型だと2秒で溢れてしまいますよ。(128までしか数えられない)
unsigned intが必要です。

保存したデータの情報は「押下状態が変わった」だけですから、どれ位押されているかは解りません。
ここでいうならば
GetJoypadInputStateでとってくるPadInputの状態を変化させるための情報であり、
どれ位入力され続けているかはまた別に計算する必要があります。

読み込み・適用部と入力カウント計算部は関数で分けた方がわかりやすいかもしれませんね。


1,190ポイント を手に入れた。

Name: レイ  ..かけだし(2,047ポイント)   Date: 2010/06/13(日) 21:01   No:54252     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
>私が最初に書いたようにフレーム番号で管理してみて下さい。 

管理人さんの詳しい説明でビットの知識がかなり身に付きましたので
管理人さんの作って下さったサンプルを使って龍神録のkey.cppを変えてみました。

添付ファイルがそれです。
メイン関数の部分は管理人さんのサンプルと同じです。

とりあえず分かりやすい実装とアドヴァイスを頂いたので
このソースでは差分フレームはまだ行ってないです。
フレーム番号と、ボタン番号のみ保存して、読み込むというものです。

nowKeyStateは、加算される仕様は溢れてしまうと教えて頂いたので取りやめました。
nowKeyState[configpad.up]=1;とすると、メモリーエラーがなくなって大丈夫でした。

しかし、リプレイの録画した自機の動きが
再生したものと異なる動きをしてしまいます。

すみません…ご指摘お願いいたします…。 編集済み


299ポイント を手に入れた。

Name: スキマ妖怪  ..かけだし(1,469ポイント)   Date: 2010/06/14(月) 02:51   No:54284     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
すいません…、多分私が元凶です;


> しかし、リプレイの録画した自機の動きが 
> 再生したものと異なる動きをしてしまいます。 

ReadKeyChangeState関数内の

pad_key[KeyNum]++;

が原因ではないでしょうか。
押されていないキーに対しては、

pad_key[KeyNum] = 0;

とかしないと足しっ放しになってまずくないですか。
間違っていたらすいません


2倍のポイントを手に入れた! 162ポイント を手に入れた。

Name: レイ  ..かけだし(2,090ポイント)   Date: 2010/06/16(水) 14:23   No:54489 解決!     
Title: Re:リプレイデータでキー入力の変化を記録する方法    
できました!
差分フレームでのリプレイ記録、及び再生まできっちり完成しました。
これはかなりいいですね。

ありがとうございました!


43ポイント を手に入れた。



Name: Ultimate  ..中級者(10,184ポイント)   Date: 2010/06/15(火) 23:15   No:54456       
Title: 1つのプロジェクトに2つ以上のcppファイルを使う方法    
龍神録では、かなり多くのcppファイルに分かれています。

僕は、今まですべて1つのcppファイルの中でやってきたので、2つ以上で使う方法がわかりません。

分けたりするときはexternなどを使うようですが、2つ以上にcppを分けて使うために必要な関数はどんな感じでしょうか?

また、そういうことについて書いてあるページがあったら教えてください。

なかなか分かりやすいサイトが見つからず困っています。


202ポイント を手に入れた。


Name: たかぎ [URL]  ..ハッカー(207,593ポイント)   Date: 2010/06/15(火) 23:21   No:54459     
Title: Re:1つのプロジェクトに2つ以上のcppファイルを使う方法    
> 2つ以上にcppを分けて使うために必要な関数はどんな感じでしょうか? 

とくに必要な関数というのはないと思いますよ。

> なかなか分かりやすいサイトが見つからず困っています。 

しっかりした書籍を読んだ方がよいと思います。


48ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(96,130ポイント)   Date: 2010/06/15(火) 23:40   No:54461     
Title: Re:1つのプロジェクトに2つ以上のcppファイルを使う方法    
判りやすいサイト
http://www7b.biglobe.ne.jp/robe/cpphtml/index.html


31ポイント を手に入れた。

Name: シエル  ..中級者(9,207ポイント)   Date: 2010/06/15(火) 23:53   No:54462     
Title: Re:1つのプロジェクトに2つ以上のcppファイルを使う方法    
前にUltimateさんには苦しんで覚えるC言語を紹介させていただきました。

苦しんで覚えるC言語にはファイル分割についても、ある程度詳しく載っています。
早くゲームを作りたいというお気持ちは分かりますが、基本は大事です。
もう一度復習しなおしてきて、分からないところがあれば、具体的に質問して下さい。 編集済み


97ポイント を手に入れた。

Name: Ultimate  ..中級者(10,295ポイント)   Date: 2010/06/16(水) 06:15   No:54471 解決!     
Title: Re:1つのプロジェクトに2つ以上のcppファイルを使う方法    
苦しんで覚えるC言語にもあったんですね。

Googleで直接調べていて、それでなかなか分かりやすいところがなかったから質問しました。

ロベールのC++教室や、その他の本も必要に応じて参考にしようと思います。

ありがとうございました。


111ポイント を手に入れた。

Name: softya [URL]  ..ハッカー(182,347ポイント)   Date: 2010/06/16(水) 13:20   No:54485     
Title: Re:1つのプロジェクトに2つ以上のcppファイルを使う方法    
>ロベールのC++教室や、その他の本も必要に応じて参考にしようと思います。 

あれ?今までのやりとりの記憶からすると基本的にC言語の文法の範囲で開発されていませんでしたか?
ここやDXライブラリのサンプルは大半C言語の文法にC++の便利なところをちょっと利用した感じのソースになっていると思いますので、C言語の文法を理解した範囲で扱えます。
今の理解の状態でC++のサイトなどを見ると中途半端な理解に混乱が増えるだけだと思いますのでC++に手をだすのは避けることをお勧めします。
特に「ロベールのC++教室」は既に内容的に古いので、そのままコンパイルが通らない問題もあります。C++をちゃんとやるならちゃんとした入門書を購入してください。

「明解C++」
http://www.bohyoh.com/Books/MeikaiCPP/index.html
「独習C++」
http://www.amazon.co.jp/gp/product/4798103187/
「ロベールのC++入門」 ← サイトと違い最新に合わせています。
http://www.amazon.co.jp/dp/4839926050/

当然ながらC++は、C言語に比べて覚えることが沢山増えます。


413ポイント を手に入れた。

Name: たかぎ [URL]  ..ハッカー(207,997ポイント)   Date: 2010/06/16(水) 13:29   No:54486     
Title: Re:1つのプロジェクトに2つ以上のcppファイルを使う方法    
C++はC++でも、ベターCに特化した入門書とか解説サイトがあってもよい気がしますね。
時間ができたら作ってみようかな。
それとも、Wikiでも立ち上げて、みんなでよってたかって作るというのもよいかもしれませんね。


79ポイント を手に入れた。

Name: softya [URL]  ..ハッカー(182,395ポイント)   Date: 2010/06/16(水) 13:33   No:54487     
Title: Re:1つのプロジェクトに2つ以上のcppファイルを使う方法    
>それとも、Wikiでも立ち上げて、みんなでよってたかって作るというのもよいかもしれませんね。 
DXライブラリ使用前提のベターCって感じならWikiが良いかも知れませんね。


48ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(96,488ポイント)   Date: 2010/06/16(水) 13:36   No:54488     
Title: Re:1つのプロジェクトに2つ以上のcppファイルを使う方法    
> あれ?今までのやりとりの記憶からすると
> 基本的にC言語の文法の範囲で開発されていませんでしたか?

cppファイルということでしたので、C++のサイトを紹介しましたが、
あまり区別を意識していないのでしょうね。私も覚えたての頃はそうでした。
それどころかCとC++とMFCとWin32APIの区別も付かずに使ってたし。


> 特に「ロベールのC++教室」は既に内容的に古いので、
> 「ロベールのC++入門」 ← サイトと違い最新に合わせています。

そうでしたか。サイトは昔お世話になったのですが。
最近本になったのは知っていましたが購入はしていません。
フォローありがとうございました。


74ポイント を手に入れた。



Name: shiro4ao  ..初心者(5,421ポイント)   Date: 2010/06/15(火) 20:34   No:54432       
Title: 受信時のスピンロック回避方法    
ソケット(sock1)からのデータをもう一方のソケット(sock2)に送るスレッドを作りたいです。
以下のコードで一応できたのですがCPU使用率が100%になってしまいます。

DWORD WINAPI Thread1(LPVOID lpvoid ) {
   while{
        char   tmp1[1024];
    int ret1;
    while((ret1=recv(sock1, tmp1,1000, 0))>0){
        send(sock2,tmp1,ret1, 0);        
    }
    ExitThread(TRUE);
    }
}

スピンロックになっているようですが、なにか解決策はありますでしょうか。
あまりにも長いため全ソースコードはお見せできませんが出来る限りご質問にはお答えしたいと
思います。 編集済み


248ポイント を手に入れた。


Name: シエル  ..中級者(9,110ポイント)   Date: 2010/06/15(火) 20:37   No:54433     
Title: Re:無題    
少しSleepして間隔を空けた方がいいのでは?

18ポイント を手に入れた。

Name: shiro4ao  ..初心者(5,543ポイント)   Date: 2010/06/15(火) 20:50   No:54434     
Title: Re:無題    
通信内容の問題があり、sleep()できないのです・・・・
やはりCPU100%でrecv()させるしかないのでしょうか・・・・
非同期で似たようななものを作ったのですが(FD_READが来たら送る)
sock1からsock2のデータ送信中にsock2からsock1へのデータが来たら
上手くいかない(?)ような感じでした。

追伸:先の質問(文字列をわけて配列に入れる)が解決いたしました
   ありがとうございました。


122ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(545,822ポイント)   Date: 2010/06/15(火) 21:11   No:54441     
Title: Re:無題    
 ブロッキングモードですか?
 その 100%になっているとき常に send関数を通過していますか?


27ポイント を手に入れた。

Name: shiro4ao  ..初心者(5,824ポイント)   Date: 2010/06/15(火) 21:15   No:54442     
Title: Re:無題    
プログラムは非同期で作っており、右から左へ受け流す部分がメインとは別の
スレッドになっています。
100%になってしまうと送信しなくても100%から戻ってこないようでした。


61ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(545,822ポイント)   Date: 2010/06/15(火) 21:37   No:54443     
Title: Re:無題    
>100%になってしまうと送信しなくても100%から戻ってこないようでした
 ということはデータが来ていない状態で recvが呼ばれ続けている、ポーリング状態になっている
わけですね。

 selectを使うとかブロッキングモードにしてみてはどうでしょう?


Name: shiro4ao  ..初心者(5,852ポイント)   Date: 2010/06/16(水) 10:56   No:54477 解決!     
Title: Re:無題    
通信の確実さは犠牲にしてでも非同期モードで送信させてみます。
ありがとうございました。 編集済み


28ポイント を手に入れた。



Name: Ultimate  ..初心者(7,212ポイント)   Date: 2010/06/13(日) 21:45   No:54256       
Title: パソコン画面を動画で保存するには?    
Dixqさんの作った***の館などのページには、よくパソコン画面の動画があります。

例:http://dixq.net/rp/15.html

どのように保存したのでしょうか?

僕はPrint Screenしか知らないので・・・

C言語何でも質問から少し外れた内容で済みませんが教えてください。


120ポイント を手に入れた。


Name: fatens  ..中級者(13,154ポイント)   Date: 2010/06/13(日) 22:12   No:54259     
Title: Re:パソコン画面を動画で保存するには?    
Captured by Dxtoryとありますので、Dxtoryというソフトを使ったことが分かります。

ほかにもVectorなどで調べてみると良いのではないでしょうか。

 編集済み


54ポイント を手に入れた。

Name: Ultimate  ..初心者(7,268ポイント)   Date: 2010/06/14(月) 16:03   No:54328 解決!     
Title: Re:パソコン画面を動画で保存するには?    
ソフトを使うんですね。

カハマルカ(?)の瞳っていうのをダウンロードしてみました。

VISTAでしっかり動くようです。

ありがとうございました。


56ポイント を手に入れた。

Name: Dixq (管理人)  ..ウィザード(1,213,286ポイント)   Date: 2010/06/14(月) 17:57   No:54333     
Title: Re:パソコン画面を動画で保存するには?    
Dxtoryいいですよ。
気に入って購入しました。
気に入ったらなるべく買うようにしています。
落ち込んでいるソフトウェア業界の発展のために…


50ポイント を手に入れた。

Name: Ultimate  ..中級者(9,687ポイント)   Date: 2010/06/14(月) 18:27   No:54346     
Title: Re:パソコン画面を動画で保存するには?    
Dxtoryは有料のようですね。

中2で、プログラミングは趣味なのでフリーソフトを使います。


38ポイント を手に入れた。

Name: Ma  ..ハッカー(104,399ポイント)   Date: 2010/06/16(水) 08:29   No:54474     
Title: Re:パソコン画面を動画で保存するには?    
Dixtory は無償版の場合宣伝が大きすぎる・・・
アマレコをおすすめします。
次にCamStudio もおすすめ。


27ポイント を手に入れた。

Name: Dixq (管理人)  ..ウィザード(1,213,736ポイント)   Date: 2010/06/16(水) 08:56   No:54475     
Title: Re:パソコン画面を動画で保存するには?    
Camいいですよね。
私はゲームキャプチャはDxtory、デスクトップキャプチャはCam使ってます。
DxtoryはDirectxかGLじゃないとキャプチャ出来ないのが難点ですねぇ


74ポイント を手に入れた。



Name: 夏天  ..初心者(7,051ポイント)   Date: 2010/06/15(火) 15:37   No:54416       
Title: DirectXのウィンドウ切り替え    
[1] 質問文
現在DirectX SDK 2010(Feb)を使ってゲームプログラムを書いているのですが、
Alt+Enterで画面モードを切り替えるというものを作っています。
ですが画面モード自体は切り替えることはできたのですが、
切り替えた後クライアントエリアが真っ白になってしまいます。
いろいろ調べまわった結果、デバイスを作り直すというものを見つけたのですが、
内容がまったくわからない状態です。

 [1.1] やりたいこと:画面モードの切り替え
 [1.2] ソースコード:添付ファイルを参照
 [1.3] 躓いているところ:切り替え後、再描画されず画面が真っ白
 [1.4] 知りたいところ:画面モードの切り替え方法、デバイスの再構築
      
[2] 環境  
 [2.1] OS : WindowsXP SP2
 [2.2] コンパイラ名 : VS2008
[3] その他 
 ・習熟度:高校3年間C言語で簡単なコンソールプログラムを作っていた程度
 ・DirectX SDK (February 2010)を使用しています


272ポイント を手に入れた。


Name: fr  ..ぴよぴよ(266ポイント)   Date: 2010/06/15(火) 17:29   No:54421     
Title: Re:DirectXのウィンドウ切り替え    
あ、すみませんデバイスロストと混同してました。
フルスクリーンとの切替はデバイスの初期化だけでいいです。 編集済み


239ポイント を手に入れた。

Name: toyo  ..熟練のプログラマー(49,409ポイント)   Date: 2010/06/15(火) 17:41   No:54422     
Title: Re:DirectXのウィンドウ切り替え    
まずdirextx.cppのInit3D( )関数内の
D3DPRESENT_PARAMETERS   d3dpp;
をグローバル変数にします
また同関数内で
    d3dpp.BackBufferWidth    = 800;
    d3dpp.BackBufferHeight    = 600;
のように全画面時の解像度を指定しておきます

画面モード変更時にすること
1. draw.cppのInitialize( )関数で確保した頂点バッファg_pVBを開放
    RELEASE(g_pVB);
または
    Close(NULL);
2. d3dpp.Windowedを反転
    d3dpp.Windowed = !d3dpp.Windowed;
3. デバイスを変更したウィンドウモードでリセット
    g_pD3DDev->Reset(&d3dpp);
4. 頂点バッファを作成しなおす
    Initialize(g_pD3DDev);
になります


112ポイント を手に入れた。

Name: 夏天  ..初心者(7,599ポイント)   Date: 2010/06/15(火) 23:12   No:54453 解決!     
Title: Re:DirectXのウィンドウ切り替え    
すばやい解答ありがとうございます

>>fr様
デバイス再構築をせずに初期化だけでよかったのですね^^;
今後気をつけます><

>>toyo様
なんとか自分の求めていた結果になりました
ありがとうございます!

一応ChangeMode関数を貼っておきます
void ChangeMode(HWND hwnd)
{
    DEVMODE dv;
    Close(NULL);
    d3dpp.Windowed = !d3dpp.Windowed;
    g_bWindowMode = !g_bWindowMode;
    ShowCursor(g_bWindowMode);

    if (g_bWindowMode) {
        ShowWindow(hwnd, SW_HIDE);
        
        ChangeDisplaySettings(NULL, 0);

        SetWindowLongPtr(hwnd, GWL_STYLE, g_dwWindowStyle);
        SetWindowPos(hwnd, HWND_NOTOPMOST, g_rcWindow.left, g_rcWindow.top, g_rcWindow.right - g_rcWindow.left, g_rcWindow.bottom - g_rcWindow.top, 0);    
    }
    else {
        GetWindowRect(hwnd, &g_rcWindow);

        SetWindowLongPtr(hwnd, GWL_STYLE, WS_POPUP);
        SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, g_cxClient, g_cyClient, 0);
        
        dv.dmSize       = sizeof(DEVMODE);
        dv.dmFields     = DM_PELSWIDTH | DM_PELSHEIGHT;
        dv.dmPelsWidth  = g_cxClient;
        dv.dmPelsHeight = g_cyClient;
        ChangeDisplaySettings(&dv, CDS_FULLSCREEN);
    }
    g_pD3DDev->Reset(&d3dpp);
    Initialize(g_pD3DDev);

    SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
    
    ShowWindow(hwnd, SW_SHOW);
}


548ポイント を手に入れた。



Name: たろう  ..プログラマー(26,216ポイント)   Date: 2010/06/13(日) 07:04   No:54181       
Title: 無題    
何度も質問すみません。
あの、例えば原点(50,50)から円を描くようにしたいのですが、うまくいきません。どうしたらうまく円を描くようにできるのでしょうか?
void enemy_pattern3(int i)
{
    float x=enemy[i].x,y=enemy[i].y;
    if(enemy[i].cnt==0)
    {
        enemy[i].ang=0;
        enemy[i].vy=2;
        enemy[i].vx=0;
        enemy[i].sp=0;
        return;
    }
    if(enemy[i].cnt==20)
    {
        enemy[i].x=((enemy[i].x-enemy[i].gentenx)*cos(-2*PI/180)-(enemy[i].y)*sin(-2*PI/180));
        enemy[i].y=(enemy[i].x*sin(-2*PI/180)+(enemy[i].y)*cos(-2*PI/180));                
    }
}

よろしくお願いします。


202ポイント を手に入れた。


Name: Dixq (管理人) [URL]  ..ウィザード(1,212,046ポイント)   Date: 2010/06/13(日) 09:19   No:54186     
Title: Re:無題    
少しずつ近づけてみてはどうでしょう?
まずは原点(0,0)を中心に半径300の円を描くプログアムを作ってみてはどうでしょう。
それから中心を移動させたりしてみて下さい。

Θを角度、rを半径だとすると

x = cos(Θ) * r;
y = sin(Θ) * r;

でx,y座標が決まりますよね。
角度はenemyの持つカウンタcntで増加させてやればOKです。


121ポイント を手に入れた。

Name: Tatu  ..プログラマー(37,850ポイント)   Date: 2010/06/13(日) 09:53   No:54187     
Title: Re:無題    
出現して20カウント後に円の中心(50,50)の左にいて、
そこから反時計回りにまわり、180カウントごとに一周するとき、
円の中心から敵への角度angleを考えます。

20カウント経過したときangle=PIで
それ以降は1カウントごとにPI2/180だけ小さくなる。

よって、20カウント以上のとき
angle=PI-PI2/180*(enemy[i].cnt-20)となります。

後は20カウント以上のときに
円の中心の座標に
円の半径と中心からの角度から計算できる円の中心に対する敵の位置を
足せば求める敵の座標になります。


あと、別のやり方で、
等速円運動は速さが変わらず、方向の変化が一定な運動だといえるので、

下に直進後、等速円運動する関数は
void enemy_pattern3(int i){
    if(enemy[i].cnt==0){
        enemy[i].sp=5;
        enemy[i].ang=PI/2;
    }
    if(enemy[i].cnt==20){
        enemy[i].sp=2;
    }
    if(enemy[i].cnt>20){
        enemy[i].ang-=PI2/180;
    }
}

のようにかくことができます。


432ポイント を手に入れた。

Name: たろう  ..プログラマー(26,237ポイント)   Date: 2010/06/13(日) 12:31   No:54198     
Title: Re:無題    
 Dixq (管理人)Tatuさん回答ありがとうございます。
Tatuさんのおかげでできたのですが、
画像のように移動したいのですがどうすればよいでしょうか?


21ポイント を手に入れた。

Name: Tatu  ..プログラマー(37,885ポイント)   Date: 2010/06/13(日) 13:51   No:54203     
Title: Re:無題    
Dixqさんの提案したプログラムを
書かずに「できた」と書きこんだということは
enemy[i].spとenemy[i].angを使うやり方に
切りかえたということでよいでしょうか?

それでは、
(1)直進が終わった直後の速さと角度はいくつにすればよいでしょうか?

(2)向きが変わるときのenemy[i].cntをはじめから4つ以上書いてください。
そしてこれらの値にどのような関係があるのかを考えてみてください。

(3)向きが変わるときに敵の移動する方向を逆向きにする方法、
その後の移動方向の変化はどうなるかわかりますか?

これらを考えてもわからなかったら自分で考えたものを実行してどうなるか試してみてください。


35ポイント を手に入れた。

Name: たろう  ..プログラマー(26,953ポイント)   Date: 2010/06/13(日) 18:40   No:54243     
Title: Re:無題    
回答ありがとうございます。
>(1)直進が終わった直後の速さと角度はいくつにすればよいでしょうか? 
角度は2度ずつで速さは2です。
プログラム組んでみたのですが、
ただenemy[i].xとenemy[i].yでやるのでできればこれをenemy[i].angとenemy[i].spでするにはどうすればよいのでしょうか?
ソースは以下です。
void enemy_pattern2(int i)
{
    float x=enemy[i].x,y=enemy[i].y;
    if(enemy[i].cnt==0)
    {
        enemy[i].ang=0;
        enemy[i].vy=2;
        enemy[i].vx=0;
        enemy[i].sp=0;
        return;
    }
    if(enemy[i].cnt==20)
    {
        enemy[i].gentenx=enemy[i].x;
        enemy[i].genteny=enemy[i].y;
        return;
    }

    if(enemy[i].cnt==40)
    {
        enemy[i].ang=0;
        enemy[i].vy=0;
        enemy[i].vx=0;
        enemy[i].knd2=1;
        enemy[i].sp=0;
    }
    if(enemy[i].cnt%80==0)
    {
        enemy[i].ang=0;
        enemy[i].vy=0;
        enemy[i].vx=0;
        enemy[i].knd2=2;
        enemy[i].sp=0;
    }
    if(enemy[i].cnt%160==0)
    {
        enemy[i].ang=0;
        enemy[i].vy=0;
        enemy[i].vx=0;
        enemy[i].knd2=1;
        enemy[i].sp=0;
    }

    
    switch(enemy[i].knd2)
    {
    case 1:
        x=((enemy[i].x-enemy[i].gentenx)*cos(PI2/180)-(enemy[i].y-enemy[i].genteny)*sin(PI2/180))
                    +enemy[i].gentenx;
        y=((enemy[i].x-enemy[i].gentenx)*sin(PI2/180)+(enemy[i].y-enemy[i].genteny)*cos(PI2/180))
                    +enemy[i].genteny;
        break;
    case 2:
        x=((enemy[i].x-enemy[i].gentenx)*cos(-PI2/180)-(enemy[i].y-enemy[i].genteny)*sin(-PI2/180))
                    +enemy[i].gentenx;
        y=((enemy[i].x-enemy[i].gentenx)*sin(-PI2/180)+(enemy[i].y-enemy[i].genteny)*cos(-PI2/180))
                    +enemy[i].genteny;
        break;
    }
    enemy[i].x=x,enemy[i].y=y;
}


716ポイント を手に入れた。

Name: たろう  ..プログラマー(26,974ポイント)   Date: 2010/06/13(日) 23:50   No:54269     
Title: Re:無題    
やっぱりangやspだけではできないのでしょうか?1

21ポイント を手に入れた。

Name: Tatu  ..プログラマー(39,339ポイント)   Date: 2010/06/14(月) 01:36   No:54283     
Title: Re:無題    
angとspでできるかどうかですが答えは「できます。」
しかし、どのようにすればよいのかを直接は書きません。
理由はさっきの場合はangとspを用いる方法があるということを示すために関数を書きましたが
それでは、今のように自分で書くことができないからです。

さて、どうやらenemy[i].angとenemy[i].spを使うとどのように動くのかを
全く分かってなく、試してすらいなさそうな感じがするので問題を出します。
(vyをつかっているということは座標の計算をどこで行っているかはわかっていますよね?)

次のような時、enemy[i].angとenemy[i].spはどのようになるでしょうか。
これらにどのように代入すればよいのかを答えてください。
考えるとき、時計回りが正になっていることに注意してください。
enemy[i].vxとenemy[i].vyならどうなるかは今は考えないでください。

enemy[i].angに入る値の単位はラジアンで
1°=PI/180ラジアンの関係があります。

a)右向きに動き、速さは3

b)下向きに動き、速さは1 

c)左下に動く、このとき右向きとなす角の大きさは135°、速さは4

d)右上に動く、このとき右向きとなす角の大きさは30°、速さは5

角度があっているかどうかは
void enemy_pattern2(int i){
    if(enemy[i].cnt==0){
        enemy[i].ang=???;
        enemy[i].sp=???;
    }
}
の???に代入して実行すればわかります。


(1)については実は速さはどうでもよいです。
しかし、移動方向は真横になります。
右向き、左向きを表す角度はそれぞれいくつでしょうか。
これらのどちらかであれば真横になります。

これらがわかるならば
2度ずつと書かれているので(2)は
角度の変化の大きさを2°として考えてみてください。
直進後、最初に向きを逆にするまでに変化する角度はいくらになるか、
向きを逆にしたのち、次に向きが逆になるまでに変化する角度はいくらになるかを考えるとよいでしょう。



625ポイント を手に入れた。

Name: たろう  ..プログラマー(28,676ポイント)   Date: 2010/06/14(月) 13:33   No:54310     
Title: Re:無題    
返信ありがとうございます。
>右向き、左向きを表す角度はそれぞれいくつでしょうか。 
右向きは0度で左の向きは180度ですよね?
enemy[i].angを2度ずつとやって逆を-2度ずつとやったのですが、S字を描くように移動します。
どうしたらよいのでしょうか?ソース載せます。
void enemy_pattern3(int i){ 
    if(enemy[i].cnt==0){ 
        enemy[i].sp=2; 
       // enemy[i].ang=PI/2;
        return;
    } 
    if(enemy[i].cnt==20){ 
        enemy[i].sp=2; 
    } 
    if(enemy[i].cnt==40){ 
        enemy[i].sp=1; 
        enemy[i].knd2=1;
    } 
    if(enemy[i].cnt%80==0)
    {
        enemy[i].sp=2;
        enemy[i].knd2=1;    
    }
    if(enemy[i].cnt%160==0)
    {
        enemy[i].sp=-2;
        enemy[i].knd2=2;
    }

    switch(enemy[i].knd2)
    {
    case 1:
        enemy[i].ang-=PI2/180;
        break;
    case 2:
        enemy[i].ang+=PI2/180;
        break;
    }
} 



387ポイント を手に入れた。

Name: たろう  ..プログラマー(28,837ポイント)   Date: 2010/06/14(月) 13:54   No:54313     
Title: Re:無題    
すみません。enemy[i].ang-=PI2/180;
でなぜ円を描くように動くのでしょうか?
enemy[i].ang=-PI2/180ではなぜ円を描かない動きになってしまうのでしょうか?
enemy[i].ang=-PI2/180で円を描くなら納得するのですが。どうもしっくりきません。


114ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(95,304ポイント)   Date: 2010/06/14(月) 14:00   No:54317     
Title: Re:無題    
"-="と"=-"の違いには気付いているのですよね?
それぞれ、次の意味です。

enemy[i].ang = enemy[i].ang - PI2/180;
enemy[i].ang = -PI2/180;

前者は角度が-2度ずつ変わっていきますが、
後者は常に-2度を代入しています。
回転するのはどっちですか?


95ポイント を手に入れた。

Name: たろう  ..プログラマー(29,061ポイント)   Date: 2010/06/14(月) 14:30   No:54322     
Title: Re:無題    
>"-="と"=-"の違いには気付いているのですよね? 
>それぞれ、次の意味です。 

>enemy[i].ang = enemy[i].ang - PI2/180; 
>enemy[i].ang = -PI2/180; 
前者それはわかるのですが、
あっわかりました。すみませんでした。なんか勘違いしていました。
enemy[i].ang = enemy[i].ang - PI2/180; 
で毎回拡大して回転しているのかと思っていましたが、
enemy[i].ang = -PI2/180;だと2度固定されると言うことですね。ということで回転はしない。
わかっていませんでした。変な質問してすみませんでした。


149ポイント を手に入れた。

Name: たろう  ..プログラマー(29,573ポイント)   Date: 2010/06/14(月) 16:26   No:54329     
Title: Re:無題    
ソースを変更しました。
void enemy_pattern3(int i){ 
    if(enemy[i].cnt==0){ 
        enemy[i].sp=5; 
        
        return;
    } 
    if(enemy[i].cnt==20){ 
        enemy[i].sp=5; 
        enemy[i].ang=PI2;
    } 

    if(enemy[i].cnt%80==0)
    {
        enemy[i].sp=1;
        enemy[i].knd2=1;    
    }
    if(enemy[i].cnt%160==0)
    {
        enemy[i].sp=1;
        enemy[i].knd2=2;
    }

    switch(enemy[i].knd2)
    {
    case 1:
        enemy[i].ang-=PI2/180;
        break;
    case 2:
        enemy[i].ang+=PI2/180;
        break;
    }
}

enemy[i].ang=PI2;
何ですけど、縦90度に移動するにはenemy[i].ang=PI/2だとはわかっているんですが、
enemy[i].ang=PI2;にしないと縦に動いてくれないのでこれにしました。原因は不明です。
enemy[i].angはこのほかには代入計算をしていないのはずなんですが・・・

このプログラムで実行すると横にSを描いたような動きになってしまいます。
画像のような動きについて、ヒントでもよいので、ご教授よろしくお願いします。


491ポイント を手に入れた。

Name: たろう  ..プログラマー(29,693ポイント)   Date: 2010/06/14(月) 17:23   No:54332     
Title: Re:無題    
Tatuさんの問題やっていませんでした。
a)右向きに動き、速さは3 
enemy[i].ang=0;
enemy[i].sp=3
b)下向きに動き、速さは1  
enemy[i].ang=PI/2;
enemy[i].sp=1;
c)左下に動く、このとき右向きとなす角の大きさは135°、速さは4 
enemy[i].ang=PI*3/4;
enemy[i].sp=4
d)右上に動く、このとき右向きとなす角の大きさは30°、速さは5 
enemy[i].ang=PI/6;
enemy[i].sp=5;
です。


120ポイント を手に入れた。

Name: Tatu  ..プログラマー(39,717ポイント)   Date: 2010/06/14(月) 19:55   No:54363     
Title: Re:無題    
角度とスピードの問題については
d)の角度は右上に進むとしているのでPI/6ではなく、-PI/6であるということ以外はあっているので
ほぼ角度とスピードについては理解しているとわかりました。
今はS字を描くように動いているということなので行ったり来たりする動きはそろそろできるでしょう。
また、S字を描くように動かすにはどうすればよいかがこれでわかりましたね?

さて、プログラムの一部を取り出すと

    if(enemy[i].cnt%80==0)
    {
        enemy[i].sp=1;
        enemy[i].knd2=1;    
    }
    if(enemy[i].cnt%160==0)
    {
        enemy[i].sp=1;
        enemy[i].knd2=2;
    }

となっていますが
この書き方ではenemy[i].cntが0,160,320,...のときに
二つのif文の条件を両方とも満たしてしまい、
両方の処理が行われます。

両方の処理が行われるということがないようにするには
どうすればよいでしょうか?
この場合、enemy[i].cntが80,240,400,...の時に
一つ目のif文の条件を満たすようにすればよさそうですね。

if文の条件を変えたら今度は
動きを変えるときに逆向きにするにはそのときに角度をどう変化させればよいかを考えてください。
この時、ある向きとそれに対して逆の向きの間にはどのような関係があるかを考えてください。



378ポイント を手に入れた。

Name: たろう  ..プログラマー(29,522ポイント)   Date: 2010/06/14(月) 20:39   No:54371     
Title: Re:無題    
返信ありがとうございます。
>動きを変えるときに逆向きにするにはそのときに角度をどう変化させればよいかを考えてください。 
逆向きにするのはenemy[i].angを+=から−=にした時、逆向きになるんですよね?

>この時、ある向きとそれに対して逆の向きの間にはどのような関係があるかを考えてください。 
ある向きに対して逆向きには角度が違う?
すみません。わかりません。


171ポイント を落としてしまった。

Name: たろう  ..プログラマー(29,662ポイント)   Date: 2010/06/14(月) 20:42   No:54372     
Title: Re:無題    
>両方の処理が行われるということがないようにするには 
>どうすればよいでしょうか? 
>この場合、enemy[i].cntが80,240,400,...の時に 
>一つ目のif文の条件を満たすようにすればよさそうですね。 
if(enemy[i].cnt%80==0 && enemy[i].cnt%160!=0)
{}
でしょうか?


140ポイント を手に入れた。

Name: たろう  ..プログラマー(29,727ポイント)   Date: 2010/06/14(月) 21:05   No:54374     
Title: Re:無題    
ソース変えたので載せます。
void enemy_pattern3(int i){ 
    if(enemy[i].cnt==0){ 
        enemy[i].sp=5; 
        enemy[i].ang=PI/2;
        return;
    } 
    if(enemy[i].cnt==20){ 
        enemy[i].sp=5; 
        
    } 

    if(enemy[i].cnt%80==0 && enemy[i].cnt%160!=0)
    {
        enemy[i].sp=1;
        enemy[i].knd2=1;    
    }
    if(enemy[i].cnt%160==0)
    {
        enemy[i].sp=-1;
        enemy[i].knd2=2;
    }

    switch(enemy[i].knd2)
    {
    case 1:
        enemy[i].ang+=PI2/180;
        break;
    case 2:
        enemy[i].ang-=PI2/180;
        break;
    }
} 

これで画像に近い動きができたのですが、
ただ、画像のように動くのではなく、直進した後すぐに「J」みたいに移動します。


65ポイント を手に入れた。

Name: Tatu  ..熟練のプログラマー(40,527ポイント)   Date: 2010/06/14(月) 22:31   No:54383     
Title: Re:無題    
>>ある向きに対して逆向きには角度が違う?
では、その違いはどういうものでしょうか?

右向き(0)の反対は左向き(PI)で
下向き(PI/2)の反対は上向き(PI*3/2)で
上向き(PI*3/2)の反対は下向きだけど
ある角度にPI2の整数倍を足した角度は同じ方向を指すから
下向きはPI/2だけではなく、PI*5/2でもあらわすことができる。

これらからどのように変化させればよいかわからないでしょうか?

速さに−をかけるのも一つの手段ではあります。


if文の条件
それでもよいですが、
if(enemy[i].cnt%160==80)と書くと考えてました。


>>jの字の形に動く。
ここでenemy[i].cntがいくつの時に向きとenemy[i].knd2がどうなるのかが
問題になるのですが

まず、直進が終わってから何カウントのとき向きが変化するでしょうか。
いちばん最初が40カウントだとすれば、最初からその次までは40カウントの二倍かかるから120カウントになります。
それ以降は200,280,....のときに向きが変わります。

これと最初の20カウントが直進であることを考えると
enemy[i].cntが60,140,220,300,...のときに向きが変わる(enemy[i].sp *= -1 もしくは enemy[i].ang += PI)ことになります。

enemy[i].cntが20のときenemy[i].sp=1, enemy[i].ang=0, enemy[i].knd2=2(反時計回り)とすれば
enemy[i].cntが60,220,380,...のときにenemy[i].knd2が1(時計回り)になり、
enemy[i].cntが140,300,460,...のときにenemy[i].knd2が2(反時計回り)になります。


692ポイント を手に入れた。

Name: たろう  ..プログラマー(29,756ポイント)   Date: 2010/06/14(月) 23:04   No:54393 解決!     
Title: Re:無題    
回答ありがとうございます。おかげでできました。
本当にありがとうございました。


29ポイント を手に入れた。

Name: Tatu  ..熟練のプログラマー(40,755ポイント)   Date: 2010/06/14(月) 23:18   No:54395     
Title: Re:無題    
解決したようでよかったです。

最後に私が書いたプログラムです。

void enemy_patternT1(int i){
    if(enemy[i].cnt==0){
        enemy[i].sp=5;
        enemy[i].ang=PI/2;
    }
    if(enemy[i].cnt==20){
        enemy[i].sp=2;
        enemy[i].ang=0;
    }
    if(enemy[i].cnt>20){
        if( (enemy[i].cnt+25)%90==0 ){
            enemy[i].ang+=PI;
        }
        if( (enemy[i].cnt+25)%180<90){
            enemy[i].ang-=PI2/180;
        }
        else{
            enemy[i].ang+=PI2/180;
        }
    }
}



228ポイント を手に入れた。

Name: たろう  ..プログラマー(29,881ポイント)   Date: 2010/06/15(火) 01:04   No:54397     
Title: Re:無題    
そのソースで
if((enemy[i].cnt+25)%180<90)
{
    enemy[i].ang-=PI/180;
}else{
    enemy[i].ang+=PI/180;
}

とやってみたんですが、時計周りに90度回転してそして反時計回りに90度回転すると思ったのですが、
ちゃんと180度回転します。なぜなのでしょうか?


125ポイント を手に入れた。

Name: Tatu  ..熟練のプログラマー(41,048ポイント)   Date: 2010/06/15(火) 15:24   No:54415     
Title: Re:無題    
角度の変化は たろう さんが考えているとおり、90度しか変わっていません。
これは向きを変える前後の向きを見ればわかります。

同じ弧を同じ速さで90度回転させたいのならば向きを変えるタイミングを変えることになるので
if文の条件が変わります。


説明しませんでしたが
条件をif((enemy[i].cnt+25)%180<90)としている理由は以下の通りです。

まず往復の周期を180としたく、その半分の間だけ条件を満たすようにしたいので
if(???%180<90)
と考えました。

そして、最初に向きを変えるのが20+45=65カウントで
これに25を足すと90カウントになるため、
if((enemy[i].cnt+25)%180<90)とし、
enemy[i].cntが20から65の間にあるときにこの条件を満たすので
この条件でよいことがわかりました。

もし、このとき逆だったら
処理を変えるか、
if((enemy[i].cnt+25)%180>=90)
と書き換えればよいだけです。


また、向きを変える条件を
if((enemy[i].cnt+25)%90==0)としていますが

これはif((enemy[i].cnt+25)%180==0 || (enemy[i].cnt+25)%180==90)が
if((enemy[i].cnt+25)%90==0)と同じ条件になるからです。


293ポイント を手に入れた。

Name: たろう  ..プログラマー(29,903ポイント)   Date: 2010/06/15(火) 18:22   No:54424     
Title: Re:無題    
回答ありがとうございます。
enemy[i].spを上げてもenemy[i].ang-=PI/180は結局90度回転するという認識でよいのでしょうか?


22ポイント を手に入れた。

Name: Tatu  ..熟練のプログラマー(41,104ポイント)   Date: 2010/06/15(火) 19:02   No:54426     
Title: Re:無題    
enemy[i].spをあげて試したらどうなりましたか?
それを見てわからなければenemy[i].ang-=PI2/180のとき
enemy[i].spを変えたらどうなりましたか?


56ポイント を手に入れた。

Name: たろう  ..プログラマー(29,992ポイント)   Date: 2010/06/15(火) 21:05   No:54439     
Title: Re:無題    
>enemy[i].spをあげて試したらどうなりましたか?
>それを見てわからなければenemy[i].ang-=PI2/180のとき 
>enemy[i].spを変えたらどうなりましたか? 


弧を描く長さが長くなりました。
PI/180の時1度90回繰り返されて結局90度回転しているという認識でよいのでしょうか?
何か勘違いしているのでしょうか?


89ポイント を手に入れた。

Name: Tatu  ..熟練のプログラマー(41,104ポイント)   Date: 2010/06/15(火) 22:08   No:54444     
Title: Re:無題    
PI/180 * 90 = PI/2 という考え方でいいですよ。

enemy[i].spを変えて弧の長さが変わっても回転する角度は変わらないということを確認してほしかっただけです。


Name: たろう  ..プログラマー(29,995ポイント)   Date: 2010/06/15(火) 22:10   No:54445     
Title: Re:無題    
そうだったんですか。本当に回答ありがとうございました!

3ポイント を手に入れた。



Name: なんちゃってプログラマ  ..ぴよぴよ(186ポイント)   Date: 2010/06/15(火) 01:06   No:54398       
Title: ifやswitchを使わない条件分岐について    
始めまして。

例えばオミクジのプログラムを作ったとして
普通に書くと
if( kekka == 0 )
{
 printf( "大吉" );
}
else if( kekka == 1 )
{
 printf( "中吉" );
}
else if( kekka == 2 )
{
 printf( "小吉" );
}


と単純なif文が多くなってしまうと思うんですが、それをなるべく短く、かつ見やすく解決する方法って無いでしょうか?
ちなみにこの例だと配列を使えば解決するんですが、それ以外の方法を教えてほしいです。


186ポイント を手に入れた。


Name: たかぎ [URL]  ..ハッカー(207,322ポイント)   Date: 2010/06/15(火) 01:11   No:54399     
Title: Re:ifやswitchを使わない条件分岐について    
短くできるのは条件演算子ですが、決して見やすいとはいえません。
やはり配列にするのが一番では?


14ポイント を手に入れた。

Name: なんちゃってプログラマ  ..ぴよぴよ(415ポイント)   Date: 2010/06/15(火) 01:34   No:54400     
Title: Re:ifやswitchを使わない条件分岐について    
お返事ありがとうございます。
確かに配列を使うと見やすく行くと思うのですが…。
srand( (unsigned int)time(NULL) );
char* s[5] = { "大吉" , "中吉" , "小吉" , "凶" , "大凶" };
printf( "%s\n" , s[ rand() % 5 ] );

この用に単純なプログラムだと良いのですが、C++での開発で
「もし、何々の時にオブジェクトを生成する」といった場合はどの様にしたら良いのでしょう?

製作しているゲームで、外部データを元にオブジェクトを生成させる処理があり、

//    登録されたデータ分生成
for( ; itr != DataContiner.end() ; ++itr )
{
 int type = (*itr).ObjType;
 if( (*itr).ObjType == WALL )
 {
  ObjectSPtr enemy( new Wall( 略 );
  mObjectManager.add( enemy );
 }
 if( (*itr).ObjType == WOODWALL )
 {
  ObjectSPtr enemy( new WoodWall( 略 );
  mObjectManager.add( enemy );
 }
 〜略(この様な処理が30個程…。)〜
}

この様な処理になってしまい、非常に醜い(見にくい)です。

ファクトリーなどの導入も考えましたが、結局の所コードが同じ様な処理になってしまいどうにも参っています。

こういった場合、どうすれば簡潔にかけるでしょうか?


229ポイント を手に入れた。

Name: YuO  ..熟練のプログラマー(47,256ポイント)   Date: 2010/06/15(火) 10:49   No:54406     
Title: Re:ifやswitchを使わない条件分岐について    
素直に実装するなら,
class Object
{
public:
  virtual ObjectSPtr create_enemy() = 0;
};

class WallObject : public Object
{
public:
  ObjectSPtr create_enemy() { return new Wall(); }
};

class WoodWallObject : public Object
{
public:
  ObjectSPtr create_enemy() { return new WoodWall(); }
};
のような継承関係を作っておいて,
for( ; itr != DataContiner.end() ; ++itr ) {
  mObjectManager.add(itr->create_enemy());
}

のように処理することでしょうか。

どこか一箇所switch文かそれに相当するコードが必要になりますが,
それ以降は全部継承を使ってswitch文が不要になります。


2倍のポイントを手に入れた! 214ポイント を手に入れた。

Name: なんちゃってプログラマ  ..ぴよぴよ(510ポイント)   Date: 2010/06/15(火) 20:29   No:54431     
Title: Re:ifやswitchを使わない条件分岐について    
>YuOさん
Wallを生成するのにWallObjectと言うクラスに責任を預けると言う事でしょうか?

やはりクラス数が2倍になっても、ファクトリーの様なものを作ったほうがスマートに書けそうですね。
(というかそれ以外になさそう…w)


95ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(545,795ポイント)   Date: 2010/06/15(火) 20:55   No:54436     
Title: Re:ifやswitchを使わない条件分岐について    
>外部データを元にオブジェクトを生成させる処理があり、
 ObjTypeが整数・列挙型とかで、0から始まっているとするなら

    enum Type { WALL, WOODWALL };
    ObjectSPtr *CreateWall() { return new Wall(); }
    ObjectSPtr *CreateWoodWall() { return new WoodWall(); }

という関数を作っておいて

    const std::pair<Type, ObjectSPtr* (*)()> CreateSptrTbl[] = 
    {
        std::make_pair(WALL, CreateWall),
        std::make_pair(WOODWALL, CreateWoodWall),
    };
というような(手抜きなので pairを使っていますが)テーブルを作ります。
 で、何の型かは不明ですが DataContinerをループで回すときに

    for( ; itr != DataContiner.end() ; ++itr )
    {
        const Type type = (*itr).ObjType;
        if(type >= 0 && type <sizeof(CreateSptrTbl) / sizeof(CreateSptrTbl[0]))
            mObjectManager.add((*CreateSptrTbl[type].second)());
    }

とすればそれなりにすっきりはしますね。

 ObjTypeが整数・列挙型以外だったり、0から始まっているわけでないのなら
mapにでも入れて似たようなことができるかと思いますが、どうでしょう?


700ポイント を手に入れた。



Name: オデン  ..ぴよぴよ(51ポイント)   Date: 2010/06/15(火) 10:44   No:54405       
Title: 画像が表示されない    
龍神録プログラミング4章でエラーは出ないんですけど画像が表示されません。
なにか問題があるんでしょうか。
ちなみにBCC Developer と Borland c++ でやってます


51ポイント を手に入れた。


Name: a  ..かけだし(1,776ポイント)   Date: 2010/06/15(火) 15:16   No:54414     
Title: Re:画像が表示されない    
画像はDatフォルダにちゃんと入っていますか?
パスは間違えてませんか?
タイプミスはしていませんか?
画像が表示されていないということは画面が真っ黒ということですか?


72ポイント を手に入れた。

Name: シエル  ..中級者(9,092ポイント)   Date: 2010/06/15(火) 20:15   No:54429     
Title: Re:画像が表示されない    
左上隅にチラっと見えてませんか?

8ポイント を手に入れた。



Name: shiro4ao  ..入門者(4,277ポイント)   Date: 2010/06/12(土) 21:39   No:54138       
Title: コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。    
コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。

例)
111 2222 33

111
2222
33
のようにしたいです。
で配列に入れて、簡単にアクセス出来るようになりたいです。

=================ここから==============================
#include <stdio.h>
#include <windows.h>

int main(void){

    wchar_t buf[1024];
    int nNumArgs,i;

    gets(buf);
    PWSTR *ppArgv = CommandLineToArgvW(buf,&nNumArgs);
    
    for(i;i<nNumArgs;i++){
        printf("%s\n",(char)*ppArgv[0]);
    }

    return 0;
}
=============ここまで======================================

ところがこんなエラーが出てきます。
エラー E2034 divcmdl.cpp 10: 'wchar_t *' 型は 'char *' 型に変換できない(関数 main() )
エラー E2342 divcmdl.cpp 10: パラメータ '__s' は char * 型として定義されているので wchar_t * は渡せない(関数 main() )
エラー E2034 divcmdl.cpp 13: 'wchar_t *' 型は 'char' 型に変換できない(関数 main() )

CommandLineToArgvW()がUnicode版なのでまずいのでしょうか・・・

何別の方法があるのでしょうか・・・?


414ポイント を手に入れた。


Name: たかぎ [URL]  ..ハッカー(206,550ポイント)   Date: 2010/06/12(土) 21:52   No:54143     
Title: Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。    
C++のようですが、それなら...

#include <iostream> 
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include <algorithm>

int main()
{
    std::vector<std::string> v;
    
    std::string buffer;
    std::getline(std::cin, buffer);
    std::istringstream iss(buffer);
    std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::back_inserter(v));

    std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "\n"));

    return 0;
}

これでよくないですか?
配列ではなくvectorですが、やりたいことはこれでできるはずです。


2倍のポイントを手に入れた! 154ポイント を手に入れた。

Name: shiro4ao  ..入門者(4,395ポイント)   Date: 2010/06/12(土) 22:05   No:54146     
Title: Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。    
素早いご回答ありがとうございます!
C++は使ったことがないので勉強してみようとおもいます・・・
難しいですね・・・

関数にして、変換前の文字列へのポインタ、配列の数へのポインタをもらい、
変換後の文字列の配列を戻り値にするような関数を作りたかったのです。

C++だと関数は使えないのでしょうか・・・・?


118ポイント を手に入れた。

Name: たかぎ [URL]  ..ハッカー(206,930ポイント)   Date: 2010/06/12(土) 22:18   No:54151     
Title: Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。    
> C++は使ったことがないので

いや、C++を使っていると思いますよ。

> 関数にして、変換前の文字列へのポインタ、配列の数へのポインタをもらい、 
> 変換後の文字列の配列を戻り値にするような関数を作りたかったのです。 

↓でよいのでは?

#include <iostream> 
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
#include <algorithm>

std::vector<std::string> split(const std::string* s, std::size_t* n = 0)
{
    std::istringstream iss(*s);
    std::vector<std::string> v;
    std::copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(), std::back_inserter(v));
    if (n != 0)
        *n = v.size();
    return v;
}

int main()
{
    std::string buffer;
    std::getline(std::cin, buffer);
    std::vector<std::string> v = split(&buffer);
    std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
    return 0;
}

> C++だと関数は使えないのでしょうか・・・・?

そんなことはありません。



380ポイント を手に入れた。

Name: shiro4ao  ..入門者(4,446ポイント)   Date: 2010/06/12(土) 23:38   No:54164     
Title: Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。    
PWSTR split(char buf, int *n)のようにchar型の文字列を配列に
変えて戻り値にして、配列の個数をint型で渡したかったのですが、
うまくいきませんでした。もう少し勉強してみます。


51ポイント を手に入れた。

Name: shiro4ao  ..入門者(4,929ポイント)   Date: 2010/06/13(日) 07:24   No:54182     
Title: Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。    
以下のようなコードが
エラーに成ります・・・・
どこが良くなかったのでしょう…?


エラー E2034 divcmdl.cpp 11: 'int' 型は 'char *' 型に変換できない(関数 CmdTok(ch
ar *,char *,int,char *) )
エラー E2342 divcmdl.cpp 11: パラメータ '__s1' は char * 型として定義されている
ので char は渡せない(関数 CmdTok(char *,char *,int,char *) )
エラー E2034 divcmdl.cpp 11: 'char *' 型は 'char' 型に変換できない(関数 CmdTok(c
har *,char *,int,char *) )
エラー E2034 divcmdl.cpp 12: 'char *' 型は 'char' 型に変換できない(関数 CmdTok(c
har *,char *,int,char *) )


#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//buf コマンドライン、div 区切り文字、n 何番目かのコマンドライン、 ret 切り出されたコマンドライン
int CmdTok(char *buf ,char *div,int n ,char *ret){
     int i;

     *ret = strtok(buf,div);
     for(i=0;i<n-1;i++) *ret = strtok(NULL,div);

     return 0;
}



/* main */
int main(void) {
    char s1[1024],cmd[1024];

    gets(s1);

    CmdTok(s1," ",2,cmd);

    printf("%s\n", cmd);

    return 0;
}





483ポイント を手に入れた。

Name: シエル  ..入門者(4,089ポイント)   Date: 2010/06/13(日) 07:44   No:54183     
Title: Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。    
ざっとしか見てませんが…

char *retはポインタですよね?

じゃあ *ret = strtok(buf,div)の*は要らないのでは?



58ポイント を手に入れた。

Name: shiro4ao  ..初心者(5,225ポイント)   Date: 2010/06/13(日) 08:07   No:54184     
Title: Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。    
ありがとうございます。
うっかりしてました…

/* header files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//buf ごっちゃのコマンドライン、div 区切り文字、n 何番目かのコマンドライン、 ret 切り出されたコマンドライン
int CmdTok(char *buf ,char *div,int n ,char *ret){
     int i;
     ret = strtok(buf,div);
     for(i=0;i<n-1;i++) ret = strtok(NULL,div);
     return 0;
}

int main(void) {
    char s1[1024],*code;

  gets(s1);

    CmdTok(s1," ",4,code);

    printf("cmdtok: %s\n", code);

    return 0;
}

コンパイルはできたんですが、今度はトークン切り出しが出来ていないようです。
111 222 333 444 555 666 777
を入力しても、
cmdtok:
としか出てきませんでした・・・・


296ポイント を手に入れた。

Name: シエル  ..初心者(6,217ポイント)   Date: 2010/06/13(日) 17:28   No:54233     
Title: Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。    
すいません。イメージってこんな感じですか?


/* header files */ 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 


//buf ごっちゃのコマンドライン、div 区切り文字、n 何番目かのコマンドライン、 ret 切り出されたコマンドライン 
int CmdTok(char *buf ,char *div,int n ,char **ret){ 
     int i; 
     *ret = strtok(buf,div); 
     for(i=0;i<n-1;i++) *ret = strtok(NULL,div); 
     return 0; 


int main(void) { 
    char s1[1024],*code; 

    gets(s1); 

    CmdTok(s1," ",3,&code); 

    printf("cmdtok: %s\n", code); 

    return 0; 
}


218ポイント を手に入れた。

Name: shiro4ao  ..初心者(5,173ポイント)   Date: 2010/06/15(火) 20:10   No:54428 解決!     
Title: Re:コマンドラインからスペースで区切った文字列を分けて配列に入れたいです。    
>for(i=0;i<n-1;i++) *ret = strtok(NULL,div);  

なるほど!分かりました!
ありがとうございました。


52ポイント を落としてしまった。



Name: suz  ..ぴよぴよ(165ポイント)   Date: 2010/06/14(月) 04:38   No:54287       
Title: C++の質問です。    
C++でRPGを作っています。キャラの頭上に文字を表示させるプログラムを作ったんですが、その結果、キャラが動かないという現象が起きました。どうぞお分かりになる方ご回答お願いいたします。

環境は Windows/DXLib/Visual C++ です。

文字の表示プログラムはこちら↓。

http://game.suz45.net/test14.txt

読み出すプログラムは以下です。

http://game.suz45.net/test15.txt

どうぞよろしくお願いいたします。


165ポイント を手に入れた。


Name: シエル  ..初心者(8,038ポイント)   Date: 2010/06/14(月) 08:38   No:54292     
Title: Re:C++の質問です。    
DrawGraph( 320 , 160 , ch.img , TRUE ) ;//画像を描画


↑これじゃ動かないでしょう。。。。。もう分かりますよね? 編集済み


58ポイント を手に入れた。

Name: TKOZ  ..熟練のプログラマー(61,607ポイント)   Date: 2010/06/14(月) 09:09   No:54293     
Title: Re:C++の質問です。    
ちらっと見ただけですが、
読み出すプログラムで、
//ScreenFlip();
になってます。これでは、画面の更新が出来ません。


52ポイント を手に入れた。

Name: softya [URL]  ..ハッカー(180,692ポイント)   Date: 2010/06/14(月) 12:05   No:54302     
Title: Re:C++の質問です。    
閉じているのでマルチポストとは言いませんが、同じ人だと思うので。
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1342171888

2つの問題は解決していないと思いますので、ここで解決した方が良いですよ。現状かなりひどいプログラムになってます。
>関係ないけど、少なくともループ中に画像をロードするのはやめた方が良い。
>それと行き当たりばったりでプログラムを拡張し続けるのはやめた方が。このままだとワケがわからなくなって放棄することになりますよ。関数化・ファイル分割などを勉強してください。


142ポイント を手に入れた。

Name: suz45  ..ぴよぴよ(1ポイント)   Date: 2010/06/15(火) 16:25   No:54419 解決!     
Title: Re:C++の質問です。    
皆さん、お返事ありがとうございます!
なんとなくできるようになりました。
ありがとうございました!


1ポイント を手に入れた。



Name: テントウムシ  ..ぴよぴよ(0ポイント)   Date: 2010/06/14(月) 20:01   No:54364       
Title: 10個の配列から被らないように5つの値を取りだす    
10個の配列から被らないようにランダムに5つの値を取りだしたいです。
下記の様なソースを考えてみたのですが""の部分の書き方がわかりません・・・。
 ※わからないというより ==&&と複数書かなければいけないのでしょうか?
もっと効率のよいPGはないでしょうか?


int Num[10] = { 1,2,3,4,5, 6,7,8,9,10 };
int Array[5];

while(1){
    for(int i=0; i<5; i++){
        Array[i] = rand()%10;
    }
    if("全部違ってたら")break;
}




Name: たかぎ [URL]  ..ハッカー(207,216ポイント)   Date: 2010/06/14(月) 20:23   No:54367     
Title: Re:10個の配列から被らないように5つの値を取りだす    
std::random_shuffleでかき混ぜたあと、最初から5つを取り出せばOKです。


24ポイント を手に入れた。

Name: MNS  ..プログラマー(35,347ポイント)   Date: 2010/06/14(月) 20:32   No:54369     
Title: Re:10個の配列から被らないように5つの値を取りだす    
一応、for文を重ねることによって
while(1){
    for(int i=0; i<5; i++)
    {
        Array[i] = rand()%10;
    }
    for(int x=0; x<5; ++x)
    {
        for(int y=0; y<5; ++y)
        {
            if(x!=y && Array[x]==Array[y])
            {
                goto CONTINUE;
            }
        }
    }
    break;
CONTINUE:
    continue;
}
と書くことも出来ますが、効率は良くないでしょう。スマートでもありませんね。
それよりは、たかぎさんが仰るような、
そもそも値が重複しないように取り出す手法をとったほうが無難です。


178ポイント を手に入れた。

Name: シエル  ..中級者(9,009ポイント)   Date: 2010/06/14(月) 20:37   No:54370     
Title: Re:10個の配列から被らないように5つの値を取りだす    
簡単に作ってみました。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void main(void)
{
    int Num[10] = { 1,2,3,4,5, 6,7,8,9,10 };
    int random[5];
    int tmp;
    int j;

    srand((unsigned)time(NULL));

    for(int i=0;i<5;i++){
        random[i]=0;
        while(1){
            tmp=rand()%10;
            for(j=0;j<i+1;j++){
                if(random[j]==tmp){
                    break;
                }
            }
            if(j==i+1){
                random[i]=tmp;
                break;
            }
        }
    }
    
    for(int s=0;s<5;s++){
    printf("ランダム数字=%d\n",random[s]);
    }
    for(int x=0;x<5;x++){
        printf("配列の数字読み込み=%d\n",Num[random[x]]);
    }
編集済み


279ポイント を手に入れた。

Name: ideyan  ..初心者(5,729ポイント)   Date: 2010/06/14(月) 21:30   No:54376     
Title: Re:10個の配列から被らないように5つの値を取りだす    
while(1)に対抗して(笑)

int Num[10] = { 1,2,3,4,5,6,7,8,9,10 }; 
int Array[5]; 
int i=0,j=0,tmp;
srand((unsigned)time(NULL)); 
    
while(i<5){
    tmp = rand()%10;
    for(j=0;j<i;++j){
        if(Array[j]==Num[tmp])break;
    }
    if(j==i){
        Array[i]=Num[tmp];
        ++i;
    }
}


でもやってることは皆さんと変わらないw
最初から被らないようにするのがいいですよねぇ。


134ポイント を手に入れた。

Name: シエル  ..中級者(9,084ポイント)   Date: 2010/06/14(月) 22:11   No:54378     
Title: Re:10個の配列から被らないように5つの値を取りだす    
ideyanさんに横槍を入れるようで申し訳ないですが、
ideyanさんのコードだとNumの配列内に同じ数字があった場合は
その数字は一回しか選ばれない気がします。

間違ってたらすいません。


75ポイント を手に入れた。

Name: ideyan  ..初心者(6,018ポイント)   Date: 2010/06/14(月) 22:36   No:54385     
Title: Re:10個の配列から被らないように5つの値を取りだす    
ん、あぁ。
元々の配列も重複無しかと思ってたんですが
よく見たら特にそんなことは書いてないですね^^;

というわけで修正版。
欠点は配列の要素の数と同じ個数のバッファを必要とすることです。
(同じ長さである必要は無いですがビット演算面倒です。。。)

int Num[10] = { 1,2,3,4,5,6,7,8,9,10 }; 
char flag[10];
int Array[5]; 
int i=0,tmp;

srand((unsigned)time(NULL)); 
for(i=0;i<10;++i)flag[i]=0;

i=0;
while(i<5){
    tmp = rand()%10;
    if(!flag[tmp]){
        flag[tmp]=1;
        Array[i++]=Num[tmp];
    }
}


289ポイント を手に入れた。

Name: めるぽん  ..ぴよぴよ(14ポイント)   Date: 2010/06/15(火) 15:11   No:54413     
Title: Re:10個の配列から被らないように5つの値を取りだす    
たかぎさんの書いているのが一番スマートが気がしますね。

#include <algorithm>
#include <iostream>
 
int main()
{
  int Num[10] = { 1,2,3,4,5,6,7,8,9,10 };
  int Array[5];
  std::random_shuffle(Num, Num + 10);
  std::copy(Num, Num + 5, Array);
 
  for (int i = 0; i < 5; i++) std::cout << Array[i] << std::endl;
}

もし元の配列に重複する値があるなら、std::sort して std::unique で削除してしまえばいいかと。

#include <algorithm>
#include <iostream>
#include <iterator>
#include <cassert>
 
int main()
{
  int Num[10] = { 8,2,3,2,4,5,1,5,8,9 };
  int Array[5];
  std::sort(Num, Num + 10);
  int* last = std::unique(Num, Num + 10);
  assert(std::distance(Num, last) >= 5); // 5個以上は unique な値が必要
  std::random_shuffle(Num, last);
  std::copy(Num, Num + 5, Array);
 
  for (int i = 0; i < 5; i++) std::cout << Array[i] << std::endl;
}


14ポイント を手に入れた。



Name: JIN  ..かけだし(1,409ポイント)   Date: 2010/06/14(月) 22:23   No:54381       
Title: 2D格闘のアニメーションについて    
はじめまして。
キング・オブ・ファイターズ2002のような2D格闘ゲームの製作を目指している
JINといいます。

キャラクターのアニメーション関数を次のように書いたところ滑らかに
表示させることができました。

graph_ch{
        //ch.xとch.yはキャラクターの原点座標です。
        //ch.anim_cnt[0]は初期化関数にて0を代入しました。
        //ch.anim_cnt[0]をカウンタにして1コマ毎の表示フレーム数を制御しています。
    ch.anim_cnt[0] = ch.anim_cnt[0]++;
        if(ch.anim_cnt[0]<4)
            LoadGraphScreen(ch.x-28,ch.y-98,"ch0001.bmp",TRUE);
        if(ch.anim_cnt[0]>=4 && ch.anim_cnt[0]<8)
            LoadGraphScreen(ch.x-28,ch.y-99,"ch0002.bmp",TRUE);
        if(ch.anim_cnt[0]>=8 && ch.anim_cnt[0]<12)
            LoadGraphScreen(ch.x-28,ch.y-100,"ch0003.bmp",TRUE);
        if(ch.anim_cnt[0]>=12 && ch.anim_cnt[0]<16)
            LoadGraphScreen(ch.x-27,ch.y-101,"ch0004.bmp",TRUE);
        if(ch.anim_cnt[0]>=16 && ch.anim_cnt[0]<20)
            LoadGraphScreen(ch.x-27,ch.y-101,"ch0005.bmp",TRUE);
        if(ch.anim_cnt[0]>=20 && ch.anim_cnt[0]<24)
            LoadGraphScreen(ch.x-28,ch.y-100,"ch0006.bmp",TRUE);
        if(ch.anim_cnt[0]>=24 && ch.anim_cnt[0]<28)
            LoadGraphScreen(ch.x-28,ch.y-99,"ch0007.bmp",TRUE);
        if(ch.anim_cnt[0]>=28 && ch.anim_cnt[0]<32)
            LoadGraphScreen(ch.x-28,ch.y-98,"ch0008.bmp",TRUE);
        if(ch.anim_cnt[0]>=32 && ch.anim_cnt[0]<36)
            LoadGraphScreen(ch.x-29,ch.y-97,"ch0009.bmp",TRUE);
        if(ch.anim_cnt[0]>=36 && ch.anim_cnt[0]<=40)
            LoadGraphScreen(ch.x-29,ch.y-97,"ch0010.bmp",TRUE);
        if(ch.anim_cnt[0]>=40)
            ch.anim_cnt[0]=0;
          }

このLoadGraphScreenをDrawRectGraphに書き換えてみました。

graph_ch{
            //アニメーションに使われている1コマ毎の画像をまとめた、
            //サイズ512x512の画像を初期化関数にてimg_ch[0][0]に代入してあります。
ch.anim_cnt[0] = ch.anim_cnt[0]++;
if(ch.anim_cnt[0]<4)
    DrawRectGraph(ch.x-29,ch.y-99,2,2,56,103,img_ch[0][0],TRUE,FALSE);
if(ch.anim_cnt[0]>=4 && ch.anim_cnt[0]<8)
    DrawRectGraph(ch.x-29,ch.y-100,59,2,56,104,img_ch[0][0],TRUE,FALSE);
if(ch.anim_cnt[0]>=8 && ch.anim_cnt[0]<12)
    DrawRectGraph(ch.x-29,ch.y-101,116,2,56,105,img_ch[0][0],TRUE,FALSE);
if(ch.anim_cnt[0]>=12 && ch.anim_cnt[0]<16)
    DrawRectGraph(ch.x-28,ch.y-102,173,2,55,106,img_ch[0][0],TRUE,FALSE);
if(ch.anim_cnt[0]>=16 && ch.anim_cnt[0]<20)
    DrawRectGraph(ch.x-28,ch.y-102,229,2,55,106,img_ch[0][0],TRUE,FALSE);
if(ch.anim_cnt[0]>=20 && ch.anim_cnt[0]<24)
    DrawRectGraph(ch.x-29,ch.y-101,285,2,56,105,img_ch[0][0],TRUE,FALSE);
if(ch.anim_cnt[0]>=24 && ch.anim_cnt[0]<28)
    DrawRectGraph(ch.x-29,ch.y-100,342,2,56,104,img_ch[0][0],TRUE,FALSE);
if(ch.anim_cnt[0]>=28 && ch.anim_cnt[0]<32)
    DrawRectGraph(ch.x-29,ch.y-99,399,2,56,103,img_ch[0][0],TRUE,FALSE);
if(ch.anim_cnt[0]>=32 && ch.anim_cnt[0]<36)
    DrawRectGraph(ch.x-30,ch.y-98,455,2,57,102,img_ch[0][0],TRUE,FALSE);
if(ch.anim_cnt[0]>=36 && ch.anim_cnt[0]<=40)
    DrawRectGraph(ch.x-30,ch.y-98,1,108,57,102,img_ch[0][0],TRUE,FALSE);
if(ch.anim_cnt[0]>=40)
    ch.anim_cnt[0]=0;
      }

このように書き換えたところ、最後のコマの表示時間が長くなってしまい、
結果、最後のコマから最初のコマに戻るまでの間が滑らかに表示されなくなりました。
「龍神録プログラミングの館」の、「FPSの制御と表示を可能にする関数」を使わせて頂いたところ、
処理速度に問題はありませんでした。
解決法が見つからず困っています。

DrawRectGraphを使って、ループするアニメーションを
滑らかに表示できる方法はないのでしょうか?
 編集済み


1,409ポイント を手に入れた。


Name: JIN  ..かけだし(1,527ポイント)   Date: 2010/06/15(火) 11:55   No:54409 解決!     
Title: 自己解決しました    
自己解決させることができました。
テクスチャ画像img_ch[0][0]を確認したところ、
最後のコマの画像をひとつ手前のコマにも貼り付けていたという
私のミスが原因であったことが分かりました。

掲示板のみなさんに迷惑をかけてしまい、すみませんでした。


118ポイント を手に入れた。



Name: しろ  ..中級者(10,640ポイント)   Date: 2010/06/14(月) 14:21   No:54320       
Title: if文などの条件式について    
if文などの条件式の表記について質問です。

C言語の規則としてif文の中の条件などで
a==b==cのような表記は認められているのでしょうか?

それとも(a==b) && (b==c)のような表記をしないとだめでしょうか?


手元の資料には特に記載がなかったので……

よろしくお願いいたします。


40ポイント を手に入れた。


Name: たいちう  ..比類無きプログラマー(95,484ポイント)   Date: 2010/06/14(月) 14:32   No:54323     
Title: Re:if文などの条件式について    
> a==b==cのような表記は認められているのでしょうか?

認められていますが、おそらく実行結果は意図とは違ったものになるでしょう。
色々試してみてください。
if (2 == 1 == 0)
    printf("True!\n");
else
    printf("False!\n");


73ポイント を手に入れた。

Name: しろ  ..中級者(10,792ポイント)   Date: 2010/06/14(月) 17:06   No:54331     
Title: Re:if文などの条件式について    
ご回答いただきありがとうございます。

今コンパイラがないので確認できませんが、帰宅次第いろいろ試してみて、結果をこちらに記入させていただきます。

よろしくお願いいたします。


2倍のポイントを手に入れた! 152ポイント を手に入れた。

Name: Ultimate  ..中級者(9,945ポイント)   Date: 2010/06/14(月) 19:13   No:54356     
Title: Re:if文などの条件式について    
if(a==b&&b==c){
     文章
}

の形のほうが無難だと思います。

大した手間ではないので、そうするべきだと思います。

それがだめということもありませんが、たいちうさんが言うように、意図と違う結果を招きかねません。


62ポイント を手に入れた。

Name: MNS  ..プログラマー(35,169ポイント)   Date: 2010/06/14(月) 19:54   No:54362     
Title: Re:if文などの条件式について    
比較演算子の結果は値になるということと、
if( a == b == c )

if( (a==b) == c )
であることに注意して考えてみてください。


68ポイント を手に入れた。

Name: しろ  ..中級者(10,895ポイント)   Date: 2010/06/14(月) 21:34   No:54377     
Title: Re:if文などの条件式について    
いろいろ試してみましたが一応a==b==cなども通るようでした。

たいちうさんの

if (2 == 1 == 0)
    printf("True!\n");
else
    printf("False!\n");

も試したが、これはTrueとなりました。

これは((2==1)==0)が

偽の偽で結局真になるという理解でいいでしょうか?



103ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(95,652ポイント)   Date: 2010/06/14(月) 22:50   No:54391     
Title: Re:if文などの条件式について    
> 偽の偽で結局真になるという理解でいいでしょうか?

その理解で↓の結果を予想できますか?
if (2 == 0 == 1)
    printf("True!\n");
else
    printf("False!\n");


30ポイント を手に入れた。

Name: ぽこ  ..上級者(15,295ポイント)   Date: 2010/06/14(月) 22:52   No:54392     
Title: Re:if文などの条件式について    
> これは((2==1)==0)が

> 偽の偽で結局真になるという理解でいいでしょうか?

関係演算子は真の場合、1と評価され、偽の場合0と評価されます。
2==1は偽なので、0になります。
その結果(0 == 0)となりますので((2==1)==0)の結果は真となります。



75ポイント を手に入れた。

Name: box  ..ハッカー(154,574ポイント)   Date: 2010/06/14(月) 23:15   No:54394     
Title: Re:if文などの条件式について    
> if(a==b&&b==c){
>      文章
> }

> の形のほうが無難だと思います。

無難なのではなくて、a,b,cのすべてが等しいことを
判定するためにはそう書かなくちゃダメ。


41ポイント を手に入れた。

Name: しろ  ..中級者(10,921ポイント)   Date: 2010/06/15(火) 07:03   No:54404 解決!     
Title: Re:if文などの条件式について    
なるほど、理解することができました。

ありがとうございました。


26ポイント を手に入れた。



Name: Roi  ..ぴよぴよ(3ポイント)   Date: 2010/06/14(月) 22:34   No:54384       
Title: C言語のリストで分からないことがあります。    
『次の「Josephusの問題」を,循環リストを用いて解け.
9枚のコインを円形に並べる.1番のコインから数えて5枚目のコイン(5番のコイン)を取り除き,また次から数えて5枚目のコイン(1番)を取り除く,という操作を繰り返す.取り除かれる順番を答えよ.』
という課題なんですが全く分かりません。

教えてください。よろしくお願いします。


3ポイント を手に入れた。


Name: たいちう  ..比類無きプログラマー(95,524ポイント)   Date: 2010/06/14(月) 22:38   No:54386     
Title: Re:C言語のリストで分からないことがあります。    
問題は理解できますか?
まだプログラムは書かなくてよいので、先に答を求めてみましょう。


40ポイント を手に入れた。

Name: Roi  ..ぴよぴよ(29ポイント)   Date: 2010/06/14(月) 22:42   No:54387     
Title: Re:C言語のリストで分からないことがあります。    
問題は理解できます。
答えは『5・1・7・4・3・6・9・2・8』になると思います。


29ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(95,622ポイント)   Date: 2010/06/14(月) 22:47   No:54390     
Title: Re:C言語のリストで分からないことがあります。    
循環リストは判りますか?リストは?

循環リストが判るならば、その要素はどう書けると思いますか?
また、どのように初期化できますか?
リストを辿って初期化された状態を表示するプログラムは書けますか?
無限ループにならないように注意してください。


69ポイント を手に入れた。



Name: 蒼空  ..かけだし(2,413ポイント)   Date: 2010/06/14(月) 18:06   No:54337       
Title: C++についての質問    
私はこのサイトを見てC++を始めたのですが、データ型はbool、int、double、float、charなどがあるといろいろなサイトを見てるうちにわかりました。

そこで聞きたいのですが、
これらのデータ型などはどういう意味を持つのか?
皆さんはこれらのデータ型をどういう時に使用しますか?
それと、これらのデータ型はDXライブラリで使用することができるのか?

上の3点を聞いてみたいと思い質問しました。
初歩的な質問ですが、どうぞご回答よろしくお願いします。

あと、「ほかにこんなデータ型もあるよ(^o^)」という方は、教えていただけると幸いです。

長文 失礼いたしました。





280ポイント を手に入れた。


Name: シエル  ..初心者(8,651ポイント)   Date: 2010/06/14(月) 18:34   No:54350     
Title: Re:C++についての質問    
http://www.cppll.jp/cppreference/data_types.html
↑この辺をごらんになった方が良いかと…

これらのデータ型はDXライブラリを使用したプログラムでも当然使用できます。


59ポイント を手に入れた。

Name: y  ..初心者(5,909ポイント)   Date: 2010/06/14(月) 18:38   No:54351     
Title: Re:C++についての質問    
まずはC/C++言語について学ぶと良いですよ…というのは常套句ですが全くその通りです。

>これらのデータ型などはどういう意味を持つのか?
C/C++言語を学ぶと良いです。

>皆さんはこれらのデータ型をどういう時に使用しますか?
私は、必要なときに使用します。

>それと、これらのデータ型はDXライブラリで使用することができるのか?
できます。
あと、理解の仕方が違います。
DXライブラリ「で」使うのではなく、DXライブラリ「を使ったプログラムで」使います。


これ以上具体的な返答ができる質問ではないため、
こんな文章になってしまい申し訳ございません。
いろいろなサイトをご覧になったようですが、勉強はされてない様子で。
恐らくそのいろいろなサイトに、データ型の意味についても書かれているはずですよ。
意味がわかれば、どんなときにどのデータ型を使うかもわかるはずです。

プログラミングは一度わかってしまえば非常に楽しいものですので、
是非勉強してプログラミングを楽しんでください(^^


※推敲が足りませんでした。初級者さん、ご指摘ありがとうございます。
 編集済み


311ポイント を手に入れた。

Name: 初級者  ..初心者(8,118ポイント)   Date: 2010/06/14(月) 19:08   No:54353     
Title: Re:C++についての質問    
誤:拝見なさる
正:ごらんになる、など

拝見する、は見るの謙譲語。
他者の行為に使ってはダメ。
日本語を勉強しましょう。


61ポイント を手に入れた。

Name: シエル  ..初心者(8,707ポイント)   Date: 2010/06/14(月) 19:12   No:54355     
Title: Re:C++についての質問    
なるべく初級者って名前も使わず、ユニークな名前がいいかと。
規約を読みましょう。


2倍のポイントを手に入れた! 56ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,213,662ポイント)   Date: 2010/06/14(月) 19:52   No:54361     
Title: Re:C++についての質問    
確かに初級者さんは初心者さんと同じような意味合いに感じられたり、読み違えたりする可能性はありますが、
初心者さんが沢山重複している一方で、初級者さんはお名前を使っている方が一人しかいらっしゃらないようです。
初級者さんはかなり前から同じお名前をお使いのようですし、大丈夫ではないかなと思ったりしています。
せっかく規約について書いて下さったのに否定するようなコメントですみません。

> 蒼空さん

逆に蒼空さんのお名前は他に誰かがお使いのようです・・。
何か他の名前にして頂けると幸いです。
登録制じゃないので、この辺がめんどうですね、すみません・・。

ところで、型についてですが、皆さん仰るように、サイトか本で勉強された方が良いと思います。
回答が面倒だからとか、意地悪で言っているわけではなく、
C言語におけるもっとも基本的なことなので、それがここで解決したとしても、全体としては何も解決にならないと思います。
それよりも学び方を学んだ方が今後に為になりそうです。

サイトを見て勉強したと書かれていますが、どこのサイトをご覧になりました?
そのサイトにはその型についての説明はありませんでしたか?




376ポイント を手に入れた。

Name: 組木紙織  ..比類無きプログラマー(86,895ポイント)   Date: 2010/06/14(月) 21:01   No:54373     
Title: Re:C++についての質問    
論理型(bool)、
文字列型(char,unsigned char signed char, wchar_t)、
整数型(int,signed int, unsigned int, short int, unsigned short int,signed short int, long int,signe long int, unsigned long int)、
浮動点小数型(float double long double)、
列挙型、
void型、
ポインタ型、
配列型、
リファレンス型、
構造体、クラス

多分C++の型はこれで全部だと思う。
詳細は自分で調べてください。


211ポイント を手に入れた。

Name: たかぎ [URL]  ..ハッカー(207,293ポイント)   Date: 2010/06/14(月) 22:15   No:54379     
Title: Re:C++についての質問    
> 文字列型(char,unsigned char signed char, wchar_t)、 

文字列型ではなく、文字型ですね。
ただし、文字型も汎整数型の一種です。

> 多分C++の型はこれで全部だと思う。 

関数型が抜けています。
あと、メンバへのポインタ型はポインタ型に含んでいますか?


77ポイント を手に入れた。

Name: 組木紙織  ..比類無きプログラマー(86,972ポイント)   Date: 2010/06/14(月) 22:29   No:54382     
Title: Re:C++についての質問    
>関数型が抜けています。 
>あと、メンバへのポインタ型はポインタ型に含んでいますか? 

その二つは普段あまり意識しないから忘れてました。
ありがとうございます。

#メンバへのポインタはポインタ型に含めていいんでしょうか。


77ポイント を手に入れた。

Name: たかぎ [URL]  ..ハッカー(207,308ポイント)   Date: 2010/06/14(月) 22:43   No:54389     
Title: Re:C++についての質問    
> #メンバへのポインタはポインタ型に含めていいんでしょうか。 

ポインタ型だといえばそうですが、普通は分けて考えますね。
 編集済み


15ポイント を手に入れた。



Name: wing  ..中級者(10,723ポイント)   Date: 2010/06/14(月) 00:08   No:54274       
Title: スーパーマリコ3を作りました。    
よかったら遊んでみてください。
ソースも一緒にアップしたのでよければそちらも見てください。

http://www1.axfc.net/uploader/Li/so/69526.zip
キー 7777

操作方法
矢印キーで移動
Xキーを押すとスピードアップ
Zきーを押すとジャンプ

タイトル画面
Sキーで決定、スタート

私はゲームが下手なので、なかなかクリアーできない面もあるので、
今回は8面にしました。
(添付した画像のところができない)

ぜひ遊んでください。


224ポイント を手に入れた。


Name: wing  ..中級者(10,799ポイント)   Date: 2010/06/14(月) 15:18   No:54325     
Title: Re:スーパーマリコ3を作りました。    
9面ができたので、追加しました。

http://www1.axfc.net/uploader/Li/so/69567.zip
キー 7777

ソースも一緒にアップしています。
よければ遊んでみてください。


76ポイント を手に入れた。

Name: ぽこ  ..上級者(15,220ポイント)   Date: 2010/06/14(月) 20:11   No:54365     
Title: Re:スーパーマリコ3を作りました。    
どうでもいい話ですが、Readmeがスーパーマリコ2のままです。。

もう1点指摘したいことがあるのですが、出来れば誰にも見られずにやり取りしたいです。
wingさんのメールアドレスとか公開できませんか?


100ポイント を手に入れた。

Name: wing  ..中級者(10,815ポイント)   Date: 2010/06/14(月) 20:23   No:54366     
Title: Re:スーパーマリコ3を作りました。    
アドレスを公開しました。

2倍のポイントを手に入れた! 16ポイント を手に入れた。

Name: Tatu  ..プログラマー(39,835ポイント)   Date: 2010/06/14(月) 20:31   No:54368     
Title: Re:スーパーマリコ3を作りました。    
全9面クリアしました。
今までのシリーズに比べ、かなり難しくなっていますね。

次はどのような仕掛けが追加されるのか、(また、どれだけ難しくなるか)楽しみにしています。


2倍のポイントを手に入れた! 118ポイント を手に入れた。

Name: wing  ..中級者(10,955ポイント)   Date: 2010/06/14(月) 22:16   No:54380     
Title: Re:スーパーマリコ3を作りました。    
Tatuさん、遊んでいただきありがとうございます。
テクニックがないとなかなかクリアーできないようにしました。

9面は思いっきり難しくしたつもりなんですが、クリアーされましたか。
ありがとうございます。おかげでもっと難しいのを作ってみようという
意欲がでてきました。


2倍のポイントを手に入れた! 140ポイント を手に入れた。



Name: Ultimate  ..中級者(9,366ポイント)   Date: 2010/06/14(月) 17:59   No:54334       
Title: 三角関数で弾幕(3)    
こんにちは。

三角関数で弾幕(2)での皆様の回答を参考に、ソースを作ってみました。

今後どうしたらいいかなどのアドバイスや、感想などをお待ちしています。

(たとえば、この後はさらに弾の種類を増やすのか、敵を登場させたほうがいいのかなど)

あと、全方向ショットが、キーで発射させられるようになったものの、Zを押している間しか広がらないのでどのような方法でそれを改善すればいいのでしょうか?

(ソースではなく、やり方のみで大丈夫です。)

弾は、XキーとZキーで操作です。

実行ファイルはhttp://www1.axfc.net/uploader/Sc/so/123784で、キーは12345です。

ソースは以下の通りです。

実行時は、実行ファイルの中にある画像を入れ忘れないように注意してください。



#include "DxLib.h"
#include<math.h>

#define PI 3.14159265358979323846264338327950288419
#define BALL_SPEED 10
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        ChangeWindowMode( TRUE ) ; // ウインドウモードに変更
        if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了 
 
//変数作成/////////////////////////////////////////////////////////////////////
    
    char key[256];
    int i,j;
    int color;
    color=GetColor(255,255,255);
     
//自機設定/////////////////////////////////////////////////////////////////////
    
    typedef struct {
    int x,y,flag;
    }ch_t;

    ch_t jiki;
    
    int jimage;
    jiki.x=300;
    jiki.y=440;
    jiki.flag=1;
    jimage=LoadGraph("inbe-da-.png");
    
    

    
//弾1変数など//////////////////////////////////////////////////////////////////
    
    int tx1[5],ty1[5],tz1=3,tflag1[5],tcount1=0;
    for(i=0;i<5;i++){
        tflag1[i]=0;
        }
    int t1image;
    t1image=LoadGraph("tama1.png");
        
//弾2変数など//////////////////////////////////////////////////////////////////

    struct {
        double x[20],y[20],z,ang[20];
        int flag,counter;
    }ball2;

    for(i=0;i<20;i++){
        ball2.x[i]=320;
        ball2.y[i]=240;
        ball2.ang[i]=18*i*PI/180;
    }
    ball2.flag=0;
    ball2.z=3;
    ball2.counter=0;

//描画先を裏画面へ/////////////////////////////////////////////////////////////
    
    SetDrawScreen(DX_SCREEN_BACK);
    
    while(1){
        GetHitKeyStateAll(key);    
        if(ProcessMessage()==-1){//メッセージ処理
            break;
            }
            
        ClearDrawScreen();
        
        
//自機表示/////////////////////////////////////////////////////////////////////
        
        if(jiki.flag==1){
            DrawGraph(jiki.x,jiki.y,jimage,TRUE);
            }
        
//自機移動/////////////////////////////////////////////////////////////////////
        
        if(key[KEY_INPUT_RIGHT]==1){
             jiki.x+=5;
             }
        if(key[KEY_INPUT_LEFT]==1){
             jiki.x-=5;
             }
        if(key[KEY_INPUT_UP]==1){
             jiki.y-=5;
             }
        if(key[KEY_INPUT_DOWN]==1){
             jiki.y+=5;
             }
             
//自機移動制限/////////////////////////////////////////////////////////////////
        
        if(jiki.x<0){
             jiki.x=0;
            }
        if(jiki.x>607){
             jiki.x=607;
            }
        if(jiki.y<0){
             jiki.y=0;
            }
        if(jiki.y>455){
             jiki.y=455;
            }
            
//弾1【Xキーで上へ発射】//////////////////////////////////////////////////////////
        
        //フラグ0の弾を自機に合わせて移動
        for(i=0;i<5;i++){
            if(tflag1[i]==0){
                tx1[i]=jiki.x+15;
                ty1[i]=jiki.y;
                }
            }
        
        //Xが押されて、且つフラグが0ならフラグを1に
        if(key[KEY_INPUT_X]==1&&tcount1>10){
            for(i=0;i<5;i++){
                if(tflag1[i]==0){
                    tflag1[i]=1;
                    tcount1=0;
                    break;
                    }
                }
            }
            
        //弾1描画
        for(i=0;i<5;i++){
            if(tflag1[i]==1){
                DrawGraph(tx1[i],ty1[i],t1image,TRUE);
                ty1[i]-=10;
                }
            }
        
        //弾が場外に出たらフラグを0に戻す
        for(i=0;i<5;i++){
            if(ty1[i]<0&&tflag1[i]==1){
                tflag1[i]=0;
                }
            }
        
        //カウンター
        tcount1++;


//弾2【全方向ショット】/////////////////////////////////////////////////////////
        
        //Xキーで発射フラグを立てる
        if(key[KEY_INPUT_Z]==1){
            ball2.flag=1;
        }

        if(ball2.flag==0){
            for(i=0;i<20;i++){
            ball2.x[i]=jiki.x+15;
            ball2.y[i]=jiki.y;
            }
        }

        if(ball2.flag==1){
             for(i=0;i<20;i++){  
                    ball2.x[i]+=cos(ball2.ang[i])*BALL_SPEED;  
                    ball2.y[i]+=sin(ball2.ang[i])*BALL_SPEED;  
                }
               //描画  
               for(i=0;i<20;i++){  
                 DrawCircle(ball2.x[i],ball2.y[i],ball2.z,color,TRUE);  
                }
               if(ball2.counter>10){
                   ball2.flag=0;
                   ball2.counter=0;
               }
               ball2.counter++;
        }

        
        ScreenFlip();//表画面へ反映
        
        }
 
        WaitKey() ;             // キーの入力待ち(『WaitKey』を使用) 
        DxLib_End() ;           // DXライブラリ使用の終了処理
        return 0 ;              // ソフトの終了
編集済み


2,098ポイント を手に入れた。


Name: シエル  ..初心者(8,138ポイント)   Date: 2010/06/14(月) 18:02   No:54335     
Title: Re:三角関数で弾幕(3)    
とりあえず普通のシューティングゲームから作っていけばよいのではないでしょうか?

25ポイント を手に入れた。

Name: Ultimate  ..中級者(9,420ポイント)   Date: 2010/06/14(月) 18:05   No:54336     
Title: Re:三角関数で弾幕(3)    
ありがとうございます。

つまり、この後は敵などを表示させて、当たり判定などをつけた普通のシューティングに、機能を追加するべきだということでしょうか?

とりあえず、頑張って作ってみたので、一度実行していただけたら嬉しいです。


54ポイント を手に入れた。

Name: シエル  ..初心者(8,239ポイント)   Date: 2010/06/14(月) 18:07   No:54338     
Title: Re:三角関数で弾幕(3)    
if(ball2.counter>10){ 
                   ball2.flag=0; 
                   ball2.counter=0; 
               } 

↑10カウント超えたらフラグを戻してるから描画がされないですよ。
描画する条件はball2のフラグが1のときなのですから。


101ポイント を手に入れた。

Name: シエル  ..初心者(8,369ポイント)   Date: 2010/06/14(月) 18:12   No:54339     
Title: Re:三角関数で弾幕(3)    
とりあえず敵を出して、弾が当たったら敵を消す、弾を消す。
それができるようになったら、弾の発射音を出す、弾のショット音、敵の消滅音を出す。
それ以降は、敵の弾幕の種類を増やすなど。
基本はまず普通のシューティングをまず作ってみるべきですよ。

自機の絵がそのままインベーダーですね。自分で描いたんですか?


130ポイント を手に入れた。

Name: Ultimate  ..中級者(9,519ポイント)   Date: 2010/06/14(月) 18:13   No:54340     
Title: Re:三角関数で弾幕(3)    
ありがとうございました。

原因がわかり、うまく改善できました。

if(ball2.counter>10){  
                   ball2.flag=0;  
                   ball2.counter=0;  
               } 



for(i=0;i<20;i++){
    if(ball2.y[i]<0){
    ball2.flag=0;
    }
}

に直してください。

これで改善できました。



99ポイント を手に入れた。

Name: Ultimate  ..中級者(9,604ポイント)   Date: 2010/06/14(月) 18:17   No:54341     
Title: Re:三角関数で弾幕(3)    
インベーダーは

http://dic.nicovideo.jp/b/a/ニコニコ大百科:素材集%2Fドットキャラ/31-

の33番目のものを参考に(一部色をコピー)してペイントで書きました。

とりあえず、自機の画像を考えるのが大変だったので・・・。 編集済み


85ポイント を手に入れた。

Name: Ultimate  ..中級者(9,649ポイント)   Date: 2010/06/14(月) 18:24   No:54342     
Title: Re:三角関数で弾幕(3)    
さらに改善

for(i=0;i<20;i++){
    for(j=0;j<20;j++){
        if(ball2.y[i]<-100&&ball2.y[j]>600){
            ball2.flag=0;
        }
    }
}


45ポイント を手に入れた。

Name: シエル  ..初心者(8,511ポイント)   Date: 2010/06/14(月) 18:25   No:54343     
Title: Re:三角関数で弾幕(3)    
URLのページが見つからないって出ますね。。

自分で描いたんですね。自分は絵が下手なので描ける人は羨ましいです。

↓たぶん下記のように修正しても、キャラが画面の上のほうに居るときに
全方向ショットを撃つとたぶん途中で消えちゃいますよ。

for(i=0;i<20;i++){ 
    if(ball2.y[i]<0){ 
    ball2.flag=0; 
    } 



142ポイント を手に入れた。

Name: ROM  ..かけだし(1,733ポイント)   Date: 2010/06/14(月) 18:26   No:54344     
Title: Re:三角関数で弾幕(3)    
この素材は再配布OKなんですか?

18ポイント を手に入れた。

Name: ROM  ..かけだし(1,751ポイント)   Date: 2010/06/14(月) 18:27   No:54345     
Title: Re:三角関数で弾幕(3)    
>シエルさん

全角URLが含まれていないからでしょう。


18ポイント を手に入れた。

Name: シエル  ..初心者(8,551ポイント)   Date: 2010/06/14(月) 18:29   No:54347     
Title: Re:三角関数で弾幕(3)    
>ROMさん
>全角URLが含まれていないからでしょう。
全角文字もURLだったのか。。ありがとうございます。。。


40ポイント を手に入れた。

Name: シエル  ..初心者(8,592ポイント)   Date: 2010/06/14(月) 18:31   No:54348     
Title: Re:三角関数で弾幕(3)    
↓のように修正しても、自機が左下のほうにある状態で、
全方向ショットを撃つと一部の弾が途中で消えちゃいますよ。
答えは分かりますが、あえて教えません。自分で考えましょう。

for(i=0;i<20;i++){ 
    for(j=0;j<20;j++){ 
        if(ball2.y[i]<-100&&ball2.y[j]>600){ 
            ball2.flag=0; 
        } 
    } 
}


41ポイント を手に入れた。

Name: Ultimate  ..中級者(9,736ポイント)   Date: 2010/06/14(月) 18:31   No:54349     
Title: Re:三角関数で弾幕(3)    
使っていいのか考えていなかったので、もう少しオリジナル性のあるインベーダーを今から描き、出来次第新しいものをアップロードします。

青い弾は完全自作です。


49ポイント を手に入れた。

Name: Ultimate  ..中級者(9,860ポイント)   Date: 2010/06/14(月) 18:38   No:54352     
Title: Re:三角関数で弾幕(3)    
さらに数値を大きくして

for(i=0;i<20;i++){
    for(j=0;j<20;j++){
        if(ball2.y[i]<-300&&ball2.y[j]>700){
            ball2.flag=0;
        }
    }
}

ではだめですよね?

これでは、無駄に数値を大きくしただけですから・・・

もう少しよい方法を考えます。


124ポイント を手に入れた。

Name: Ultimate  ..中級者(9,883ポイント)   Date: 2010/06/14(月) 19:08   No:54354     
Title: Re:三角関数で弾幕(3)    
インベーダー画像完全オリジナルバージョン完成です。

これに画像を変更してください。


23ポイント を手に入れた。

Name: シエル  ..初心者(8,730ポイント)   Date: 2010/06/14(月) 19:15   No:54357     
Title: Re:三角関数で弾幕(3)    
オリジナルに変えたのであれば、アップしたファイルは消して、あげなおしたほうがいいのでは?

23ポイント を手に入れた。

Name: Ultimate  ..中級者(9,982ポイント)   Date: 2010/06/14(月) 19:35   No:54360     
Title: Re:三角関数で弾幕(3)    
http://www1.axfc.net/uploader/Sc/so/123821

に場所変更しました。

パスは今まで通り12345です。


37ポイント を手に入れた。



Name: みかみ  ..ぴよぴよ(6ポイント)   Date: 2010/06/14(月) 07:08   No:54290       
Title: DXライブラリの通信関係のサンプルについて    
DXライブラリを使ってオンラインゲーム(オセロ等簡単なもの)を作ろうとしております。
その為、通信関係のサンプルに書いてあるソースを試して実行したのですが2つ起動することが出来ません。
どちらか一つならCtrl+F5でウインドウが開いてくれるのですが何故なのでしょうか?



6ポイント を手に入れた。


Name: 白い時空  ..ぴよぴよ(379ポイント)   Date: 2010/06/14(月) 10:10   No:54297     
Title: Re:DXライブラリの通信関係のサンプルについて    
この関数を使えばいいと思います。
SetDoubleStartValidFlag( int Flag );//2重起動を許すかどうかのフラグをセットする

DxLib_Init()より前で使ってください。


4ポイント を落としてしまった。

Name: 山崎  ..熟練のプログラマー(43,448ポイント)   Date: 2010/06/14(月) 10:50   No:54300     
Title: Re:DXライブラリの通信関係のサンプルについて    
もしかしたら、
int SetAlwaysRunFlag( int Flag ) ;    // ウインドウがアクティブではない状態でも処理を続行するか、フラグをセットする
この関数も必要になるかもしれません。
参考までに。


85ポイント を手に入れた。

Name: みかみ  ..ぴよぴよ(26ポイント)   Date: 2010/06/14(月) 19:22   No:54359 解決!     
Title: Re:DXライブラリの通信関係のサンプルについて    
出来ました!!
そんな関数があるのですね。
ありがとうございました〜。


20ポイント を手に入れた。



Name: kiri  ..かけだし(2,147ポイント)   Date: 2010/06/10(木) 17:06   No:53908       
Title: GetHitKeyStateAll_2とCheckStateKey    
GetHitKeyStateAll_2とCheckStateKey関数のことをちゃんと理解できていないので、いくつか質問したいです。

・3章にあるように、「キー情報の値が不正に書き換えられる危険性」というのはどういった場合があるのでしょうか?
・GetHitKeyStateAll_2は、常にメインループで呼ばれていて、その上でなにかしらのキーが入力されたらCheckStateKeyが呼ばれるんですよね?だとしたら、どういった順序で関数に値が渡っているのかがいまいち分からないです。
CheckStateKey(KEY_INPUT_ESCAPE)←ESCAPEが入力された
↓
int CheckStateKey(unsigned char Handle){←Handleはなぜchar型で、値はいくつになるのでしょうか?
        return stateKey[Handle];
}

GetHitKeyStateAll_2()はどのタイミングで呼ばれるのでしょうか?

説明が下手で恐縮ですが分かづらいところがあれば指摘をお願いします。
よろしくお願いします。


220ポイント を手に入れた。


Name: fatens  ..中級者(11,515ポイント)   Date: 2010/06/10(木) 19:57   No:53935     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
>3章にあるように、「キー情報の値が不正に書き換えられる危険性」というのはどういった場合があるのでしょうか? 
2章においてKey[]はグローバル変数なので、例えばWinMain 関数内で書き換えることができます。

>GetHitKeyStateAll_2 は、常にメインループで呼ばれていて、その上でなにかしらのキーが入力されたらCheckStateKeyが呼ばれるんですよね?
CheckStateKey 関数は自分で呼び出さない限り呼ばれません。

>Handleはなぜchar型で、値はいくつになるのでしょうか?
Handleはunsigned char型ですね。
値はヘッダファイルで定められています。
KEY_INPUT_ESCAPEの場合は0x01です。

>GetHitKeyStateAll_2() はどのタイミングで呼ばれるのでしょうか? 
WinMain 関数内の while(ProcessLoop()==0) でループしていますが、
その中のProcessLoop 関数の最後で呼ばれています。


354ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,204,482ポイント)   Date: 2010/06/10(木) 20:20   No:53939     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
もしかしたら「char型は文字で扱う為の方のはずなのに、何故キー番号として使っているの?」という疑問でしょうか。
DXライブラリはDirectXの複雑さをなるべく無くそうとしてあるライブラリです。
DirectXは独自の定義のオンパレードなので、初めてみるとわけがわからなく感じます。
そこで、DXライブラリはなるべく、見た事があるような型だけで実装してあります。

int, char, float, double位しか出てこないですよね。

そして、キーの番号はintで計算出来る整数型ですが、
256種類しかないので、4バイトも必要ありません。unsigned charで十分です。

そこで、DXライブラリではunsigned charをキー番号を入れる型として使っているわけです。

キー番号がいくつになっているかは、ヘッダファイルを見るといいですよ。
たとえば

KEY_INPUT_ESCAPE

と書いた上で、右クリック>定義に移動、さらに定義に移動すると値を見る事が出来ます。


133ポイント を手に入れた。

Name: kiri  ..かけだし(2,342ポイント)   Date: 2010/06/11(金) 00:08   No:53971     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
>「char型は文字で扱う為の方のはずなのに、何故キー番号として使っているの?」という疑問
指摘されている通りそのことが知りたかったんです。説明不足でした。
char型=文字しか扱わないと思っていました。

お二人の回答とリファレンスページを何度か読み返すなどして、なんとなく理解することができました。
ありがとうございます。

また、関連して、GetHitMouseStateAll_2関数をGetHitKeyStateAll_2とCheckStateKey関数のように使用するにはどうしたらいいのでしょうか?



195ポイント を手に入れた。

Name: fatens  ..中級者(11,746ポイント)   Date: 2010/06/11(金) 00:18   No:53973     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
>また、関連して、 GetHitMouseStateAll_2関数をGetHitKeyStateAll_2とCheckStateKey関数のように使用するにはどうしたらいいのでしょうか? 
それは、 GetHitMouseStateAll_2 関数を自分で作りたいということでしょうか?
GetHitKeyStateAll_2 関数は管理人さんが作られたもので、DXライブラリの関数ではありません。


118ポイント を手に入れた。

Name: kiri  ..かけだし(1,743ポイント)   Date: 2010/06/11(金) 00:36   No:53978     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
えーと、そうではなくて龍神録プログラミングの館にある
//key.cpp
unsigned int stateKey[256];

int GetHitKeyStateAll_2(){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) stateKey[i]++;
        else                            stateKey[i]=0;
    }
    return 0;
}

int CheckStateKey(unsigned char Handle){
        return stateKey[Handle];
}
を
//key.cpp
int GetHitMouseStateAll_2(Mouse_t *Nezumi){
    if(GetMousePoint( &Nezumi->x, &Nezumi->y ) == -1){ //マウスの位置取得
        return -1;
    }
    int MouseInput=GetMouseInput();    //マウスの押した状態取得
    for(int i=0; i<8; i++){            //マウスのキーは最大8個まで確認出来る
        if( (MouseInput & 1<<i ) != 0 ) Nezumi->Button[i]++;   //押されていたらカウントアップ
        else                            Nezumi->Button[i] = 0; //押されてなかったら0
    }
    Nezumi->WheelRotVol = GetMouseWheelRotVol() ;    //ホイール回転量取得
    return 0;
}

int CheckStateMouse(unsigned int Handle){
        return 〜〜〜;
}

という風にmain.cppから呼んで、GetHitMouseStateAll_2関数とCheckStateMouse関数を使用したいということです。


599ポイント を落としてしまった。

Name: fatens  ..中級者(12,005ポイント)   Date: 2010/06/11(金) 21:39   No:54047     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
なるほど。分かりました。

KEY_INPUT_ESCAPEなどと同じようにマウスについてもヘッダファイルで定められているのですが、
それをそのまま使うのは都合が悪いので、自分で#defineやenumで定義します。
以下は龍神録と同じようにしたものの例です。

//mouse.h
enum MOUSE_BUTTON {
    MOUSE_BUTTON_1,
    MOUSE_BUTTON_2,
    MOUSE_BUTTON_3,
    MOUSE_BUTTON_4,
    MOUSE_BUTTON_5,
    MOUSE_BUTTON_6,
    MOUSE_BUTTON_7,
    MOUSE_BUTTON_8,

    MOUSE_BUTTON_MAX
};

//mouse.cpp
#include "mouse.h"

static unsigned int stateMouse[MOUSE_BUTTON_MAX];

int GetHitMouseStateAll_2()
{
    //stateMouse[]に値を設定
}

int CheckStateMouse(MOUSE_BUTTON id){
    return stateMouse[id];
}

コンパイルしてませんが、これでどうでしょうか。



259ポイント を手に入れた。

Name: Dixq (管理人) [URL]  ..ウィザード(1,205,918ポイント)   Date: 2010/06/12(土) 03:53   No:54088     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
もしくは
mouse.cppを作り、引数となっているMouse_t構造体をグローバル変数にして、
CheckStateMouseはMouse_t型の構造体を返してはどうでしょう。

key.cppと全く同じように倣ってやってみるといいと思います。

意味が解らなければまた聞いて下さい。


112ポイント を手に入れた。

Name: kiri  ..かけだし(2,141ポイント)   Date: 2010/06/13(日) 22:16   No:54260     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
fatensさんが示された例を元に下記のようにしてみましたが合っていますか?
//mouse.cpp

int GetHitMouseStateAll_2(){
    if(GetMousePoint( &Mouse.x, &Mouse.y ) == -1){ //マウスの位置取得
        return -1;
    }
    int MouseInput=GetMouseInput();    //マウスの押した状態取得
    for(int i=0; i<8; i++){            //マウスのキーは最大8個まで確認出来る
        if( (MouseInput & 1<<i ) != 0 ) stateMouse[i]++;//押されていたらカウントアップ
        else                            stateMouse[i]=0;//押されてなかったら0
    }
    Mouse.WheelRotVol = GetMouseWheelRotVol() ;    //ホイール回転量取得
    return 0;
} 

int CheckStateMouse(MOUSE_BUTTON id){ 
    return stateMouse[id]; 
}
管理人さんが示された例を使った場合は、おそらくGetHitMouseStateAll_2()は上と同じでCheckStateMouse()はポインタを使用するのだと思いますが、どういった書き方(?)になるのかが分からないです。
int CheckStateMouse(Mouse_t *p){ 

}


398ポイント を手に入れた。

Name: fatens  ..中級者(13,420ポイント)   Date: 2010/06/13(日) 22:37   No:54262     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
>fatensさんが示された例を元に下記のようにしてみましたが合っていますか?
CheckStateMouse(MOUSE_BUTTON_1)
などとして思った通りの値が得られているのであれば大丈夫です。


私の例はマウスのボタンしか考えてなかったので、
マウスの座標なども扱うのであれば管理人さんの案のほうが良いですね。
ただ、CheckStateMouse 関数が返すのはstateMouseへのポインタで。
その場合は以下のような感じになるのではないでしょうか。
またコンパイルはしてませんが。

//mouse.cpp
static Mouse_t stateMouse;

int GetHitMouseStateAll_2()
{
    //...
}

Mouse_t *CheckStateMouse()
{
    return &stateMouse;
}

//使う側
Mouse_t *mouse = CheckStateMouse();
if (mouse->Button[0] > 0)
    //...


266ポイント を手に入れた。

Name: kiri  ..かけだし(2,233ポイント)   Date: 2010/06/14(月) 02:58   No:54285     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
Mouse_t *mouse = CheckStateMouse();

は使用する関数内で宣言するしかないのでしょうか?
いろいろなところで使うと思うのでグローバル変数としたいのですが

GLOBAL Mouse_t *mouse = CheckStateMouse();

としてみたのですが、エラーが出てしまいます。


92ポイント を手に入れた。

Name: fatens  ..中級者(13,616ポイント)   Date: 2010/06/14(月) 07:30   No:54291     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
>いろいろなところで使うと思うのでグローバル変数としたいのですが
グローバル変数にするのであればそもそもCheckStateMouse 関数は不要で、
GLOBAL Mouse_t mouse;
として、GetHitMouseStateAll_2 関数をGetHitKeyStateAll_2 関数と同じようにメインループで毎回呼び出し、
状態を知りたいときは直接mouse.xなどにアクセスすれば良いです。

>GLOBAL Mouse_t *mouse = CheckStateMouse();
>としてみたのですが、エラーが出てしまいます。
main.cppではGLOBALが削除され、mouseは定義になります。
main.cpp以外ではGLOBALはexternに置き換わりますが、初期化子を伴っているので定義とみなされます。
そのため同名のグローバル変数が存在し、エラーになるのではないでしょうか。


172ポイント を手に入れた。

Name: kiri  ..かけだし(2,344ポイント)   Date: 2010/06/14(月) 19:18   No:54358 解決!     
Title: Re:GetHitKeyStateAll_2とCheckStateKey    
>グローバル変数にするのであればそもそもCheckStateMouse 関数は不要
そうだったのですか・・・
GetHitKeyStateAll_2()関数と同じで、「キー情報の値が不正に書き換えられる危険性」があるものと思いCheckStateMouse()関数のようなものを使うのだと思っていました。

いろいろと勉強になりました。
fatensさん管理人さん、丁寧に教えて頂きありがとうございました。


111ポイント を手に入れた。



Name: たろう  ..プログラマー(27,617ポイント)   Date: 2010/06/14(月) 01:00   No:54282       
Title: アクションゲームの移動について    
アクションゲームの移動でフィールドを
int hantei[15][20] = {
        { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
        { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
        { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
};
のようにして通れない場所と通れる場所を区別しますが、
これ以外に通れる場所と通れない場所を区別することができる方法ってあるのでしょうか?


643ポイント を手に入れた。


Name: TKOZ  ..熟練のプログラマー(61,696ポイント)   Date: 2010/06/14(月) 09:15   No:54294     
Title: Re:アクションゲームの移動について    
ネットカフェからの書き込みです。
http://www.play21.jp/board/formz.cgi?action=res&resno=49320&page=30&lognum=152&id=dixq&rln=49484
過去ログにこんなプログラムがあります。参考にしてください。


89ポイント を手に入れた。

Name: たろう  ..プログラマー(28,289ポイント)   Date: 2010/06/14(月) 12:52   No:54307     
Title: Re:アクションゲームの移動について    
やっぱりint hantei[15][20] = { 
        { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, 
        { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, 
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 }, 
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 }, 
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 }, 
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 }, 
        { 1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1 }, 
        { 1,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1 }, 
        { 1,1,1,1,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,1 }, 
        { 1,1,1,1,1,0,0,0,1,1,1,0,0,0,1,0,0,0,1,1 }, 
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1 }, 
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 }, 
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 }, 
        { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, 
        { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, 
}; 
を使わない駄目みたいですね。
この方法以外でやることはできないのでしょうか?


672ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(95,019ポイント)   Date: 2010/06/14(月) 13:25   No:54309     
Title: Re:アクションゲームの移動について    
> この方法以外でやることはできないのでしょうか?

この方法でどんな問題があるか具体的に書いてくれれば、
解決方法を教えてもらえると思いますが。

その他の方法で比較的汎用性が高そうなのは、
フィールドの全ては同じだが配列で壁を表現するとか、
行けない部分を数式で判定するとか、でしょうか。

壁は縦と横があるので、フィールドを配列で持つよりも少し複雑です。
数式の場合は、元のマップやマップ生成のルールが単純でないならば、
やる価値はあまりないかな。

結局あなたが何をやりたいかです。


94ポイント を手に入れた。

Name: たろう  ..プログラマー(28,723ポイント)   Date: 2010/06/14(月) 13:40   No:54311     
Title: Re:アクションゲームの移動について    
回答ありがとうございます。
自分がやりたいのは、配列以外で壁などを作って通れなくすることはできるのかということです。


47ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(95,209ポイント)   Date: 2010/06/14(月) 13:53   No:54312     
Title: Re:アクションゲームの移動について    
> 自分がやりたいのは、配列以外で壁などを作って通れなくすることはできるのかということです。

私が聞きたいのは、何故配列以外で作りたいのか、ということです。
一連の質問でのやり取りを見ると、ゲームを作る上での定石というものを、
もっと練習したほうが良いと思います。
配列を使わないことで素晴らしいゲームになるアイデアがあったとしても、
まだ自由にプログラムを作れるレベルではないと思います。
まずは普通のゲームを普通に作れるようになることだと思いますが。

その上で、何故配列を使いたくないのですか?
使わないですむ方法は色々ありますが、お勧めできる方法かどうかは、
もっと詳しく聞かないと判りません。


190ポイント を手に入れた。

Name: シエル  ..初心者(8,113ポイント)   Date: 2010/06/14(月) 13:57   No:54316     
Title: Re:アクションゲームの移動について    
>>自分がやりたいのは、配列以外で壁などを作って通れなくすることはできるのかということです。
できないことはないでしょう。
全体的に質問内容がアバウトすぎる気がします。


66ポイント を手に入れた。

Name: たろう  ..プログラマー(28,912ポイント)   Date: 2010/06/14(月) 14:03   No:54318     
Title: Re:アクションゲームの移動について    
ただ気になっただけなので質問しました。いろいろあるんですか。
>まずは普通のゲームを普通に作れるようになることだと思いますが。 
はい。そうしたいと思います。

ただ、その色々の中のなんでも一つでいいので簡単に説明してはもらえないでしょうか?
難しくてもよいので。よろしくお願いします。


75ポイント を手に入れた。

Name: たいちう  ..比類無きプログラマー(95,411ポイント)   Date: 2010/06/14(月) 14:25   No:54321     
Title: Re:アクションゲームの移動について    
何でも良いならば、既に書きました。

> 行けない部分を数式で判定するとか、でしょうか。

例えばS(sx, sy)の近く(縦横3マス)には行けないとして、
このように書けます。

if (abs(sx - x) + abs(sy - y) <= 3)
  // 行けない
else
  // 行ける

原理的にはどのようなマップも数式で表せますが、
単純なルールのマップでなければ、この方法は使わないほうが良いでしょう。


その他の方法としては、背景のビットマップの色で判定とか。


107ポイント を手に入れた。

Name: たろう  ..プログラマー(29,082ポイント)   Date: 2010/06/14(月) 14:47   No:54324 解決!     
Title: Re:アクションゲームの移動について    
まずはゲームを作ることから始めたいと思います。
回答ありがとうございました。


21ポイント を手に入れた。

Name: softya [URL]  ..ハッカー(180,911ポイント)   Date: 2010/06/14(月) 15:19   No:54326     
Title: Re:アクションゲームの移動について    
色々ありますよ。
(1)マップチップの番号で通れる通れないを管理する。
(2)マップチップ番号の情報配列を作って管理する。
マップチップ番号で通行可否・マップチップのアニメーション有無・前景背景などを管理。
(3)マップ配列→アトリビュート配列(マップ配列上の番号で参照)→マップチップ配列(アトリビュート配列の構造体に含まれるマップチップ番号で参照)と更に高機能化します。アトリビュート(属性)とは(2)でも書いた付随する情報のことですね。アトリビュートで通行可否・マップチップのアニメーション有無・前景背景のマップチップ番号などを管理ます。

(2)(3)辺りはプロだとこうするって例ですが高度な知識が不可欠です。
これ以外にも管理する方法は、作る人の趣味も含めて千差万別で数え切れない方法が有り得ます。


219ポイント を手に入れた。

Name: dic  ..比類無きプログラマー(72,161ポイント)   Date: 2010/06/14(月) 16:56   No:54330     
Title: Re:アクションゲームの移動について    
反応ないので消しますね 編集済み

255ポイント を手に入れた。



Name: 爺プログラマー  ..ぴよぴよ(75ポイント)   Date: 2010/06/13(日) 21:24   No:54253       
Title: 同時に複数録音するには    
サウンドカードを複数枚搭載して、それぞれのカードの音声を別々に録音する関数を教えてください。

DirectSoundCaptureCreate8(
CreateCaptureBuffer(

この当たりでは使えないとおもうのですが、よろしくお願いします。


75ポイント を手に入れた。


Name: 爺プログラマー  ..ぴよぴよ(3ポイント)   Date: 2010/06/14(月) 14:10   No:54319     
Title: Re:同時に複数録音するには    
この質問の補足ですが・・・OSはXPです。
マイクとライン個別に同時に録音可能なAPIを教えてください。



3ポイント を手に入れた。



Name: ft [URL]  ..上級者(16,039ポイント)   Date: 2010/06/13(日) 21:38   No:54254       
Title: みょん弾幕で見られるスローモーション    
こんにちは。
タイトル通り、妖夢の弾幕などでみられる強制スローモーションについてですが、どのような方法で実装できるでしょうか?
思い付いたものとしては、全ての速度、アングル等に係数を掛けることで実現出来そうなのですが、係数の管理が大変そうに見えます。
もっと良い管理方法はないでしょうか?


110ポイント を手に入れた。


Name: jay  ..上級者(17,047ポイント)   Date: 2010/06/14(月) 00:32   No:54280     
Title: Re:みょん弾幕で見られるスローモーション    
あれは僕も本気で考えたことがありますね、ややこし過ぎて挫折しましたがw
以下はその時考えたことです、参考にでもして下さい。


これは係数による数値の補正ではなく、あらかじめスロー時の処理をする関数を作っておくものです。

まずslow_flagなるものをグローバル変数で作りました。
これが0の時は通常通りの処理。
1の時は全体をスローにする処理、という具合です。

例えばキャラ移動の場合は
普段は移動キーが押されていると5ピクセルずつ。
slow_flagが1になった場合は移動量を半分に、するといった感じですね。


同じように敵の弾を管理する関数でも
slow_flagが0の時は通常の処理を、1の時は移動量を半分にとすれば理論上は実装出来ると思います。
全ての物から一定の割合で速度を引けば、弾のアングルに補正を掛ける必要もなくなるとおもいます。


slow_flagを1にする部分は、弾幕の関数でいいかと思われます。
龍神録風にいうなら
if (boss_shot.cnt == 100)
   slow_flag = 1;

といった具合です。

探せばっもっと楽な方法もあるかもしれませんけどね。


339ポイント を手に入れた。

Name: y  ..初心者(5,598ポイント)   Date: 2010/06/14(月) 00:41   No:54281     
Title: Re:みょん弾幕で見られるスローモーション    
大雑把、というか、多分本家でも使われてる方法ですが、
60FPSの状態で、通常1フレームに一度更新するのを2フレームに一度にすれば、
結構楽に実装できると思います。


46ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(545,095ポイント)   Date: 2010/06/14(月) 03:09   No:54286     
Title: Re:みょん弾幕で見られるスローモーション    
>全ての速度、アングル等に係数を掛けることで実現出来そうなのですが、係数の管理が大変そうに見えます。 
 大変なのは管理じゃなくて、係数から計算する方では?
 設計段階である程度システム側で吸収できるよう作っておくとか、サポート用のクラス・関数を作っておけば
少しは楽かもしれません。


>60FPSの状態で、通常1フレームに一度更新するのを2フレームに一度にすれば
 更新の処理負荷は高くなりますが、通常時は2回スロー時は1回更新する、でもいいですね。


128ポイント を手に入れた。

Name: ft  ..上級者(16,148ポイント)   Date: 2010/06/14(月) 12:29   No:54305 解決!     
Title: Re:みょん弾幕で見られるスローモーション    
ありがとうございます。
スローモーションといっても色んなやり方があるんですね。
yさんの方法は制御が簡単になりそうなのですが、
PSPに実装しようと考えているためJustyさんの言われるように処理速度が気になります。
今回はjayさんのように設計段階からスローを想定した構造を組み立てていこうかと思います。
みなさんどうもありがとうございました。


109ポイント を手に入れた。



Name: kai  ..上級者(16,811ポイント)   Date: 2010/06/13(日) 13:13   No:54199       
Title: メッセージボックスについて    
よくDXライブラリを使った皆さまのゲームで使われてる
メッセージボックスのこのプログラムですが

void message_box(){
    int flag;
    flag=MessageBox(
        NULL,
        TEXT("フルスクリーンモードで起動しますか?"),
        TEXT("スクリーン設定"), 
        MB_YESNO | MB_ICONQUESTION );
    if(flag==IDNO)
        ChangeWindowMode( TRUE );
}

実行すると右上に×のマークが表示されますよね?
このプログラムでは×マークを押しても何の変化もないのですが、
×マークを押したら、メッセージボックスを消す(ゲームを終了させる)
ようにしたいのですが、どうしたらいいのでしょうか?
分かる方がいましたら、どういったプログラムを追加、修正すると可能なのか教えてください・・
よろしくお願いします。



199ポイント を手に入れた。


Name: シエル  ..入門者(4,255ポイント)   Date: 2010/06/13(日) 13:29   No:54201     
Title: Re:メッセージボックスについて    
下記のMessageBoxの第四引数をMB_YESNOCANCELに変更。
この状態で×ボタンを押すとキャンセルボタンが押されたことになるので、
flagがIDCANCELのときだけ終了処理を書けばいい。

flag=MessageBox( NULL, TEXT("フルスクリーンモードで起動しますか?"), TEXT("スクリーン設定"),  
MB_YESNOCANCEL | MB_ICONQUESTION ); 
if(flag==IDNO) 
        ChangeWindowMode( TRUE ); 
else if(flag==IDCANCEL)
       //ここに終了処理を書く


メッセージボックスにキャンセルボタンが出てしまいますが、消し方は分かりません。


145ポイント を手に入れた。

Name: kai  ..上級者(17,160ポイント)   Date: 2010/06/13(日) 13:59   No:54205     
Title: Re:メッセージボックスについて    
>シエルさん
う〜ん・・
言われた通り試してみましたが

void message_box(){
    //int flag;
    //flag=MessageBox(
    //    NULL,
    //    TEXT("フルスクリーンモードで起動しますか?"),
    //    TEXT("スクリーン設定"), 
    //    MB_YESNO | MB_ICONQUESTION );
    //if(flag==IDNO){
    //    ChangeWindowMode( TRUE );
    //}
    int flag;
    flag=MessageBox(
        NULL,
        TEXT("フルスクリーンモードで起動しますか?"),
        TEXT("スクリーン設定"), 
        MB_YESNOCANCEL | MB_ICONQUESTION );
    if(flag==IDNO){
        ChangeWindowMode( TRUE );
    }
    else if(flag==IDCANCEL){
        DxLib_End();        //DXライブラリ終了処理
    }
}

キャンセルボタンはいらないですね・・
ついでにキャンセルボタンを押した場合はフルスクリーン。
×ボタンを押しても終了するどころか
フルスクリーン画面になり、ゲームがスタートしてしまいました。

他にご存知の方、その辺のプログラムに詳しい方がいましたら教えてください。
よろしくお願いします 編集済み


349ポイント を手に入れた。

Name: シエル  ..入門者(4,391ポイント)   Date: 2010/06/13(日) 14:12   No:54207     
Title: Re:メッセージボックスについて    
おかしいですね。
ボタンの動作は間違いないはずなんですけど。。
この関数以外の場所で、
「いいえ」ボタンを押す以外はすべてフルスクリーン起動
するようになってませんか?


63ポイント を手に入れた。

Name: シエル  ..入門者(4,472ポイント)   Date: 2010/06/13(日) 14:24   No:54209     
Title: Re:メッセージボックスについて    
ゲームがスタートしてしまうのも、
else if(flag==IDCANCEL)の処理で、起動しないようにしないとスタートしてしまいますよ。

メッセージボックスのボタンも、自作のダイアログボックスを作るなりするしか
ないと思います。。


81ポイント を手に入れた。

Name: kai  ..上級者(17,662ポイント)   Date: 2010/06/13(日) 15:19   No:54213     
Title: Re:メッセージボックスについて    
>この関数以外の場所で、 
>「いいえ」ボタンを押す以外はすべてフルスクリーン起動 
>するようになってませんか?
いえ、調べてみましたが特にそういった操作はしてませんでした。

>else if(flag==IDCANCEL)の処理で、起動しないようにしないとスタートしてしまいますよ。 
と、いうと具体的にはどうしたら良いのでしょうか?
よろしければ教えてください。

>メッセージボックスのボタンも、自作のダイアログボックスを作るなりするしか 
>ないと思います。。
すると、シエルさんがおっしゃる結論としてはMB_YESNOを使った場合、
×ボタンを押したときの操作方法は設定出来ないということでしょうか?
それならば諦めるしかないですね・・・残念です。
MB_YESNOCANCELでキャンセルを押したとき、または×ボタンを押したときに
終了する方法はないでしょうか?分かる方がいましたら教えてください。


2倍のポイントを手に入れた! 502ポイント を手に入れた。

Name: シエル  ..初心者(5,088ポイント)   Date: 2010/06/13(日) 16:13   No:54217     
Title: Re:メッセージボックスについて    
>いえ、調べてみましたが特にそういった操作はしてませんでした。  
>と、いうと具体的にはどうしたら良いのでしょうか? 
>よろしければ教えてください。

この関数を呼び出しているメインのソースコードを貼って下さい。答えようがありません。

>すると、シエルさんがおっしゃる結論としてはMB_YESNOを使った場合、 
>×ボタンを押したときの操作方法は設定出来ないということでしょうか? 
>それならば諦めるしかないですね・・・残念です。 
>MB_YESNOCANCELでキャンセルを押したとき、または×ボタンを押したときに 
>終了する方法はないでしょうか?分かる方がいましたら教えてください。

MB_YESNOを指定した場合は右上の×ボタンがグレーアウトして押せなかったはずだと思います。
ですので、MB_YESNOを指定した場合は右上の×ボタンを使った操作は行えないと私は思っています。

そこで代替案として、MB_YESNOCANCELを指定する方法や、自作ダイアログボックスを作成する
方法を提案しているわけです。
後者の方はちょっと難しいですが。。。

まあ私もまだ初心者のレベルなので他の人の意見も参考にして下さい。


2倍のポイントを手に入れた! 616ポイント を手に入れた。

Name: kai  ..上級者(17,833ポイント)   Date: 2010/06/13(日) 23:33   No:54266     
Title: Re:メッセージボックスについて    
>この関数を呼び出しているメインのソースコードを貼って下さい。答えようがありません。 

こんな感じでしょうか

//メッセージボックスのウィンドウを利用する
void message_box(){
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){

    略

    message_box();

    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;    //初期化と裏画面化

    while(ProcessLoop()==0){        //メインループ
    略



171ポイント を手に入れた。

Name: 白い時空  ..ぴよぴよ(383ポイント)   Date: 2010/06/13(日) 23:52   No:54270     
Title: Re:メッセージボックスについて    
あの、message_box()で、IDCANCELのときにDxLib_End関数を呼んでいますが、これではプログラムは終了しません。
IDCANCELのとき、WinMainでreturn 0をすればいいはずです。


61ポイント を手に入れた。

Name: シエル  ..初心者(7,272ポイント)   Date: 2010/06/13(日) 23:58   No:54271     
Title: Re:メッセージボックスについて    
DxLib_Initを呼んだ後に終了する場合であれば、DxLib_Endを呼ぶ必要がありますが、
このメッセージボックス関数を呼んでる場所は、DxLib_Initをまだ呼び出していないので、
DxLib_Endを呼ぶ必要はありません。

白い時空さんがおっしゃってるように、return 0;を書いて終了させればいいだけです。 編集済み


103ポイント を手に入れた。

Name: kai  ..上級者(17,959ポイント)   Date: 2010/06/14(月) 00:08   No:54275     
Title: Re:メッセージボックスについて    
あの

void message_box(){
    int flag; 
    flag=MessageBox( 
        NULL, 
        TEXT("フルスクリーンモードで起動しますか?"), 
        TEXT("スクリーン設定"),  
        MB_YESNOCANCEL | MB_ICONQUESTION ); 
    if(flag==IDNO){ 
        ChangeWindowMode( TRUE ); 
    } 
    else if(flag==IDCANCEL){ 
        return 0;
    } 
}
これだとエラーが出るのですが・・


126ポイント を手に入れた。

Name: シエル  ..初心者(7,494ポイント)   Date: 2010/06/14(月) 00:14   No:54277     
Title: Re:メッセージボックスについて    
言い方が悪かったかも知れません。
WinMain関数内でreturn 0;を呼び出してください。

void message_box()関数内で、return 0;を呼び出してもその関数の戻り値で0
を返しているだけになります。

なので、void message_box()関数の戻り値として、flagの値を戻すようにし、
WinMain関数内で、その戻り値の値を判定し、return 0;を呼び出すようにしてください。


146ポイント を手に入れた。

Name: シエル  ..初心者(7,980ポイント)   Date: 2010/06/14(月) 00:19   No:54278     
Title: Re:メッセージボックスについて    
message_box関数はこんな感じ。

int message_box(){ 
    int flag;  
    flag=MessageBox(  
        NULL,  
        TEXT("フルスクリーンモードで起動しますか?"),  
        TEXT("スクリーン設定"),   
        MB_YESNOCANCEL | MB_ICONQUESTION );  
    if(flag==IDNO){  
        ChangeWindowMode( TRUE );  
    }  
    else if(flag==IDCANCEL){  
        return flag; 
    }

return 0;
}


で、WinMain内ではこんな感じに呼び出す。

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){ 

    略 
//メッセージボックス関数はこう呼び出す。
    if(IDCANCEL==message_box()){
       return 0;
    }

    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;    //初期化と裏画面化 

    while(ProcessLoop()==0){        //メインループ 
    略 


2倍のポイントを手に入れた! 486ポイント を手に入れた。

Name: kai  ..上級者(17,860ポイント)   Date: 2010/06/14(月) 00:22   No:54279 解決!     
Title: Re:メッセージボックスについて    
おお出来ました!
ありがとうございます。
助かりました! 編集済み


99ポイント を落としてしまった。



Name: prester  ..ぴよぴよ(573ポイント)   Date: 2010/06/12(土) 22:37   No:54155       
Title: ポインタ変数について    
初めてお世話になります。よろしくお願いします。
ポインタ変数とアドレスについて調べる問題なのです。元々はint型だったのを私が以下のように
char型に変えました。これを今度はdouble型に変えたいのですがこれができません。
さらに、printf("%p) = ox%x\n", ptr_d, *ptr_d):を用いて表示すると図1のようになる。これを図2のように表示しなさいという問題です。
[図1]               [図2]
0.22ccc0) = 0.3020100        ptc_d:0.22ccc0) = 0.3020100
0.22ccc8) = 0.b0a0306              0.22ccc4) = 0.7060504
                  ptr_d:0.22ccc8) = 0.b0a0306
                     0.22cccc) = 0.f0e0d0e

#include <stdio.h>

int main(void){
char src[32], dst[32];
    char *ptr_c, *a;
    int *ptr_i, *ptr;
    double *ptr_d;
    int i;
    // src[i]配列にデータを格納
    for(i=0; i<32; i++){
        src[i] = i;
    }

    // ptr_cにsrcの先頭アドレスをコピー
    ptr_i =(int *) src;

    // ptrを使用してsrc[i]のデータを内容を出力する。
    for(i=0; i<8; i++){
        printf("%p)  = 0x%x\n", ptr_i, *ptr_i);
        ptr_i++;
        if(i==6){
            a = (char *) ptr_i;
        }    
    }
    printf("アドレスの差=%d",(char *) ptr_i - a);
}

どうぞよろしくお願いします。


573ポイント を手に入れた。


Name: prester  ..ぴよぴよ(587ポイント)   Date: 2010/06/13(日) 22:23   No:54261     
Title: Re:ポインタ変数について    
誰もわかりませんか?

14ポイント を手に入れた。

Name: box  ..ハッカー(154,533ポイント)   Date: 2010/06/13(日) 22:46   No:54263     
Title: Re:ポインタ変数について    
> [図1]               [図2]
> 0.22ccc0) = 0.3020100        ptc_d:0.22ccc0) = 0.3020100
> 0.22ccc8) = 0.b0a0306              0.22ccc4) = 0.7060504
>                   ptr_d:0.22ccc8) = 0.b0a0306
>                      0.22cccc) = 0.f0e0d0e

そもそも、与コードの出力結果が図1のようにならないところに、
回答が付かない原因があるのではないでしょうか。


43ポイント を手に入れた。

Name: シエル  ..初心者(7,348ポイント)   Date: 2010/06/14(月) 00:10   No:54276     
Title: Re:ポインタ変数について    
どこがどうできないのか具体的に説明して下さい。

16ポイント を手に入れた。



Name: 深黒  ..入門者(2,618ポイント)   Date: 2010/06/11(金) 20:37   No:54041       
Title: メニューバー    
DXライブラリで、上部にメニューバー(?)を表示する方法を知りたいです。
あと、出来れば設定を反映する方法も教えて欲しいです(文字サイズを変更する等簡単な物を例で…)。 編集済み


58ポイント を手に入れた。


Name: a  ..かけだし(1,354ポイント)   Date: 2010/06/11(金) 22:13   No:54050     
Title: Re:メニューバー    
こういうバーのことでしょうか?

18ポイント を手に入れた。

Name: 深黒  ..入門者(2,623ポイント)   Date: 2010/06/11(金) 22:33   No:54054     
Title: Re:メニューバー    
そうです。
そういったメニューバーの出し方や設定の反映の仕方等が知りたいです 編集済み


5ポイント を手に入れた。

Name: a  ..かけだし(1,550ポイント)   Date: 2010/06/12(土) 22:26   No:54152     
Title: Re:メニューバー    
DirectXなら簡単に出来ますが
DXライブラリではどうなんでしょうね。
私も知りたいです。


43ポイント を手に入れた。

Name: シエル  ..入門者(4,031ポイント)   Date: 2010/06/12(土) 22:33   No:54154     
Title: Re:メニューバー    
WinAPIならウインドウクラスの登録時やウインドウ作成時、またはSetMenu関数を使えばできますけど、
DXライブラリでは私も分かりません。
ウインドウハンドル取得して、SetMenu関数を呼び出すしかないのかな。。
私も知りたいです。


2倍のポイントを手に入れた! 218ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(543,701ポイント)   Date: 2010/06/12(土) 22:37   No:54156     
Title: Re:メニューバー    
 過去に似たような質問がありました。

C言語何でも質問掲示板 - DXライブラリでメニューバーを作りたいのですが
http://www.play21.jp/board/formz.cgi?action=res&resno=14837&page=30&lognum=47&id=dixq&rln=14850


62ポイント を手に入れた。

Name: 深黒  ..入門者(2,720ポイント)   Date: 2010/06/13(日) 00:09   No:54165     
Title: Re:メニューバー    
返信ありがとうございます。
とりあえずヘッダを確認しましたが、
int AddMenuItem( int AddType /* MENUITEM_ADD_CHILD等 */ , const char *ItemName, int ItemID,
int SeparatorFlag, const char *NewItemName = NULL , int NewItemID = -1 ) ;
引数をどう入れればいいのか分からないです・・・


97ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(544,848ポイント)   Date: 2010/06/13(日) 02:23   No:54180     
Title: Re:メニューバー    
 大体こんな感じです。
 細かいパラメータの意味は本家の掲示板で訊いた方がいいでしょうけど、
メニューにIDを割り振ってどれを親にしてどの項目を追加するのかを指定します。

    enum { MenuID_File = 1000, MenuID_NewFile, MenuID_Open, MenuID_Exit, MenuID_Help, MenuID_About };
    AddMenuItem(MENUITEM_ADD_CHILD, NULL, MENUITEM_IDTOP, FALSE, "ファイル(&F)", MenuID_File);
    AddMenuItem(MENUITEM_ADD_CHILD, NULL, MenuID_File, FALSE, "新規作成(&N)", MenuID_NewFile);
    AddMenuItem(MENUITEM_ADD_CHILD, NULL, MenuID_File, FALSE, "開く(&O)", MenuID_Open);
    AddMenuItem(MENUITEM_ADD_CHILD, NULL, MenuID_File, TRUE, NULL, 0);
    AddMenuItem(MENUITEM_ADD_CHILD, NULL, MenuID_File, FALSE, "終了(&X)", MenuID_Exit);
    AddMenuItem(MENUITEM_ADD_CHILD, NULL, MENUITEM_IDTOP, FALSE, "ヘルプ(&H)", MenuID_Help);
    AddMenuItem(MENUITEM_ADD_CHILD, NULL, MenuID_Help, FALSE, "About...(&A)", MenuID_About);



 あぁ、制限はありますけど AddMenuItem_Nameの方が楽かもしれません。
 こちらは親の名前と子の名前だけの指定でメニューを作れます。

    AddMenuItem_Name(NULL, "A");
    AddMenuItem_Name("A", "B");


772ポイント を手に入れた。

Name: 深黒  ..入門者(3,467ポイント)   Date: 2010/06/13(日) 16:28   No:54220     
Title: Re:メニューバー    
返信ありがとうございます。
メニューバーの出し方は分かりましたが、そこからの設定の反映等のやり方がわからないです・・・
C++は初心者の部類なので・・・
簡単な例でいいので教えて欲しいです


65ポイント を手に入れた。

Name: シエル  ..初心者(5,113ポイント)   Date: 2010/06/13(日) 16:31   No:54222     
Title: Re:メニューバー    
設定の反映とは、「このメニューを選択したらこう動かしたい」ということでしょうか?
もしそうであれば、通常はウィンドウプロシージャで制御します。

追記:
私は普段はDXライブラリを一切使用しないので、DXライブラリでは
ウィンドウプロシージャをどのように制御しているのか、
また、どのようにすればメッセージを制御できるのかは分かりません。 編集済み


1ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(544,821ポイント)   Date: 2010/06/13(日) 17:29   No:54234     
Title: Re:メニューバー    
>設定の反映等等
 設定の反映ですか?
 よく意味がわかりませんが、ひょっとしてメニューが選択されたかどうか、
されたら何が選択されたかを知りたいということですか?

 さすがに設定の変え方については情報が不足しているのでこちらではわかりませんが、
メニューが選択されたときの判定方法でしたら以下の関数を使って判定して下さい。

・ CheckMenuItemSelectAll
・ CheckMenuItemSelect
・ CheckMenuItemSelect_Name
・ CheckMenuItemSelect_ID

 意味はヘッダを参照して下さい。


27ポイント を落としてしまった。

Name: a  ..かけだし(1,704ポイント)   Date: 2010/06/13(日) 18:03   No:54240     
Title: Re:メニューバー    
多分ですが、深黒さんが言いたいのは、

例えば、「画面」というメニューバーを作ったとして、
そのボタンをマウスで押した時、選択肢で
「フルスクリーン」と「ウインドウサイズ」という項目が出てくる。
そして、ウインドウサイズのときにフルスクリーンのボタンを押したとき
フルスクリーンに変わる。と、こういった具合に
具体的なプログラムをどこに書けばよいのか分からない

と、こう言いたいのではないのでしょうか?


154ポイント を手に入れた。

Name: 深黒  ..入門者(3,578ポイント)   Date: 2010/06/13(日) 18:47   No:54246     
Title: Re:メニューバー    
aさんの言ったとおりです。
分かりにくい質問の仕方をしてしまったようですみません。


12ポイント を手に入れた。

Name: はね  ..上級者(17,221ポイント)   Date: 2010/06/13(日) 19:21   No:54249     
Title: Re:メニューバー    
私もサンプルがあれば見てみたいですね。
メニューバーの作り方は知らないので気になります。


23ポイント を手に入れた。

Name: Justy  ..伝説なるハッカー(544,967ポイント)   Date: 2010/06/13(日) 21:48   No:54257     
Title: Re:メニューバー    
 メニューが選択されたかどうかを判定する関数は No54234で列挙した通りです。
 一番上はメニューがたくさんある場合の事前判定に使い、下3つは直接IDやら名前を指定して
各メニューが選択されたことを判定できます。
 
 これをメインループ内で毎フレーム判定して、選択されたのならそれぞれのアクションを
記述すればOKです。


146ポイント を手に入れた。

Name: 白い時空  ..ぴよぴよ(322ポイント)   Date: 2010/06/13(日) 22:08   No:54258     
Title: Re:メニューバー    
私もメニューバーの作り方が気になったので、DxLib.hを見て、サンプルを作ってみました。
分かりにくかったらごめんなさい。

DXライブラリなので、作るのは難しくないです。

DxLib.hの中には、メニューの関数が他にもありました。
(DxLib.hを"Menu"で検索すれば出ます)

DXライブラリには公式HPに載っていない関数が結構ありますね。


137ポイント を手に入れた。

Name: 深黒  ..入門者(3,645ポイント)   Date: 2010/06/13(日) 23:16   No:54264 解決!     
Title: Re:メニューバー    
返信ありがとうございます!
これを元に頑張ってみたいと思います!


27ポイント を手に入れた。

Name: はね  ..上級者(17,257ポイント)   Date: 2010/06/13(日) 23:30   No:54265     
Title: Re:メニューバー    
フルスクリーンのときに
メニューの項目にマウスを当てると
メニューバーが点滅するのは
DXライブラリの仕様なのかな?


36ポイント を手に入れた。

Name: fatens  ..中級者(13,444ポイント)   Date: 2010/06/14(月) 00:01   No:54272     
Title: Re:メニューバー    
メニューはGDIなのでDirectXとの相性が悪いのでは。
1秒間に画面を何十回も描画していますし。


24ポイント を手に入れた。

Name: シエル  ..初心者(7,332ポイント)   Date: 2010/06/14(月) 00:04   No:54273     
Title: Re:メニューバー    
メニュバーをつけると、処理速度が遅くなるって聞いたことがあります。

2倍のポイントを手に入れた! 60ポイント を手に入れた。




 
[ 1 , ... ]
 
 
管理者画面   RSS   + Powered By 21style +