|
Name: DTX ..ぴよぴよ(879ポイント)
Date: 2009/02/28(土) 00:10
No:29541
|
|
Title: マウスによる選択
|
|
マウスによる選択を作ったのですが、二箇所目を作るとフリーズします。
何故でしょうか?
#include "DxLib.h"
#include <stdio.h>
typedef struct{
int x;
int y; //座標
int WheelRotVol;//ホイールの回転量
unsigned int Button[8]; //ボタンの押した状態
}Mouse_t;
Mouse_t Mouse;
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;
}
以下メインでの選択画面
SetMouseDispFlag( TRUE ) ;//マウス表示オン
while(b==0){
//↑メッセージ処理 ↑画面をクリア ↑ESCが押されていない
GetHitMouseStateAll_2(&Mouse); //マウスの入力状態取得
/* DrawFormatString(0,0,White,"座標[%d,%d],回転量:%d,",Mouse.x,Mouse.y,Mouse.WheelRotVol);
for(int i=0; i<8; i++){
DrawFormatString(0, 20+20*i, White, "ボタン%d:%u", i, Mouse.Button[i]);
}*/
if(Mouse.x>50 && Mouse.x<150 && Mouse.y>350 && Mouse.y <365 && Mouse.Button[0]> 1){
change_card[0]=1;
DrawBox( 50,350 , 150 , 365 , BoxCr , TRUE ) ;
DrawFormatString(50,350, Ano, "HOLD 1:" );
}
if(Mouse.x>170 && Mouse.x<270 && Mouse.y>350 && Mouse.y <365 && Mouse.Button[0]> 1){
change_card[1]=1;
DrawBox( 170,350 , 270 , 365 , BoxCr , TRUE ) ;
DrawFormatString(170,350, Ano, "HOLD 2:" );
}
if(Mouse.x>290 && Mouse.x<390 && Mouse.y>350 && Mouse.y <365 && Mouse.Button[0]> 1){
change_card[2]=1;
DrawBox( 290,350 , 390 , 365 , BoxCr , TRUE ) ;
DrawFormatString(290,350, Ano, "HOLD 3:" );
}
if(Mouse.x>410 && Mouse.x<510 && Mouse.y>350 && Mouse.y <365 && Mouse.Button[0]> 1){
change_card[3]=1;
DrawBox( 410,350 , 510 , 365 , BoxCr , TRUE ) ;
DrawFormatString(410,350, Ano, "HOLD 4:" );
}
if(Mouse.x>530 && Mouse.x<630 && Mouse.y>350 && Mouse.y <365 && Mouse.Button[0]> 1){
change_card[4]=1;
DrawBox( 530,350 , 630 , 365 , BoxCr , TRUE ) ;
DrawFormatString(530,350, Ano, "HOLD 5:" );
}
if(Mouse.x>200 && Mouse.x<300 && Mouse.y>380 && Mouse.y <395 && Mouse.Button[0]> 1){
DrawFormatString(200,380, White, "Clear" );
DrawBox( 50,350 , 150 , 365 , BoxCr , TRUE ) ;
DrawFormatString(50, 350, White, "card %d:" , 1 );
DrawBox( 170,350 , 290 , 365 , BoxCr , TRUE ) ;
DrawFormatString(170,350, White, "card %d:" , 2 );
DrawBox( 290,350 , 410 , 365 , BoxCr , TRUE ) ;
DrawFormatString(290,350, White, "card %d:" , 3 );
DrawBox( 410,350 , 510 , 365 , BoxCr , TRUE ) ;
DrawFormatString(410,350, White, "card %d:" , 4 );
DrawBox( 530,350 , 630 , 365 , BoxCr , TRUE ) ;
DrawFormatString(530,350, White, "card %d:" , 5 );
for(i=0;i<5;){
change_card[i]=0;
i=i++;
}
}
ここがおかしい if(Mouse.x>438 && Mouse.x<520 && Mouse.y>380 && Mouse.y <395 && Mouse.Button[0]> 1){
b=1;
}
ScreenFlip();
}
この部分でマウスをクリックすると固まります。
但し一回だけしかマウス選択を行わなければ問題ありません。
よろしくお願いします。
879ポイント を手に入れた。
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(66,315ポイント)
Date: 2009/02/28(土) 01:37
No:29542
|
|
Title: Re:マウスによる選択
|
|
まず規約を読んでください。
字下げ、プレタグ等がされていません。
あと、コードが断片すぎて分かりません。
>以下メインでの選択画面
以下のコードは何ですか?関数ではありませんよね?
bというのも変数宣言されていません。
まず、コンパイルの通ったコードからの関数を抜粋し、適宜説明を加えてください。
147ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(324,104ポイント)
Date: 2009/02/28(土) 01:40
No:29543
|
|
Title: Re:マウスによる選択
|
|
>i=i++;
ここは怪しいです。
結果が不定になるので、問題の原因にもなり得ます。
しかし、雰囲気的にクリックしているところも違うので、多分原因とは違うのでしょう。
正直これだけの情報ではわからないので、周辺のコードも含めて
公開した方がいいのかもしれません。
148ポイント を手に入れた。
|
|
|
|
|
Name: 御津凪 [URL] ..熟練のプログラマー(63,806ポイント)
Date: 2009/02/28(土) 10:38
No:29544
|
|
Title: Re:マウスによる選択
|
|
断片コードからの推測です。
while(b==0) の中で ScreenFlip(); 等の更新処理を行っていませんか?
b=1; になると、 ScreenFlip(); が含まれている while(b==0) ブロック内に入ることにならず( ScreenFlip されず)、
画面が固まったように見えるのでは?
そうでないのなら、これ以上は本当に分からない(記載箇所以外に問題がある可能性がある)ので、
規約を守りつつ、全体のコードを提示するか添付してください。
183ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(12,311ポイント)
Date: 2009/02/28(土) 16:11
No:29556
|
|
Title: Re:マウスによる選択
|
|
妄想によって補完してみました。
一応動く形にまとめてみましたが、これはどうなれば想定していた結果になりますか?
34ポイント を手に入れた。
|
|
|
|
Name: Kou ..かけだし(2,307ポイント)
Date: 2009/02/28(土) 13:00
No:29547
|
|
Title: 龍神録プログラミングの館で
|
|
以前違う内容で質問させて頂いたKouです。
今回『龍神録プログラミングの館』の【EXCELのファイルから・・・】の内容について
若干分からない事がありましたので、質問させて頂きます。
EXCELで作成したCSVファイルを読み込む時に、最初の方で【2行読み飛ばす】部分があり、
その後更に【/なら行末まで読み飛ばす】という処理がループ内にありますが、これは何の為でしょうか?
【//】でコメントの様になっているのは最初の2行だけなので、ループ内で更に読み飛ばす処理の意味が
今ひとつ理解できません。
これは例えば、1つのCSVファイルの中に、『1面のデータ』、『2面のデータ』等分けて入れた時の為の
処理と考えて良いのでしょうか?
初歩的な質問になりますが、宜しくお願いします。
183ポイント を手に入れた。
|
|
|
|
Name: Kou ..かけだし(2,430ポイント)
Date: 2009/02/28(土) 13:40
No:29550
| 解決!
|
Title: Re:龍神録プログラミングの館で
|
|
早速の回答ありがとうございます。
やはりそうでしたか^^
内容的に質問しても良いものか迷ったんですが、CSVの内容とソースを見比べて理解しようとしたところ
本当にその考えで良いのか今ひとつ確信がなかったので、質問させて頂きました。
この様な初歩的な内容でも、快く回答して頂き、ありがとうございました。
123ポイント を手に入れた。
|
|
|
|
Name: M ..ぴよぴよ(50ポイント)
Date: 2009/02/27(金) 22:04
No:29525
|
|
Title: 初歩的な質問ですいません…
|
|
初めまして、このサイトでC言語を勉強させて貰っている者です
今エクセルを使って敵を出現させようとしているんですけど‘EXFILE’が「未定義の関数」とかになってコンパイルエラーになってしまうんですけどどうしてでしょうか?
使っているコンパイラは
BorlandC/C++用の物です
誰か教えて下さい、お願いします
50ポイント を手に入れた。
|
|
|
|
Name: SCI ..中級者(11,130ポイント)
Date: 2009/02/27(金) 22:06
No:29527
|
|
Title: Re:初歩的な質問ですいません…
|
|
EXFILE()って書いたらいけませんよ、としか言えませんが、ジャンプの部分をどのように書いていますか?
43ポイント を手に入れた。
|
|
|
|
|
Name: M ..ぴよぴよ(41ポイント)
Date: 2009/02/27(金) 22:08
No:29528
|
|
Title: Re:初歩的な質問ですいません…
|
|
とりあえず、こちらのサイトに載ってるのをほとんどそのまま書きました
9ポイント を落としてしまった。
|
|
|
|
|
Name: SCI ..中級者(11,185ポイント)
Date: 2009/02/27(金) 22:13
No:29529
|
|
Title: Re:初歩的な質問ですいません…
|
|
ということは、 /* ... */
goto EXFILE;
/* ... */
EXFILE: といった感じで書いてますよね?
私もBCCですけど、上のように書いていればエラーは出ないはずなんですが・・・
他にエラーは出ていませんか?
55ポイント を手に入れた。
|
|
|
|
|
Name: M ..ぴよぴよ(47ポイント)
Date: 2009/02/27(金) 22:17
No:29530
|
|
Title: Re:初歩的な質問ですいません…
|
|
EXFILEが「未定義の関数」と「未定義のラベル」で二つエラーになってます
6ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(12,277ポイント)
Date: 2009/02/27(金) 22:59
No:29535
|
|
Title: Re:初歩的な質問ですいません…
|
|
Mさん
御津凪さんのケースか、若しくは goto EXFILE;
/* ... */
EXFILE(); のように書いていませんか?
46ポイント を手に入れた。
|
|
|
|
|
Name: M ..ぴよぴよ(382ポイント)
Date: 2009/02/27(金) 23:48
No:29540
| 解決!
|
Title: Re:初歩的な質問ですいません…
|
|
ありがとうございます、ちゃんと動きました。
ありがとうございました!
27ポイント を手に入れた。
|
|
|
|
Name: s-rush ..プログラマー(31,403ポイント)
Date: 2009/02/27(金) 18:13
No:29506
|
|
Title: 急に音楽が再生されません
|
|
連続投稿になってしまいすいません。
音楽をメモリに読み込んでから、音楽を再生するという方法をとっているのですが、
マップデータを大きくしたとたんに、音楽が再生されなくなりました。
マップデータは(要領悪いですが)エクセルからデータを読み取って、配列に格納するという方法をとっています。
添付したファイルには以下の物を入れてあります。
main.cpp -メイン
load_kanto.cpp -ロード
load_map_info.cpp -エクセルからマップデータのロード
sound.cpp -音楽再生
GH.h
エクセルでのマップデータ
ちなみにマップデータは
1:あたり判定用
2:フィールドマップ描画用
3:建物描画用
4:その他オブジェクト描画用
5:エリア判定用
です。
音楽再生に使っているマップデータは5のエリア判定用です。
マップデータを変更する前はちゃんと音楽が再生されていたのですが、
添付しておいたデータに変えたとたん、音楽が再生されません。
そこで、ちょっと調べてみたのですが、どうやらメモリに音楽データがロードされていないようなんです。
ですが、マップデータ変更前はメモリに入っていました。
プログラム自体は何も触っていません。
mainの方で、
case 0:
load();
load_kanto();
ch.x=512;
ch.y=480;
ch.walking_flag=0;
ch.muki=3;
music[0] = LoadSoundMem("../data/sound/kanto_music/masara_town.mp3");
music[1] = LoadSoundMem("../data/sound/kanto_music/1_road.mp3");
func_state=100;
break;
と変更したところ、メモリにロードされていました。
なので、パスが間違っていることはなさそうです。
なにが問題なのか分からないので、皆さんの知恵を貸してください。
開発環境はVC++2008 EE OS:Vistaです。
472ポイント を手に入れた。
|
|
|
|
Name: s-rush ..プログラマー(31,531ポイント)
Date: 2009/02/27(金) 18:33
No:29509
|
|
Title: Re:急に音楽が再生されません
|
|
>>yuさん
早速の回答ありがとうございます。
私もそう思って、配列の要素数を少し大きめに変更したんですが、
それでも駄目でした。
musicには何も入っていなくて、戦闘用の音楽battle_musicには入っていたので、
原因が全く分からない状態です・・・
87ポイント を手に入れた。
|
|
|
|
|
Name: yu [URL] ..上級者(18,286ポイント)
Date: 2009/02/27(金) 18:50
No:29510
|
|
Title: Re:急に音楽が再生されません
|
|
すみません;予想が外れて・・・
それで、ソース見てみました。
void stop_sound()
{
int i;
for(i=0; i<30; i++)
{
StopSoundMem(music[i]);
}
}
ですが
i<10 じゃないですか?
直しても解決しないかもしれませんが・・・;
134ポイント を手に入れた。
|
|
|
|
|
Name: Mist ..熟練のプログラマー(52,882ポイント)
Date: 2009/02/27(金) 18:52
No:29511
|
|
Title: Re:急に音楽が再生されません
|
|
load_kanto関数内でLoadSoundMemを実行した直後のmusicの値はなんですか?
-1が入っているのであれば、DXライブラリのログ(Log.txt)に何か出力されているかも。
あと、最初の添付いくつかヘッダファイル足りないですね。(私がDLLミスっているだけ?)
2倍のポイントを手に入れた! 160ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(31,588ポイント)
Date: 2009/02/27(金) 18:53
No:29512
|
|
Title: Re:急に音楽が再生されません
|
|
それでも駄目でした・・・
ロードの際、メモリ自体にデータが入っていないみたいなんです。
main関数内で読み込むようにすれば、メモリに入ってはいたんですが、
それだと、拡張性がなくなってしまうので^^;
57ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(31,598ポイント)
Date: 2009/02/27(金) 19:14
No:29513
|
|
Title: Re:急に音楽が再生されません
|
|
>>Mistさん
load_kanto関数内でLoadSoundMemを実行した直後のmusicの値も0でした。
>最初の添付いくつかヘッダファイル足りないですね
確認してみたんですけど、ちゃんとありましたけど^^;
何が足らなかったんでしょうか?
10ポイント を手に入れた。
|
|
|
|
|
Name: Mist ..熟練のプログラマー(53,065ポイント)
Date: 2009/02/27(金) 19:23
No:29514
|
|
Title: Re:急に音楽が再生されません
|
|
私がDLLしたものではGV.hしかありませんでした。
fanction.h //関数定義
struct.h //構造体定
define.h //マクロ定義
の3つが少なくとも足りないようです。
あと、GV.hにはexternしかないけど変数の実体はどこで定義しているのでしょうか?
もしかしてソースも足りないのがあるのかな?
DLLされたファイルのサイズは正しかったんですけど。
> load_kanto関数内でLoadSoundMemを実行した直後のmusicの値も0でした。
0も1も0ですか?変ですね。
例えば、load_kanto関数内で音楽のロードとマップデータのロードの順番を入れ替えるとどうなりますか?
183ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(10,773ポイント)
Date: 2009/02/27(金) 19:29
No:29515
|
|
Title: Re:急に音楽が再生されません
|
|
>Mistさん
このプログラムは何か特別なDLLを使っているのですか?
23ポイント を手に入れた。
|
|
|
|
|
Name: Mist ..熟練のプログラマー(53,182ポイント)
Date: 2009/02/27(金) 19:43
No:29516
|
|
Title: Re:急に音楽が再生されません
|
|
ああ、すいません。
DLL=ダウンロードのことです。
私の仕事場だとそう呼ぶので無意識にそう書き込んでいました。
最後のLがなんなのかよくわかんないですけどね。
アップロードの場合はUPLと略すのでそれに合わせて3文字にしてるのかなぁ?
117ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(10,841ポイント)
Date: 2009/02/27(金) 19:47
No:29517
|
|
Title: Re:急に音楽が再生されません
|
|
命名規則にも依りますが、アップロードはULでもUPLでもUPでも一応「略語」ですね。
ダウンロード「DownLoad」はどのように略してもLが2つにはならないので、一応確認してみました。
DLLというと「Dynamic Link(ed) Library」をイメージしてしまうので・・・
それはともかく、プロジェクトが断片的で、まずコンパイル・確認ができないのでさっぱりです。。
68ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(31,877ポイント)
Date: 2009/02/27(金) 20:56
No:29519
|
|
Title: Re:急に音楽が再生されません
|
|
もう一度アップしてみます。
といっても、中身はMistさんが足りないとおっしゃっていた
fanction.h //関数定義
struct.h //構造体定
define.h //マクロ定義
です。
あと変数の実態はdeclaration.cppで定義してあります。
これは入れるの忘れていたんで、私のミスです^^;
musicの値はどうやっても0なんです・・・
エクセルのデータを変える前まではきちんと入っていたんで、
どこに原因があるのかさっぱりわからないです。
>例えば、load_kanto関数内で音楽のロードとマップデータのロードの順番を入れ替えるとどうなりますか?
順番を入れ替えても駄目でした。
ついでにmainでload_kantoを呼び出す順番を変えても変化はありませんでした。
>>SCIさん
コンパイルは通っています。
プロジェクトごとアップした方がいいでしょうか?
279ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(10,915ポイント)
Date: 2009/02/27(金) 21:06
No:29520
|
|
Title: Re:急に音楽が再生されません
|
|
s-rushさん
こっちでまず実行ファイルが作れないと、「実行して症状を確認する」という最低限の作業ができません。
「音楽が再生できない」のなら、使用している音楽ファイルが必要です。
それか、必要な部分がテスト可能な最小限のプログラムを別に作るという方法もあります。
どちらにしろ、「症状を再現」するためのコードが小出しの状態だと、周囲の人はデバッグできませんよ。
74ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(10,945ポイント)
Date: 2009/02/27(金) 21:57
No:29522
|
|
Title: Re:急に音楽が再生されません
|
|
実行確認ができましたので、変更後のマップデータを使ってテストしてみます。
30ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(323,530ポイント)
Date: 2009/02/27(金) 21:58
No:29523
|
|
Title: Re:急に音楽が再生されません
|
|
load_map_info関数の field_mapXへのアクセスで、jや kの値が
MAP_SIZE_X や MAP_SIZE_Yを超えてますよ。
これで直接関係のなかった musicなどの別のメモリを壊していますね。
34ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(11,044ポイント)
Date: 2009/02/27(金) 22:03
No:29524
|
|
Title: Re:急に音楽が再生されません
|
|
・・・と思ったら、タイムスタンプを見る限りこれは「変更後」のデータですか?
上手く動いているようですよ。
画面中ほどに表示されている音楽のハンドルは、3つとも0ではなかったのですが・・・
BCC 5.5.1
WindowsXP
Core2Duo 1.98GB
2GB RAM
99ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(11,087ポイント)
Date: 2009/02/27(金) 22:05
No:29526
|
|
Title: Re:急に音楽が再生されません
|
|
追記
Justyさんの言うとおり、ループカウンタの値とか、ツメが甘い部分があるようです。
たまたま、私の環境では上手くいっただけです。
43ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(32,277ポイント)
Date: 2009/02/27(金) 22:29
No:29532
|
|
Title: Re:急に音楽が再生されません
|
|
Justyさん、SCIさんありがとうございました。
おかげで解決することができました。
おっしゃるようにループカウンタの爪が甘かったです。
以下のように改良したら、ちゃんとメモリ内にロードされていました。
if(j>=MAP_SIZE_Y || i>=MAP_SIZE_X) //もしマップサイズよりも大きければEXFILEへ
goto EXFILE;
switch (map_kind){
case 1: field_map1[j][k] = atoi(inputc); k++; break;
case 2: field_map2[j][k] = atoi(inputc); k++; break;
case 3: field_map3[j][k] = atoi(inputc); k++; break;
case 4: field_map4[j][k] = atoi(inputc); k++; break;
case 5: field_map5[j][k] = atoi(inputc); k++; break;
}
念のために聞いておきたいのですが、こんな感じでよろしいでしょうか?
メモリ破壊のバグ?にはなかなか気付かずに作業を進めてしまいそうなので^^;
353ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(323,850ポイント)
Date: 2009/02/27(金) 22:51
No:29533
|
|
Title: Re:急に音楽が再生されません
|
|
>念のために聞いておきたいのですが、こんな感じでよろしいでしょうか?
kはチェックしなくていいのですか?
あと、MAP_SIZE_X以上だった場合、EXFILEへ飛ばすのではなく、
強制改行という扱いでもいいのかもしれません。
ちなみに csv内に '/'があった場合以降をコメントとして処理しているようですが、
ケースによってはバグります。
0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 // コメント
とすると、次の行の処理で、field_mapXのおかしなところに書き込みにいってしまうようです。
320ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(12,231ポイント)
Date: 2009/02/27(金) 22:56
No:29534
|
|
Title: Re:急に音楽が再生されません
|
|
あと、念のために書いておきますが、BCCでコンパイルすると以下のような警告が出ます。
Warning: パブリックシンボル _now がモジュール OTHER_FANCTION.OBJ と GET_TIME.OBJ の両方に定義されている
Warning: パブリックシンボル _data がモジュール OTHER_FANCTION.OBJ と GET_TIME.OBJ の両方に定義されている
Warning: パブリックシンボル _hour がモジュール OTHER_FANCTION.OBJ と GET_TIME.OBJ の両方に定義されている
Warning: パブリックシンボル _minute がモジュール OTHER_FANCTION.OBJ と GET_TIME.OBJ の両方に定義されている
Warning: パブリックシンボル _second がモジュール OTHER_FANCTION.OBJ と GET_TIME.OBJ の両方に定義されている
Warning: パブリックシンボル _wday がモジュール OTHER_FANCTION.OBJ と GET_TIME.OBJ の両方に定義されている
Warning: パブリックシンボル _time_zone がモジュール OTHER_FANCTION.OBJ と GET_TIME.OBJ の両方に定義されている
VCでも似たようなのが出ていますか?
精読していないので誤認識かも知れませんが、定義位置とかも気をつけるに越したことはないですね。
グローバル変数が増えてくると、衝突とかどうしても気づきにくいので・・・
1,046ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(32,546ポイント)
Date: 2009/02/27(金) 23:10
No:29536
|
|
Title: Re:急に音楽が再生されません
|
|
>Justyさん
>>kはチェックしなくていいのですか?
イベント用のマップを入れてから、この処理を考えます。
>>MAP_SIZE_X以上だった場合、EXFILEへ飛ばすのではなく、強制改行という扱いでもいいのかもしれません。
そうですね^^
強制改行にするか、エラー処理として扱うか、少し考えてみます。
>csv内に '/'があった場合以降をコメントとして処理しているようですが、ケースによってはバグります。
コメントは入れないつもりなので、この部分を削除しておきます。
まだまだつめが甘かったようですね^^;
>SCIさん
BCCは使ったことがないので、警告の意味が分かんないです。
VCでも警告は出ていますが、SCIさんのおっしゃるような類とは異なるかと思います。
floatとint間での代入等で、データが失われる可能性があります
という警告がほとんどでした。
(計算の都合上、これは意図的にしています)
グローバル変数ばかりを扱っているので、定義位置にも気をつけます。
269ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(323,956ポイント)
Date: 2009/02/27(金) 23:20
No:29538
|
|
Title: Re:急に音楽が再生されません
|
|
>VCでも似たようなのが出ていますか?
試してみました。
どうやら、other_fanction.cppは pokemon1.vcprojに登録されていないので
ビルド対象になっていないようで、特にそういう警告は出ませんでした。
# ちなみに関数の英語は functionです。
106ポイント を手に入れた。
|
|
|
|
Name: yasu ..かけだし(1,498ポイント)
Date: 2009/02/26(木) 19:23
No:29474
|
|
Title: Linux 対話型コマンド自動化(SCP)
|
|
yasuです。
scpの自動化コマンドをC言語にて作成したいのですが、
うまくいきません。
自動化に成功した方がいらっしゃれば、組み方を教えてください。
【現状】
1)擬似端末を使用しcp -i rm -i等のコマンドは自動化○
2)同一のコマンドにてscpを実行すると自動化×
※記事端末を作成後、子プロセスにてscpを実行しているがなぜかscpの入出力が
コマンドをたたいた端末につながっている。
【ソース】
#define ANS_PASSWD "XXX"
#define ANS_YES "yes\n"
#define Q_RM "rm: remove"
#define Q_SCP "XXX@XXX's password:"
int main () {
char *slaveTermName = NULL;
char buf[BUFSIZ + 1];
char envSet[BUFSIZ];
int masterDp, slaveDp,pid,n;
// if(!fork()){
masterDp = open( "/dev/ptmx" ,O_RDWR );
grantpt(masterDp);
unlockpt(masterDp);
slaveTermName = (char *)ptsname(masterDp);
sprintf(envSet,"SSH_TTY=%s",slaveTermName);
setsid();
putenv(envSet);
pid = fork();
if (!pid) {
slaveDp = open(slaveTermName, O_RDWR, 0);
ioctl(slaveDp, I_PUSH, "ptem");
ioctl(slaveDp, I_PUSH, "ldterm");
close(masterDp);
dup2(slaveDp, 0); dup2(slaveDp, 1); dup2(slaveDp, 2);
system("scp -p AAA XXX@XXX:BBB");
//system("rm -i AAA");
close(slaveDp);
exit(0);
}
n = read(masterDp,buf,sizeof(buf) -1 );
//if (strncmp(buf, Q_RM,strlen(Q_RM)) == 0){
//if (strncmp(buf, Q_SCP,strlen(Q_SCP)) == 0){
fprintf(stdout,"ANSWER = %s \n",ANS_PASSWD);
//write(masterDp,ANS_YES,sizeof(ANS_YES));
write(masterDp, ANS_PASSWD, sizeof(ANS_PASSWD));
//}
wait(0);
exit(0);
//}
exit(0);
}/* end main */
1,044ポイント を手に入れた。
|
|
|
Name: TKOZ ..上級者(19,064ポイント)
Date: 2009/02/26(木) 00:07
No:29410
|
|
Title: キー入力が上手くいきません
|
|
DXライブラリを使って、
UFOキャッチャーゲームを作っているのですが、上手くいきません。
どういう風にうまく行かないのかというと、
”キャッチャーをZキーで右へ移動の後にXキーで下に下ろす。”
これが出来ません。
Z、Xキーそれぞれのキーを押したのを判定するのは出来るのですが、
状態遷移が上手くいきません。
ソースコードを一部添付するので、見てもらえますか?
48ポイント を手に入れた。
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(65,944ポイント)
Date: 2009/02/26(木) 01:52
No:29422
|
|
Title: Re:キー入力が上手くいきません
|
|
まず仕様がわからないのでアドバイスができません。
まずいところをとりあえずあげておきます。
counter,counter2ともに入力がなければずっとデクリメントしていますが、
放置時間が続くとオーバーフローします。
またここも仕様がわからないので何とも言えませんが、
結構な間放置したあと(counter,counter2は負に大きな数)
zキーが数百ループ(数秒間)押されたとします。(2ずつインクリメント×数百)
counterは負に大きな数ですので、絶対にif文の条件をみたし、flag=0となります。
しかし、、ゲーム開始早々zキーを押したままだとずっと2ずつインクリメントしてます。
ゆえにzキーを離してもif文に合致せず、フラグが立ちません。
xキーも同様です。
フラグの使い分けは自分の意図したようになっていますか?
一度counter,counter2の変数の移り変わりを画面に表示してみると分かりやすいと思いますよ。
221ポイント を手に入れた。
|
|
|
|
|
Name: TKOZ ..上級者(19,098ポイント)
Date: 2009/02/26(木) 17:14
No:29462
|
|
Title: Re:キー入力が上手くいきません
|
|
キーの離された瞬間を処理したら、うまくいきました。
ありがとうございました。
今日、一日授業中に作っていたのですが、
なんとか形にはなりました。
ただ、UFOキャッチャーとオブジェクトの当たり判定が
うまくいきません。
34ポイント を手に入れた。
|
|
|
|
|
Name: TKOZ ..上級者(19,386ポイント)
Date: 2009/02/26(木) 17:43
No:29467
|
|
Title: Re:当たり判定がうまくいきません。
|
|
>うまくいきませんとおっしゃられても、添付されているファイル
>の中にはそれらしき画像ファイルはありませんし、その処理も見当たりません。
>もう一度ソースファイルをUPされては?
>(自分はテスト勉強しなければいけないので^^;)
すみません。
こっちの都合ばかり考えてましたが、いけませんでしたね。
ソースファイルをUPします。
2倍のポイントを手に入れた! 288ポイント を手に入れた。
|
|
|
|
|
Name: toyo ..プログラマー(26,434ポイント)
Date: 2009/02/26(木) 18:37
No:29468
|
|
Title: Re:当たり判定がうまくいきません。
|
|
x,yの範囲はcatcher.pngから適当に判断しました
void HitCheck(int x,int y)
{
int i;
for(i=0;i<MAX;i++)
{
if(Ball[i].x > x+8 && Ball[i].x+Ball[i].width < x+116 &&
Ball[i].y > y+370 && Ball[i].y+Ball[i].height < y+470 )
{
Ball[i].putonflag=1;
}
}
}
102ポイント を落としてしまった。
|
|
|
|
|
Name: TKOZ ..上級者(19,395ポイント)
Date: 2009/02/26(木) 19:32
No:29476
|
|
Title: Re:当たり判定がうまくいきません。
|
|
toyoさんへ
ありがとうございます。
おかげで、少しシビアなゲームになりそうです。
あとは、コインの数が0になったとき、下にスクロールして、
落ちたものを確認する状態で、きちんと確認できれば最高です。
9ポイント を手に入れた。
|
|
|
|
|
Name: toyo ..プログラマー(26,467ポイント)
Date: 2009/02/26(木) 20:08
No:29479
|
|
Title: Re:当たり判定がうまくいきません。
|
|
私のソースではボール全体が枠内にないと掴めません
大きいボールは掴めませんがそれでよかったのでしょうか
33ポイント を手に入れた。
|
|
|
|
|
Name: TKOZ ..上級者(19,429ポイント)
Date: 2009/02/26(木) 20:18
No:29480
|
|
Title: Re:当たり判定がうまくいきません。
|
|
toyoさんへ
大きいボールは、もう少し小さくします。
そして、キャッチャーで拾えるようにします。
心配をおかけして、すみません。
34ポイント を手に入れた。
|
|
|
|
|
Name: TKOZ ..上級者(19,474ポイント)
Date: 2009/02/27(金) 18:07
No:29505
| 解決!
|
Title: Re:当たり判定がうまくいきません。
|
|
自分でやってみた結果、
全ての処理が上手くいきましたので、完成です。
まあ、あと、少し手を加えますが…。
45ポイント を手に入れた。
|
|
|
|
Name: 初心者 ..プログラマー(28,996ポイント)
Date: 2009/02/27(金) 16:34
No:29500
|
|
Title: DXライブラリのサンプルプログラムで
|
|
DXライブラリ置き場 サンプルプログラムにある
8.関数ポインタ基本
http://homepage2.nifty.com/natupaji/DxLib/dxprogram.html#N8
についてなんですが、まだ初心者で1から順番に理解しながら実行していて
このサンプルを実行したらフルスクリーンで黒い画面のまんまになってしまい
何をやってもだめだったので強制終了(ちょっと違うけど)しました。
あれ?と思い今度はウィンドウで、起動してみたところ起動はするんですが、途中で
「Run-Time Check Failure #3 - The variable 'OldKey' is being used without being initialized.」
と出てきて接続をクリックするとその続きを普通に起動するんですが、どうゆうことなんでしょうか?
接続をクリックせずに中断をクリックすると
if( ( Key & ~OldKey ) & PAD_INPUT_A )
の部分で左に黄色い矢印が付いてるんですがまたF5を押すと続きから起動します。
まだ初心者なもんですいません。
324ポイント を手に入れた。
|
|
|
|
Name: SCI ..中級者(10,750ポイント)
Date: 2009/02/27(金) 16:39
No:29501
|
|
Title: Re:DXライブラリのサンプルプログラムで
|
|
そのエラーメッセージのままの意味で、変数OldKeyが初期化されていません。
宣言するところで、int OldKey = 0; としてみてください。
42ポイント を手に入れた。
|
|
|
|
|
Name: 初心者 ..プログラマー(29,045ポイント)
Date: 2009/02/27(金) 16:45
No:29502
| 解決!
|
Title: Re:DXライブラリのサンプルプログラムで
|
|
そういうことだったんですか。
サンプルでミス?があるとは思いませんでした。
何かこちらに問題があるのかとww
SCIさんありがとうございます。
49ポイント を手に入れた。
|
|
|
|
Name: s-rush ..プログラマー(28,783ポイント)
Date: 2009/02/21(土) 19:21
No:29118
|
|
Title: マップの切り替え処理
|
|
いつもお世話になっています。
今RPGのゲームを作っているのですが、マップの切り替え処理に
つまずいているので質問させていただきに来ました。
RPGのゲーム(とは限らないとは思いますが)ではマップ⇔ダンジョンのマップ切り替えがよくあると思います。
フィールドマップを表す配列とは別に
int dungeon_map[3][5][5]={
{0,0,0,0,0
0,2,1,1,0
0,1,1,1,0
0,1,1,1,0
0,4,0,0,0},
{0,0,0,0,0
0,3,1,1,0
0,1,1,1,0
0,1,1,2,0
0,0,0,0,0},
{0,0,0,0,0
0,1,1,1,0
0,1,1,1,0
0,1,1,3,0
0,0,0,0,0},
}
0:通行不可 1:通行可 2:上の階へ 3:下の階へ 4:フィールドマップへ
というマップデータとして、マップの切り替えが起こった時の処理に悩んでいます。
マップが切り替わったとき、自キャラの座標をどこかに格納しておけば、
マップが切り替わった後(特にマップ⇔ダンジョン)の描画する自キャラの位置を特定できると思うのですが、
今困っているのは、自キャラを操作するプログラムなんです。
現段階での自キャラのあたり判定のプログラムはこうです。
int can_or_cannot(int x,int y,int muki){//進めるかを判定する
if(muki==0){//上向きなら
if(field_map1[y/32-1][x/32]==0 || (field_map1[y/32-1][x/32]==2 && ch.st!=3)){//進めるか判定
return 1;//エラー
}
}
if(muki==1){//左向きなら
if(field_map1[y/32][x/32-1]==0 || (field_map1[y/32][x/32-1]==2 && ch.st!=3)){
return 1;
}
}
if(muki==2){//下向きなら
if(field_map1[y/32+1][x/32]==0 || (field_map1[y/32+1][x/32]==2 && ch.st!=3)){
return 1;
}
}
if(muki==3){//右向きなら
if(field_map1[y/32][x/32+1]==0 || (field_map1[y/32][x/32+1]==2 && ch.st!=3)){
return 1;
}
}
return 0;//正常
}
見ての通り、フィールドマップの時にしか対応できないプログラムなんです。
これをダンジョンのような別のマップ上でも対応できるにはどのようにしたらいいでしょうか?
switch文で、場合分けするのもコードが無駄に長くなりそうですし・・・
なにか良い案はないでしょうか?
開発環境はVC++2008 EEです。
931ポイント を手に入れた。
|
|
|
|
Name: dic ..中級者(13,250ポイント)
Date: 2009/02/21(土) 19:53
No:29121
|
|
Title: Re:マップの切り替え処理
|
|
フィールドマップとダンジョンマップの違いが分からないので
なんとも言えないですが
7ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(28,837ポイント)
Date: 2009/02/21(土) 23:19
No:29129
|
|
Title: Re:マップの切り替え処理
|
|
フィールドマップとダンジョンマップの大きさは違うので、引数にマップデータを渡せなさそうです。
まだ全体のマップデータはできていませんが、
・フィールドマップは1000×1000
・ダンジョンマップは500×500
・建物の中50×50
くらいになると思います。
54ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(319,881ポイント)
Date: 2009/02/22(日) 00:00
No:29134
|
|
Title: Re:マップの切り替え処理
|
|
>引数にマップデータを渡せなさそうです
少し考え方を変えて、2次元配列ではなく普通に一次元配列で扱えばできますよ。
ただ、マップデータへのアクセスは二次元配列の時はコンパイラが自動で
計算してくれましたが、一次元配列の場合は自分で計算しないと
いけなくなりますので、マップの縦横のサイズも一緒に渡してあげるといいでしょう。
下の方に適当なサンプルを乗っけておきます。
ところで、フィールドマップが 1000x1000ということですが、
これのデータはソースコード上に記述する予定なのでしょうか?
参考例)
// マップデータ
static const int dungeon_map1[]=
{
0,0,0,
0,2,1,
0,1,1,
0,1,1,
0,4,0,
};
static const int dungeon_map2[]=
{
0,0,0,0,0,
0,2,1,1,0,
};
static const int dungeon_map3[]=
{
0,0,0,0,0,
0,1,1,1,0,
0,1,1,1,0,
0,1,1,3,0,
0,0,0,0,0,
};
// マップ構造体
struct Map
{
int x_size;
int y_size;
const int *data;
};
// 複数のサイズの異なるマップを1つにまとめる
static const Map maps[] =
{
{ 3, 5, dungeon_map1 },
{ 5, 2, dungeon_map2 },
{ 5, 5, dungeon_map3 },
};
// 位置からマップデータへのオフセットを取得
static int get_map_offset_position(const Map *map, int x, int y)
{
if(!map || x < 0 || y < 0 || x >= map->x_size || y >= map->y_size)
return -1;
return y * map->x_size + x;
}
// マップの位置からマップデータを取得
static int get_map_data(const Map *map, int x, int y)
{
int offset = get_map_offset_position(map, x, y);
if(offset < 0) return -1;
return map->data[offset];
}
int can_or_cannot(const Map *map, int x, int y,int muki)
{
int xx = x / 32, yy = y / 32;
int data;
switch(muki)
{
case 0:
y -= 1;
break;
case 1:
x -= 1;
break;
case 2:
y += 1;
break;
case 3:
x += 1;
break;
}
data = get_map_data(map, xx, yy);
if(data < 0) return -1;
if(data==0 || (data==2 && ch.st!=3))
return 1;
return 0;
}
1,796ポイント を手に入れた。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(62,277ポイント)
Date: 2009/02/22(日) 00:21
No:29138
|
|
Title: Re:マップの切り替え処理
|
|
dicさんのおっしゃるように、
フィールドマップとダンジョンマップの違いが
よくわからないのではっきりしたことが言えません。
両者に格納されているデータに相互性はないっぽいですよね^^;
階段はフィールドにはありませんもんね^^;
両者ともに0は通行不可であり、それ以外は可とかならば
簡単にできると思いますが。
一つ疑問なのですが、
次に進むと上の階に行く(field_map1[y/32-1][x/32]==2)だったら進めない
っというのは必須ですか?
例えばですが・・・
まず、static int floor_checkというを変数を用意します。
これは現在のダンジョンを出る(上の階や下の階へ)たびにfloor_checkに0を代入します。
また、そのフロアで一歩踏み出したら1になるようにします。
そして、can_or_cannot()を呼び出す前に
if(field_map1[y/32-1][x/32]==2 && floor_check==1)
に合致したら、
・ダンジョンデータの入れ替え
・floor_check=0(もしフラグが立ったままだと一階まで一気に下っ(上っ)ていってしまいます。)
をすればダンジョンの移動は実現できそうです。
分かりにくくてすいません。
結局いいたいことはフィールドデータ、ダンジョンデータ
両者共通の歩行にしたいならば、条件をゆるくしないと厳しいです。
なので、階段の処理を除けば少しは実現に近づくかなと思いました。
(field_map1[y/32][x/32+1]==2
ch.st!=3(これは何か分からないので・・・ノータッチ)
をなくすとうまくいきそうだ!っとぐだぐだ↑で説明してました^^;
わかりづらい・・・
370ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(29,160ポイント)
Date: 2009/02/22(日) 22:13
No:29161
|
|
Title: Re:マップの切り替え処理
|
|
一応ダンジョンマップと銘打ってはいますが、
ダンジョンだけではなく、建物の中とか・・・
とりあえずフィールドマップ以外のマップへの切り替え、
その移動先のマップ上での移動処理をどうするのかに悩んでいます。
フィールドマップとの違いは、全体の大きさが違う(小さくなる)こと以外に、
階段の処理?だけで、ほかの処理系には何も変わることはないです。
(0は通行不可、1は通行可のような条件)
建物の中では階段やワープみたいなもので、さらにマップの切り替えが生じるくらいです。
で、field_map1[y/32-1][x/32]==0というような条件の書き方にしてしまうと、
移動先での条件に当てはまらないので、悩んでいました^^;
と、もっと詳しく移動先のマップの処理等を書くべきでした。
>>(field_map1[y/32][x/32+1]==2
>>ch.st!=3(これは何か分からないので・・・ノータッチ)
これはスルーしてもらって構いません^^;
海辺での移動条件なので・・・
>Justyさん
サンプルコードありがとうございます。
今必死に解析している途中です。
323ポイント を手に入れた。
|
|
|
|
|
Name: POK ..ぴよぴよ(4ポイント)
Date: 2009/02/25(水) 14:46
No:29333
|
|
Title: Re:マップの切り替え処理
|
|
マップの切りかえってそんなに難しいもんですかね?
4ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(30,063ポイント)
Date: 2009/02/25(水) 23:39
No:29404
|
|
Title: Re:マップの切り替え処理
|
|
>>トピ主がゲーム製作に慣れていないだけでは?
おっしゃる通りゲーム作りは初めてなので慣れていないです^^;
マップの切り替え自体はできそうなんですが、
マップ切り替え後の、キャラの移動処理に・・・
一応アイデアはあるのですが、メモリの無駄遣いになりそうなので^^;
一つ疑問なんですが、大規模なゲーム(市販のゲームみたいなもの)では
どれくらいのメモリを使用されているのでしょうか?
28ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(322,578ポイント)
Date: 2009/02/26(木) 00:48
No:29413
|
|
Title: Re:マップの切り替え処理
|
|
>一つ疑問なんですが、大規模なゲーム(市販のゲームみたいなもの)では
>どれくらいのメモリを使用されているのでしょうか?
具体的にどれくらいというのはハードやソフトによってまちまちなので
一概にはいえません。
PCのゲームなら動作推奨環境のメモリの項目が多少は参考になるかと思います。
(もちろん、その数字分使っている、というわけではないですよ)
コンシューマ系のゲームの場合、(モノにもよりますが)ある程度のクオリティがある
ゲームなら使用可能メモリに対して6〜8割以上は使われているでしょう。
(というか、ぎりぎりで動いていることも多いです)
ちなみに使用しているメモリの多くは3Dモデル・テクスチャ、コリジョンデータで
占められていることが多いようです。
>一応アイデアはあるのですが、メモリの無駄遣いになりそうなので
それは何十、何百MB以上消費するアイデアなのでしょうか?
もしそうでなければ、とりあえずやってみてはどうでしょうか?
反対に大量に消費するようであれば、何かが間違っていると考えられるので、
その時は改めて情報を整理した上で質問するのがいいかと思います。
413ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(30,428ポイント)
Date: 2009/02/26(木) 01:16
No:29416
|
|
Title: Re:マップの切り替え処理
|
|
>>それは何十、何百MB以上消費するアイデアなのでしょうか?
たぶんそこまでは無駄な消費ではないかと・・・
フィールドマップやダンジョン、建物内のマップとは別に
実際に描画するための配列を作ってあげて、
マップの切り替えが生じたとき、その描画するための配列に
マップデータを入れ込んであげればいいのでは?
と勝手に思い込んだので^^;
なので、最大のマップの大きさに合わせてしまうので、
建物内のようなそんなに大きくはないものにとっては無駄が多くなってしまうのでは
と思ったんです。
こういうゲームでのメモリの使用量も分からなかったので、
できるだけメモリの消費量を抑えれたらと考えていましたので、
マップの切り替え処理のアイデアを教えていただきに来ました。
メモリの消費量が少ないにこしたことはないと思いますが・・・
ちなみに、配列データを入れ込む(コピー)にはmemcpyを使うんでしょうか?
365ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(322,982ポイント)
Date: 2009/02/26(木) 01:41
No:29419
|
|
Title: Re:マップの切り替え処理
|
|
>マップの切り替えが生じたとき、その描画するための配列
>建物内のようなそんなに大きくはないものにとっては無駄が多くなってしまうのでは
>と思ったんです
あー、なるほど。
関数にマップの情報を引き渡さずに処理するなら、その方が楽ですね。
無駄といえば無駄ですが、数あるマップのうち最大のマップ分のサイズが
1個増えたくらい(1000x1000*sizeof(int) = 3.8MBくらい?)なら
たいしたことはないでしょう。
(どっちかというと、全てのマップがメモリに常駐している方がよほど……)
どうしても気になるなら、can_or_cannot関数などで参照するマップデータは
配列ではなく、適切なサイズ分 mallocしたポインタにしてコピーすればいいかと。
>配列データを入れ込む(コピー)にはmemcpyを使うんでしょうか
ただの intの配列なら、それで構いません
404ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(30,554ポイント)
Date: 2009/02/26(木) 12:19
No:29441
|
|
Title: Re:マップの切り替え処理
|
|
>適切なサイズ分 mallocしたポインタにしてコピーすればいいかと
ちょうどmallocは大学にて勉強中なので、
ちゃんと理解するためにもこの方法で頑張ってみたいと思います。
>ただの intの配列なら、それで構いません
intというよりもshortとcharの2つの(2次元)配列を使用しているのですが、
char型の配列は大丈夫なんでしょうか?
126ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(323,045ポイント)
Date: 2009/02/26(木) 22:45
No:29483
|
|
Title: Re:マップの切り替え処理
|
|
>intというよりもshortとcharの2つの(2次元)配列を使用しているのですが、
>char型の配列は大丈夫なんでしょうか?
コピー時のサイズを間違えなければ、大丈夫です。
63ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(30,740ポイント)
Date: 2009/02/26(木) 23:32
No:29485
| 解決!
|
Title: Re:マップの切り替え処理
|
|
Justyさん、kazuoniさん、dicさん、
ご回答ありがとうございました。
無駄の多いプログラムですが、何とか完成することができました。
不慣れなことをやっているので、またお聞きするかもしれませんが、
その時はまたよろしくお願いします。
いろいろと調べて見て思ったのですが、RPGのプログラミングを紹介しているサイトって
あまり見かけないですよね?
シューティングゲームならよく見かけるのですが・・・
186ポイント を手に入れた。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(66,168ポイント)
Date: 2009/02/27(金) 00:37
No:29486
|
|
Title: Re:マップの切り替え処理
|
|
自分の作品が出来上がったら、arrayさんのように、
支館RPG版を作ろうかと思っていたのですが、
最近はC++でプログラミングをしようと計画中なんで
ちょっと支えられそうにない気が・・・。。
C++でよいなら考えますが。。
・・・まずC++を自由に扱えるようになってからの話ですけど^^;
145ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(323,496ポイント)
Date: 2009/02/27(金) 01:05
No:29488
|
|
Title: Re:マップの切り替え処理
|
|
>いろいろと調べて見て思ったのですが、RPGのプログラミングを紹介しているサイトって
>あまり見かけないですよね?
>シューティングゲームならよく見かけるのですが・
STGは作りやすいんですよね。
ざっくり言ってしまえば、プレイヤー置いて敵置いて弾出してあたり判定つけたら
大筋は終わりです。
しかし、RPGだとシステムとして作らなければならない部分が多く、
そんな簡単にはいかないわけで。
単純に考えても、フィールドパート、バトルパートと2つの大きなパートがあって、
フィールド側には移動、アイテム管理、シナリオ・イベント(時系列進行管理)、
街・ダンジョンなどのマップ、ギミック、NPC制御、成長、ショップ、エンカウント、
各種エフェクトなどがあり、バトルの方もフィールドほどではないかもしれませんが
似たような状態です。
話がややこしくなるのが、それらの要素が密接に絡み合っていることで、
特にシナリオ・イベント……時系列にそった進行管理は、様々なパートに影響を及ぼします。
データもコード量も結構な量になりがちなので、それらをサポートする為に
何種類ものツールが別途必要になるでしょう。
とまぁ、ここまで本格的なものはともかく、要素を絞ってピンポイントで説明していけば
講座を作ることもできるのかなとは思いますが、もし龍神録の館のように
コンセプトを確かにした上で、ユーザーが拡張できる余地をいれる、とかやり始めると……。
要するに RPGのプログラムを紹介するのは大変だ、ってことですね。
451ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(30,931ポイント)
Date: 2009/02/27(金) 13:31
No:29498
|
|
Title: Re:マップの切り替え処理
|
|
>>kazuoniさん
私もC++の勉強をしようかどうか悩んでます^^;
でも、C++でのプログラミングは何のメリットがあるのかわからないんですが・・・
やっぱりクラスやオブジェクト指向があるのが魅力的なんですかね?
>>Justyさん
おっしゃる通りイベントや移動、バトルといったシステム管理が難しいです。
特に、イベントの処理をどうすればいいかいろいろと考えています。
(今はマップの切り替え処理をしていますが)
いろいろ試行錯誤を重ねて頑張っていきたいと思います。
191ポイント を手に入れた。
|
|
|
|
Name: ざこ ..上級者(24,869ポイント)
Date: 2009/02/26(木) 14:12
No:29447
|
|
Title: DragDropについて
|
|
MFCでDragDropについて勉強しています。アプリケーション内のDragDropならDragするコントロールの位置
を取りDropする位置まできたらドロップする というのは大体ですがわかりました。ではアプリケーション外からは
どうなのでしょうか?例えばAというアプリケーションがあり、Bというテキストファイルがあります。
BをAにDragDropしてA内でBの内容を開く、 ということができるAを作りたいのですがやり方がわかりません。
●イメージ:Bの位置を随時レジストリか何かに入れ、Aの位置まで着たらAのテキストファイルを扱えるような
ディレクトリまで飛ばす、という風なイメージを考えたんですが何かおかしいきがします。
今プロジェクトの状態なのでアプリケーション化しなくてはできなさそうですがどうでしょうか
色々アドバイス下さい。
VC++6.0でやっています。
312ポイント を手に入れた。
|
|
|
|
Name: ざこ ..プログラマー(25,094ポイント)
Date: 2009/02/27(金) 11:45
No:29495
|
|
Title: Re:DragDropについて
|
|
それは調べたらすぐわかりました。少し色々試したんですがプログラムを実行し、例えばリストボックスなどに
DragDropしたテキストファイルを書き出す ということはできました。DragAcceptFilesでドラッグ許可もしております。しかしデスクトップ上に実行ファイルをおいて、そこにテキストファイルをDragDropした場合反応しません。
例えばごみ箱みたいにファイルをごみ箱へDragDropするとファイルがごみ箱の中へ移動する
感じに近いと思うのですがどうすればいいのでしょうか。
225ポイント を手に入れた。
|
|
|
|
|
Name: toyo ..プログラマー(26,597ポイント)
Date: 2009/02/27(金) 12:41
No:29496
|
|
Title: Re:DragDropについて
|
|
実行ファイルのアイコンにドラッグですね
その場合はコマンドライン引数で受け取ります。
コンソールアプリ
int main(int argc, char* argv[ ])
の場合のargcとargvと同様にWin32アプリでは __argc と __argv[ ](wchar_t型の__wargv[ ]やTCHAR型の__targv[ ]も使えます)がグローバル変数として使えますよ。
GetCommandLine()でコマンドライン全体の文字列も受け取れます。
130ポイント を手に入れた。
|
|
|
|
|
Name: ざこ ..プログラマー(25,143ポイント)
Date: 2009/02/27(金) 13:02
No:29497
|
|
Title: Re:DragDropについて
|
|
なるほど、ちょっと知識不足ですのでコマンドラインについて勉強してきます。わからなかったらまた教えて下さい。ありがとうございました。
49ポイント を手に入れた。
|
|
|
|
Name: スロット ..ぴよぴよ(9ポイント)
Date: 2009/02/24(火) 19:21
No:29254
|
|
Title: お尋ね致します。
|
|
今現在、ホームページにて推測ツールなるCGIを公開していますが、一部でうまく計算されない箇所があり、悩んでいます。
私自身プログラムを組める技量が無いので、アドバイス頂けると助かると思い書き込み致しました。
9ポイント を手に入れた。
|
|
|
|
Name: バグ ..ハッカー(148,922ポイント)
Date: 2009/02/24(火) 19:27
No:29255
|
|
Title: Re:お尋ね致します。
|
|
結局、何が知りたいのでしょうか?
>>今現在、ホームページにて推測ツールなるCGIを公開していますが、一部でうまく計算されない箇所があり、悩んでいます。
1:推測ツールって何を推測するものですか?
2:CGIは何を利用して組んでいますか?(例えばPerlとか…)
3:うまく計算されない箇所があると言われても、これだけでは何の事か検討もつきません。
64ポイント を手に入れた。
|
|
|
|
|
Name: たかぎ [URL] ..比類無きプログラマー(85,713ポイント)
Date: 2009/02/24(火) 19:40
No:29257
|
|
Title: Re:お尋ね致します。
|
|
> 私自身プログラムを組める技量が無いので
ご自身でプログラミングを習得しようというのならともかく、そうでないならこの掲示板で質問しても無駄です。
詳しいことが分からないので対応可能かどうかは断定できませんが、修正を希望されるのであれば詳しい情報をご連絡ください。見積もりを出します。
90ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..ぴよぴよ(41ポイント)
Date: 2009/02/24(火) 23:25
No:29287
|
|
Title: Re:お尋ね致します。
|
|
ご返信頂きまして有難う御座います。
推測ツールというのはパチスロの設定判別に使用するツールになります。
ベースになるCGIは無料でソースを公開しているサイトから管理人様の許可を得て使用しています。
メールアドレスを登録致しましたので、こちらにご連絡頂ければ、CGIのソースを送りますので、見積もりをお願い致します。
32ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..ぴよぴよ(145ポイント)
Date: 2009/02/25(水) 10:37
No:29312
|
|
Title: Re:お尋ね致します。
|
|
> 結局、何が知りたいのでしょうか?
>
> >>今現在、ホームページにて推測ツールなるCGIを公開していますが、一部でうまく計算されない箇所があり、悩んでいます。
>
> 1:推測ツールって何を推測するものですか?
> 2:CGIは何を利用して組んでいますか?(例えばPerlとか…)
> 3:うまく計算されない箇所があると言われても、これだけでは何の事か検討もつきません。
>
説明不足ですいません。
パチスロの設定判別ツールなのですが、分母の数値が1/7とかのデータを試行回数を何千ゲームに設定して計算すると計算してくれなくなる為、結果が表示されなくなるのです。
少ない試行回数なら計算はしてくれますので、結果が表示されます。
104ポイント を手に入れた。
|
|
|
|
|
Name: Dixq (管理人) ..伝説なるハッカー(995,729ポイント)
Date: 2009/02/25(水) 11:30
No:29314
|
|
Title: Re:お尋ね致します。
|
|
見積もりを出すということは修正にお金がいるということだと思うのですが・・。
多分たかぎさんはボランティアで回答している人の回答をきちんと受けたいのなら規約を守ってきちんと質問して下さいよということが仰りたいのだと思います。
「うまくできないんです」という質問は大抵回答に困るのです。
何の情報もわからないのですから。
後から付け加えられた情報も少なすぎてわからないです。
具体的な説明が難しいならソースコードが無いと無理だと思います。
例えば医者に見てもらうとき、のどを見てもらうことも、聴診器をあてることも、問診表を書くことも何もせず、
全く情報を医者に与えない状態で、
「体調が悪いんです。どこがいけないのですか?」
と聞いたって医者はわかるはずありませんよね。
それと同じです。
スロットさんが回答する立場だと思って質問文を考えてみて下さい。
質問の仕方が解らない時は規約のテンプレを使って下さい。
> 私自身プログラムを組める技量が無いので
これは例えバグが発生している部分の指摘を受けられたとしても自分で解決出来ないということでしょうか?
72ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..かけだし(1,725ポイント)
Date: 2009/02/25(水) 12:43
No:29321
|
|
Title: お尋ね致します。
|
|
管理人 様
プログラムを自分で組める様になりたい気持ちはあります。
与えられたプログラムを自分で編集したり、判らないなりに努力していますが、知識や技量が無い為、どの様に修正すれば良いのか判らないので質問してみました。
管理人さんの言う様にソースと症状の説明がないと質問された方も困りますね^^;
申し訳ありません。
下記のソースで
@big = ('327', '318', '309', '300', '292', '284'); # 1/x
@reg = ('682', '630', '585', '546', '512', '481');
の部分が参照する元の数値になりますが、この数値を10桁、1桁の数値に置き換えると計算してくれなくなり、
設定〜の確率が何%と表示されなくなります。
分母の数値が小さくなるとオーバーフローを起こして計算しなくなると云われた事がありましたが、どの様な計算式に組み直せば良いのか判らず、ご指導頂きたく書き込み致しました。
#!/usr/bin/perl
# ゴールドシオ(シオラー2) 二項分布によるデータのみからの設定信頼度
$cginame = 'goldshio.cgi';
$title = 'ゴールドシオ(シオラー2) データからの設定信頼度';
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
read (STDIN, $input, $ENV{'CONTENT_LENGTH'});
}
foreach $str (split(/&/,$input)) {
($name,$value) = split(/=/, $str);
push(@input, $value);
}
($play, $big, $reg) = @input;
print "Content-Type: text/html\n\n";
# ヘッダとフォームの表示
print <<"__ HTML __";
<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>
<html lang='ja'>
<head>
<meta http-equiv='Content-Type' content="text/html; charset=shift_jis">
<title>ゴールドシオ(シオラー2)設定判別 $title</title>
<style type="text/css"> <!--
A:hover {color:#ff0000;}
--></style>
</head>
<body text='#000000' bgcolor='#ffffff' link='#0000ff' alink='#ff0000' vlink='#0000cc'>
$title
<form action='$cginame' method='POST'>
プレイ数
<input type='text' size=6 name='play' maxlength=5 value='$play'> BIG
<input type='text' size=6 name='big' maxlength=4 value='$big'>
REG
<input type='text' size=6 name='reg' maxlength=4 value='$reg'> <input type='submit' value="開始">
</form>
全設定が均等に設置という仮定のもとに計算。
__ HTML __
# エラーチェックとGET送信
if ($ENV{'REQUEST_METHOD'} ne 'POST') {
print 'top へ戻る',"\n",'</body></html>';
exit;
}
if($play > 99999) {
print 'ERROR ! (プレイ数制限)';
print 'top へ戻る',"\n",'</body></html>';
exit;
}
# goldshio data
@big = ('327', '318', '309', '300', '292', '284'); # 1/x
@reg = ('682', '630', '585', '546', '512', '481');
#------------
# 計算開始
#------------
$big = 0 if !$big;
$reg = 0 if !$reg;
$bp = &point(($play/$big), 2) if $big;
$rp = &point(($play/$reg), 2) if $reg;
$br = $big + $reg;
$brp = &point(($play/$br), 2) if $br;
for ($i=0; $i<=5; $i++) {
$p1 = (1/$big[$i])**$big * (1-1/$big[$i])**($play-$big);
$p2 = (1/$reg[$i])**$reg * (1-1/$reg[$i])**($play-$reg);
$p3 = $p1 * $p2;
$t_bigp += $p1; push(@bigp,$p1);
$t_regp += $p2; push(@regp,$p2);
$t_brp += $p3; push(@brp, $p3);
}
# 百分率にする
for ($i=0; $i<=5; $i++) {
if ($t_bigp){
$per1 = &point(($bigp[$i]/$t_bigp*100),2);
}else{
$per1 = 0;
}
if ($t_regp){
$per2 = &point(($regp[$i]/$t_regp*100),2);
}else{
$per2 = 0;
}
if ($t_brp){
$per3 = &point(($brp[$i]/$t_brp*100),2);
}else{
$per3 = 0;
}
push(@nb,$per1);
push(@nr,$per2);
push(@nbr,$per3);
}
# 結果の表示
print '
',"BR合成 (1/$brp)
",'BRからの設定信頼度
';
for ($i=1; $i<=6; $i++) { print "設 $i -> $nbr[$i-1] %
\n"; }
print '
',"BIG $big 回 (1/$bp)
",'BIG からの設定信頼度
';
for ($i=1; $i<=6; $i++) { print "設 $i -> $nb[$i-1] %
\n"; }
print '
',"REG $reg 回 (1/$rp)
",'REG からの設定信頼度
';
for ($i=1; $i<=6; $i++) { print "設 $i -> $nr[$i-1] %
\n"; }
exit;
# 少数を四捨五入して指定の桁にする
sub point {
my($value, $fig, $x);
($value, $fig) = @_;
$value = int($value * (10 ** $fig) + 0.5) / (10 ** $fig);
if ($value =~ /(\d+)\.(\d+)/) { $x = $2; }
elsif ($value !~ /\./) { $x =''; $value .= '.'; }
$value = $value.'0' x ( $fig - length($x) );
return $value;
}
1,580ポイント を手に入れた。
|
|
|
|
|
Name: たかぎ [URL] ..比類無きプログラマー(85,950ポイント)
Date: 2009/02/25(水) 20:04
No:29373
|
|
Title: Re:お尋ね致します。
|
|
> 多分たかぎさんはボランティアで回答している人の回答をきちんと受けたいのなら規約を守ってきちんと質問して下さいよということが仰りたいのだと思います。
基本的にはそうです。丸投げは禁止ですので。
いずれにせよ、PerlやCGIに関して、入門書の一冊でも読んで、その内容を一通り実践した上で、分からないところを分かるようにする目的で質問するならともかく、単に結果が欲しいだけなら掲示板上で解決するのは無理です。
そうはいっても、結果が必要な状況は理解できます。
その場合は、お金を払って解決するしかありませんよね。
私もその手の仕事を受ける業者ですので、違法なことや公序良俗に反することでない限り、頼まれればお引き受けします。
ただし、まともに費用がかかりますので、必ずしも安くはありません。
237ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..かけだし(1,852ポイント)
Date: 2009/02/25(水) 23:24
No:29402
|
|
Title: Re:お尋ね致します。
|
|
ご返信頂きまして有難う御座います。
仰るとおりだと思います。
今までCGIやプログラム等に縁の遠い仕事ばかりしていたもので、書店等にCGIやperlの本を見に行っても内容が理解しにくいと言うか…自分の知りたい情報がどの様な書籍に紹介されているのかも判らないので「こういう本を参考に勉強して下さい」と言う様なアドバイスでも頂けると幸いです。
127ポイント を手に入れた。
|
|
|
|
|
Name: たいちう ..上級者(24,503ポイント)
Date: 2009/02/26(木) 00:02
No:29408
|
|
Title: Re:お尋ね致します。
|
|
書籍の選び方、というのが今の質問内容ですね?
Amazonの書評などは当然参考にしていると仮定しての回答です。
私はPerlの経験はありませんが、プログラムの全くの初心者が独学でそこそこのレベル
(スロットさんが現在持つ問題を解決できるレベル)に到達するには、
2週間から2ヶ月程度のフルタイム(8時間/日、5日/週)の期間が
目安として必要ではないかと思います。
問題のレベルについての私の憶測が大きく外れている可能性もある他、
本人の適性によっては半日で十分な人もいるかもしれません。
逆に、10年でも無理な人は確実にいます、それも多数。
目先の問題だけ考えるなら、つてを頼ってお金で解決するほうが多分安上がりです。
それでも自分で解決したいという場合の話ですが、
一般論として万人向けの書籍は、まず存在しません。
私の場合、その分野の本を何十冊も立ち読みして、
今の自分にあったものを選ぶことが多いです。
一冊失敗だったとしても、より良い本を選ぶためのスキルが上がったと考えましょう。
211ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..かけだし(1,971ポイント)
Date: 2009/02/26(木) 01:36
No:29418
|
|
Title: お尋ね致します。
|
|
ご返信頂きまして有難う御座います。
本を調べて勉強もしようと思いますが、ソースを見て頂いてこの部分をこうしてみたら?的なアドバイスを頂けると時間が掛からなくて済むと思うところも正直あったりしますね…すみません。
本を何度か読んでみましたが…自分が悩んでいるCGIとは違う内容であったり…。
内容の合う本に出会っていないですね。
119ポイント を手に入れた。
|
|
|
|
|
Name: 通りすがり ..中級者(14,189ポイント)
Date: 2009/02/26(木) 02:15
No:29425
|
|
Title: Re:お尋ね致します。
|
|
自分のHPでCGI公開してるのに、自分がCGI組む能力が無いというのはよくわかりませんね。
後ここはCGI掲示板ではないので、回答が集まらなくても仕方ないかと。
67ポイント を手に入れた。
|
|
|
|
|
Name: 佐倉@ ..ぴよぴよ(13ポイント)
Date: 2009/02/26(木) 02:30
No:29427
|
|
Title: Re:お尋ね致します。
|
|
if($play > 99999)
とプレイ数が大きい時に終了するようにプログラムされています。
これはサーバー負荷がかからないようにするためでして
あまり適当に大きくしてはいけないように思います。
13ポイント を手に入れた。
|
|
|
|
|
Name: SooA ..ぴよぴよ(26ポイント)
Date: 2009/02/26(木) 04:58
No:29429
|
|
Title: Re:お尋ね致します。
|
|
はじめまして。 少々気になったので書き込ませて頂きます。
ご本人も分かっていると思いますが、
このCGIはプレイ回数、プレイ回数中に BIG or REG を引いた回数を指定して
パチスロ台の各設定確率を出すプログラムです。
1000回のプレイでBIGを1回 REGを2回引いたとすると
設 1 -> 18.34 %
設 2 -> 17.95 %
設 3 -> 17.30 %
設 4 -> 16.43 %
設 5 -> 15.51 %
設 6 -> 14.46 % となり、
その台が設定6の台である確率が14.46% といった計算をしているわけです。
そして以下のデータはおそらく左から設定1の場合の平均プレイ回数を表しています。
@big = ('327', '318', '309', '300', '292', '284'); # 1/x
@reg = ('682', '630', '585', '546', '512', '481');
という事は通常この値を一桁や二桁にする必要は無い訳ですが、
まぁそれは置いといて、
まず入力した数値は
<input type='text' size=6 name='play' maxlength=5 value='$play'>
<input type='text' size=6 name='big' maxlength=4 value='$big'>
<input type='text' size=6 name='reg' maxlength=4 value='$reg'>
この部分で $play $big $reg に値が入ります。
配列宣言している名前と同じですが別のデータです。
普通違う名前にするもんですが、
仕方が無いので [] が付くか付かないかで判別します。
配列は $i=0; $big[$i]; の場合
$big[0] で、$big[0]の値は 327 となります。
$big[1] で、$big[1]の値は 318
$big[2] で、$big[2]の値は 309
以下を見れば数値がどのように対応しているかわかりますね?
@big = ('327', '318', '309', '300', '292', '284'); # 1/x
後の #計算開始 以降は四則計算を行っているだけですので。
+= や / * の意味を学んでください。
どんな計算を行っているかが分かれば、
なぜ欲しい結果が得られないか導き出せると思います。
26ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..かけだし(2,160ポイント)
Date: 2009/02/26(木) 11:04
No:29437
|
|
Title: Re:お尋ね致します。
|
|
> はじめまして。 少々気になったので書き込ませて頂きます。
>
> ご本人も分かっていると思いますが、
> このCGIはプレイ回数、プレイ回数中に BIG or REG を引いた回数を指定して
> パチスロ台の各設定確率を出すプログラムです。
>
> 1000回のプレイでBIGを1回 REGを2回引いたとすると
> 設 1 -> 18.34 %
> 設 2 -> 17.95 %
> 設 3 -> 17.30 %
> 設 4 -> 16.43 %
> 設 5 -> 15.51 %
> 設 6 -> 14.46 % となり、
> その台が設定6の台である確率が14.46% といった計算をしているわけです。
> そして以下のデータはおそらく左から設定1の場合の平均プレイ回数を表しています。
>
> @big = ('327', '318', '309', '300', '292', '284'); # 1/x
> @reg = ('682', '630', '585', '546', '512', '481');
>
> という事は通常この値を一桁や二桁にする必要は無い訳ですが、
> まぁそれは置いといて、
>
> まず入力した数値は
> <input type='text' size=6 name='play' maxlength=5 value='$play'>
> <input type='text' size=6 name='big' maxlength=4 value='$big'>
> <input type='text' size=6 name='reg' maxlength=4 value='$reg'>
> この部分で $play $big $reg に値が入ります。
>
> 配列宣言している名前と同じですが別のデータです。
> 普通違う名前にするもんですが、
>
> 仕方が無いので [] が付くか付かないかで判別します。
> 配列は $i=0; $big[$i]; の場合
> $big[0] で、$big[0]の値は 327 となります。
> $big[1] で、$big[1]の値は 318
> $big[2] で、$big[2]の値は 309
> 以下を見れば数値がどのように対応しているかわかりますね?
> @big = ('327', '318', '309', '300', '292', '284'); # 1/x
>
> 後の #計算開始 以降は四則計算を行っているだけですので。
> += や / * の意味を学んでください。
> どんな計算を行っているかが分かれば、
> なぜ欲しい結果が得られないか導き出せると思います。
仰る通りパチスロ台の各設定確率を出すプログラムになります。
'327', '318', '309', '300', '292', '284'の数値はメーカーが発表している設定別のBIGボーナス当選確率になります。
この場合は分母の数値が大きいので現在のプログラムで問題なく計算してくれます。
BIGボーナスの数値の部分を通常時の小役確率(例えばベルやスイカ)等に置き換えようとすると分母が小さくなります(1/7とか1/8.5等)
分母が小さくなった際に下記の部分が表示されなくなります。
設 1 -> %
設 2 -> %
設 3 -> %
設 4 -> %
設 5 -> %
設 6 -> %
162ポイント を手に入れた。
|
|
|
|
|
Name: hss12 ..ぴよぴよ(511ポイント)
Date: 2009/02/26(木) 13:47
No:29446
|
|
Title: Re:お尋ね致します。
|
|
Perlは詳しくないのですが、ぱっと見たところ
$p1 = (1/$big[$i])**$big * (1-1/$big[$i])**($play-$big);
$p2 = (1/$reg[$i])**$reg * (1-1/$reg[$i])**($play-$reg);
$p3 = $p1 * $p2;
のあたりで値が小さくなりすぎているのかなと思います。
($playの値が多すぎることによるオーバーフロー?)
Math::BigFloatを使うとどうなるでしょうか?
見当違いでしたらすみません。
print文などを入れてどこで値が消えているのか調べてはどうでしょうか。
220ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..かけだし(2,244ポイント)
Date: 2009/02/26(木) 14:40
No:29451
|
|
Title: Re:お尋ね致します。
|
|
> Perlは詳しくないのですが、ぱっと見たところ
>
> $p1 = (1/$big[$i])**$big * (1-1/$big[$i])**($play-$big);
> $p2 = (1/$reg[$i])**$reg * (1-1/$reg[$i])**($play-$reg);
> $p3 = $p1 * $p2;
>
> のあたりで値が小さくなりすぎているのかなと思います。
> ($playの値が多すぎることによるオーバーフロー?)
> Math::BigFloatを使うとどうなるでしょうか?
> 見当違いでしたらすみません。
> print文などを入れてどこで値が消えているのか調べてはどうでしょうか。
>
ご返答頂きまして有難う御座います。
CGIの製作者の方も比較する数値の分母が小さくなるとオーバーフローを起こして計算しなくなると仰っておりました。
試行回数=play数が増えると動作しなくなる様です。
84ポイント を手に入れた。
|
|
|
|
|
Name: SooA ..かけだし(1,107ポイント)
Date: 2009/02/26(木) 17:03
No:29459
|
|
Title: Re:お尋ね致します。
|
|
取りあえず、貼ってあるCGIは動かなかったので
他から引っ張ってきてデータを置き換えて試してみました。
計算部分は特に変更は加えてませんが、
小さい値でも正常に計算できてますよ?
1,081ポイント を手に入れた。
|
|
|
|
|
Name: SooA ..かけだし(1,152ポイント)
Date: 2009/02/26(木) 17:10
No:29461
|
|
Title: 追記
|
|
スイカの子役確率が分からないので
googleで検索してゴールドシオ30とか言うのから引っ張りました。
ちなみに四則計算とは
・加算 + 足し算
・減算 - 引き算
・乗算 * 掛け算
・除算 / 割り算
よく見るとべき乗「**」も使ってましたが
参考書には最低限これらは書かれています。
Perl(パールと読みます)を覚えたいのなら
このプログラムは短く基本的な事しかしていないので
丁度良いです。
一つ一つ解析して覚えてみましょう。
31ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..かけだし(2,344ポイント)
Date: 2009/02/26(木) 17:26
No:29465
|
|
Title: Re:追記
|
|
色々お手数をお掛けしてしまい申し訳ありません。
施行回数=play数を3500としてスイカの成立回数195回だと計算してくれなくなります。
何処かに元のデータの確率を10倍もしくは100倍して計算をし、結果表示の部分で元の数値に約分されるプログラムを組まないといけないのでしょう…。
100ポイント を手に入れた。
|
|
|
|
|
Name: SooA ..かけだし(1,730ポイント)
Date: 2009/02/26(木) 18:47
No:29469
|
|
Title: Re:追記
|
|
まず結論から言うと、大きい数字を入れると
結果がとんでもなく 0 に 近い数値しか
出さないために表示されていません。
当方の貼ったCGIで10回中3回スイカを引いた場合だと正常に表示されますよね?
つまり考え方としては入力した数値が小さければ問題ないということです。
という事は先に書きましたが入力された数値は $play $big $reg でしたね?
これをどうすれば良いのでしょうか?
大きいから問題が出るのだから?
$big = $big/10;
予め小さくしてやればいいんです。
#------------
# 計算開始
#------------
$big = 0 if !$big;
$reg = 0 if !$reg;
$play2 = $play/10;
$big2 = $big/10;
$reg2 = $reg/10;
$bp = &point(($play2/$big), 2) if $big;
$rp = &point(($play2/$reg), 2) if $reg;
$br = $big + $reg;
$brp = &point(($play2/$br), 2) if $br;
for ($x=0; $x<=5; $x++) {
$a0 = 1/$big[$x];
$a1 = 1/$reg[$x];
$p1 = $a0**$big2 * (1-$a0)**($play2-$big2);
$p2 = $a1**$reg2 * (1-$a1)**($play2-$reg2);
$p3 = $p1 * $p2;
$t_bigp += $p1; push(@bigp,$p1);
$t_regp += $p2; push(@regp,$p2);
$t_brp += $p3; push(@brp, $p3);
}
578ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..かけだし(2,473ポイント)
Date: 2009/02/26(木) 19:02
No:29470
|
|
Title: Re:追記
|
|
ご返信頂きまして有難う御座います。
色々お時間を割いてしまい申し訳ありません。
パチスロは1日打てば大体8000G〜9000G程回せます。
プレイ数=回した数なので、数値は3500とか5000とかの数値を入力しなければなりません。
上記のプレイ中にスイカの出現回数を入力するのですが、3500〜5000回程回すと200〜300回程度の出現回数になってしまいます。
129ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..入門者(2,524ポイント)
Date: 2009/02/26(木) 19:15
No:29472
|
|
Title: Re:追記
|
|
すいません読んでます。
試行回数が1000回程度でスイカの出現回数が60〜70回位なら問題なく計算してくれます。
ただ、設定判別の精度を上げるために試行回数が増えてしまうのです。
51ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..入門者(2,687ポイント)
Date: 2009/02/26(木) 19:46
No:29477
|
|
Title: Re:追記
|
|
いや…すいません。
理解していなかった様ですorz
みて驚いたのと同時に自分にがっかりしました。
#------------
# 計算開始
#------------
$big = 0 if !$big;
$reg = 0 if !$reg;
$play2 = $play/10;
$big2 = $big/10;
$reg2 = $reg/10;
$bp = &point(($play2/$big), 2) if $big;
$rp = &point(($play2/$reg), 2) if $reg;
$br = $big + $reg;
$brp = &point(($play2/$br), 2) if $br;
for ($x=0; $x<=5; $x++) {
$a0 = 1/$big[$x];
$a1 = 1/$reg[$x];
上記の部分の記述をこの様に書き換えれば良いのですね。
163ポイント を手に入れた。
|
|
|
|
|
Name: スロット ..入門者(2,736ポイント)
Date: 2009/02/26(木) 19:50
No:29478
|
|
Title: 追記
|
|
追記になりますが、
$play2 = $play/10;
$big2 = $big/10;
$reg2 = $reg/10;
上記の記述を追加しても参照する数値や判別結果に影響はないのでしょうか?
色々聞いてすいません。
49ポイント を手に入れた。
|
|
|
|
|
Name: SooA ..かけだし(1,894ポイント)
Date: 2009/02/26(木) 20:29
No:29481
|
|
Title: Re:追記
|
|
$play2 というのは実際に $play を表示に使う場合に
影響しないように、計算で使うためだけに用意した変数です。
ですので計算記述中の $play は $play2 に置き換わっています。
$big は $big2
$reg は $reg2
後、念のため言っておきますが、
書いている文章も、載せてあるプログラムも
900/9000 も 9/90 も確率は同じという
あくまで『考え方の例』として書いたものですので、
単に値を小さくしただけだと
おそらく問題が発生すると思います。
この辺りは参考書を読んで自分なりに
勉強してみてください。
1000以上の値が入力されたら値を加工するなどの
分岐処理を覚えれば大丈夫です。
118ポイント を手に入れた。
|
|
|
|
|
Name: SooA ..かけだし(2,009ポイント)
Date: 2009/02/26(木) 21:30
No:29482
|
|
Title: Re:追記
|
|
一応完成したものを上げておきますが、
そのまま使うのではなく、
できればどんな事をしているのか
内容を理解した上で使用してください。
元のプログラムの改造に役立てるなど、
とにかくPerlに触れてみましょう。
この部分は変更しました。
↓
×最大桁数を一桁上げておいたので
計算も怪しかったので
修正したのでソースを変更してください。
115ポイント を手に入れた。
|
|
|
|
|
Name: SooA ..かけだし(2,118ポイント)
Date: 2009/02/27(金) 01:03
No:29487
|
|
Title: Re:追記
|
|
> SooA様
> 色々有難う御座います。
> parlの本を読みながら色々試して見ます。
> プログラムが面白くなれば良いと思います。
余計なことをして計算結果がおかしくなっていたのと
またまた余計に桁を増やして40000/99999とかやると
計算できないので一万回以下に戻しました。
ソースを修正しておいたので直してください。
情報が足りないときに参考書を開いたり
Web検索で探したりすればいいので
様々な命令を全て覚えることはありません、
基本的な演算子とif文や比較文を覚えれば
なんとかなりますのでがんばってください。
109ポイント を手に入れた。
|
|
|
|
Name: たか ..初心者(7,028ポイント)
Date: 2009/02/27(金) 04:01
No:29489
|
|
Title: newでインスタンス化
|
|
クラスをnewでインスタンス化するメリットはありますか?
C++の入門書などを眺めていて、仮想関数を使うときはどんな場面だろうか。
とか、思っていて次に中々進めてないので質問しました。
回答よろしくお願いします。
環境:
Visual C++ Express Edition 2008
Windows Vista Home Basic
89ポイント を手に入れた。
|
|
|
|
Name: SCI ..中級者(10,708ポイント)
Date: 2009/02/27(金) 04:29
No:29490
|
|
Title: Re:newでインスタンス化
|
|
クラスに限らず、「メモリを動的に確保する」ということはC/C++特有のメリットがあります。
例えば、普通に宣言(例えば自動記憶域期間)すると、スコープを抜けた時点で問答無用でなくなります。
また、宣言時に、インスタンス生成に必要な情報を揃えておく必要があります。
これに対して、動的確保を使う場合、生成・破棄のタイミングを自分で決めることができるので、処理の幅が広がります。
実行時まで生成に関する情報が定まらないインスタンスなどは、必然的にこの方法になるでしょうね(私はまだそのようなものを扱ってませんが)。
それから、これは仮想関数とも関係があるのですが、共通する基底クラスのポインタとしていろいろな派生クラスのポインタを保持することができます。
格納したポインタから仮想関数を呼ぶことで、派生クラスの(オーバーライドされた)メソッドを呼ぶことが出来ます。
268ポイント を手に入れた。
|
|
|
|
|
Name: たか ..初心者(7,151ポイント)
Date: 2009/02/27(金) 05:33
No:29491
| 解決!
|
Title: Re:newでインスタンス化
|
|
> クラスに限らず、「メモリを動的に確保する」ということはC/C++特有のメリットがあります。
「メモリを動的に確保する」ということはCで学習してメリットも充分理解していましたが、
クラスだから、C++だからということで違うものと認識していました。
クラスでもC++でも変わりませんね。そうですよね
> 共通する基底クラスのポインタとしていろいろな派生クラスのポインタを保持することができます。
> 格納したポインタから仮想関数を呼ぶことで、...
C++の入門書にも書いてありました。今、意味が理解できました。
回答有難うございました。
123ポイント を手に入れた。
|
|
|
|
Name: はる ..ぴよぴよ(83ポイント)
Date: 2009/02/26(木) 11:50
No:29440
|
|
Title: 文字列置き換え
|
|
はじめてお世話になります。
超初心者でいまひとつ文字列について理解できていません。。
質問なのですが、
char str[]="comment\ncomment1";
と定義したものについて、
改行コード”\n”を”{\n}”に置き換えたいのです。
strtokとstrcatを使って出来る方法を思いついたのですが、
いまいち動きがよくわかりません。
どなたかご教授お願いします。
またもっと良い方法などあればそれも宜しくお願いします。
83ポイント を手に入れた。
|
|
|
|
Name: SCI ..中級者(10,150ポイント)
Date: 2009/02/26(木) 13:36
No:29444
|
|
Title: Re:文字列置き換え
|
|
strtokで分割するところまではできましたか?
「comment」と「comment1」という文字列に分解したら、
char str2[64];
strcpy(str2, 一つ目の文字列);
strcat(str2, "{\\n}"); //\記号を出力するには\\とします。
strcat(str2, 二つ目の文字列);
こんな感じでできますよ。
2倍のポイントを手に入れた! 254ポイント を手に入れた。
|
|
|
|
|
Name: はる ..ぴよぴよ(238ポイント)
Date: 2009/02/26(木) 14:21
No:29448
|
|
Title: Re:文字列置き換え
|
|
SCIさんありがとうございます。
何個改行コードがあるかわからないときに、↓のように
するとうまくいったようです。。
ネットで検索してでてきた通りに書いたのですが、
2個目以降の処理でstrtokにNULLを渡しているのがよくわかりません。
また最後にも"{\n}"がついてでます。
これを消したいのですが、
方法がわかりません。。
char *tp;
char buf_ato[100];
char str[]="comment\ncomment1";
//1個目
tp = strtok(str, "\n");
strcpy(buf_ato, tp);
if ( tp != NULL ){
strcat(buf_ato, "{\n}");
}
//2個目以降
while ( tp != NULL ){
tp = strtok(NULL, "\n");
if ( tp != NULL ){
strcat(buf_ato, tp);
strcat(buf_ato, "{\n}");
//} else {
//最後の"{\n}"を削除
}
}
printf("*** ato =%s\n",buf_ato);
return 0;
155ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(10,292ポイント)
Date: 2009/02/26(木) 14:35
No:29450
|
|
Title: Re:文字列置き換え
|
|
2個目以降NULLを渡さなければならないのは、strtok関数の仕様です。
この関数はちょっと癖のある関数なので、他の関数とは雰囲気が違いますね。
コードについてですが、2個目以降
「文字列を連結してから改行文字を付け足す」
を
「改行文字を付け足してから文字列を連結」
にしてみたらどうでしょう。1個目の連結処理のところも改行をくっつけないようにします。
142ポイント を手に入れた。
|
|
|
|
|
Name: はる ..ぴよぴよ(263ポイント)
Date: 2009/02/26(木) 14:51
No:29452
|
|
Title: Re:文字列置き換え
|
|
SCIさん何度もありがとうございます!!
まさにそれでできました!
本当に助かりました。
25ポイント を手に入れた。
|
|
|
|
|
Name: フリオ ..プログラマー(29,460ポイント)
Date: 2009/02/26(木) 19:29
No:29475
|
|
Title: Re:文字列置き換え
|
|
ちょっと気になったのですが、"strtok"を使うと、
文頭や文末、連続した'\n'が省略されてしまいますけど、いいのでしょうか。
#include <stdio.h>
#include <string.h>
void func(char *s1, const char *s2)
{
while(*s1 = *s2){
if(*s2 == '\n'){
strcpy(s1, "{\\n}");
s1 += strlen(s1);
}
else ++ s1;
++ s2;
}
}
void func2(char *buf_ato, char *str)
{
char *tp;
tp = strtok(str, "\n");
strcpy(buf_ato, tp);
while ( tp != NULL ){
tp = strtok(NULL, "\n");
if ( tp != NULL ){
strcat(buf_ato, "{\\n}");
strcat(buf_ato, tp);
}
}
}
int main(void)
{
char s1[128], s2[] = "\n\ncomment\n\n\ncomment1\ncomment2\n\n\n\n";
func(s1, s2);
puts(s1);
func2(s1, s2);
puts(s1);
return 0;
}
362ポイント を手に入れた。
|
|
|
|
Name: 桃印 ..入門者(4,602ポイント)
Date: 2009/02/25(水) 10:09
No:29307
|
|
Title: 自己参照構造体のリスト処理について
|
|
以前、矩形と円形の当たり判定でこちらのお世話になった者です。
ゲーム製作において再び疑問点が浮上しましたので、質問させていただきます。
現在龍神録の館を利用しつつSTGを製作しているのですが、アレンジするにあたって通常では定数でグローバル宣言されている弾の構造体を、リスト処理で際限なく生成できるようにしようと思いました。
色々な資料を参考にしつつプログラムを組んだのですが、どうも構造体の宣言部分で躓いてしまう問題が発生しました。
構造体を宣言するヘッダ<struct.h>において、以下のように宣言すると大量にエラーが発生(ソースから呼び出されるたびにエラーが出ている?)してしまいます。
たとえばこのような変数を持つ構造体を宣言する場合、
//弾の構造体
typedef struct{
int flag; //フラグ
double range; //当たり判定の半径
double x, y; //座標
double spd; //速度
double angle; //角度
bullet_t *next; //自己参照構造体
}bullet_t;
EXTERN bullet_t *head;//先頭ポインタ
とすると『error C2143: 構文エラー : ';' が '*' の前にありません。』『error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません』というようなエラーが大量に発生します。
おそらく記述の方法がおかしいのだと思います。一応別の宣言方法などども試してみました。
//弾の構造体
struct bullet_t{
int flag; //フラグ
double range; //当たり判定の半径
double x, y; //座標
double spd; //速度
double angle; //角度
struct bullet_t *next; //自己参照構造体
}
EXTERN struct bullet_t *head;//先頭ポインタ
しかしこのようにした場合も、『error C2236: 予期しない 'struct' 'eff_t' です。';' が入力されていることを確認してください。』というエラーが出てしまいます。
宣言が出来なければプログラム以前の問題で、解決するだけの知識もなくすっかりお手上げ状態となっています。
どうかご教示いただけたら幸いです。
使用ライブラリ:DXライブラリ
コンパイラ:Visual C++ 2008 Express Editions
※質問内容が不十分の場合はお申し付けください
2倍のポイントを手に入れた! 1,036ポイント を手に入れた。
|
|
|
|
Name: 御津凪 [URL] ..熟練のプログラマー(62,214ポイント)
Date: 2009/02/25(水) 10:30
No:29310
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
//弾の構造体
struct bullet_t{
int flag; //フラグ
double range; //当たり判定の半径
double x, y; //座標
double spd; //速度
double angle; //角度
struct bullet_t *next; //自己参照構造体
}; // ←ここに';' が無いのが問題だと思います。
EXTERN struct bullet_t *head;//先頭ポインタ
74ポイント を手に入れた。
|
|
|
|
|
Name: 桃印 ..入門者(4,417ポイント)
Date: 2009/02/25(水) 10:52
No:29313
| 解決!
|
Title: Re:自己参照構造体のリスト処理について
|
|
御津凪さん、kazuoniさん、回答ありがとうございます!
>御津凪さん
うわあー凡ミスー! すいません、しっかり確認しておくべきでした。申し訳ないです;
ちゃんと;を入れてあげたところ、正しくポインタとリスト処理が機能することができました!
ありがとうございました!
>kazuoniさん
なるほど、そういう宣言方法もあるのですね。
ありがとうございました!
しょっぱいミスでお手を煩わせて申し訳ありませんでした! 以後気をつけます……。
185ポイント を落としてしまった。
|
|
|
|
|
Name: 桃印 ..入門者(4,953ポイント)
Date: 2009/02/25(水) 15:59
No:29335
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
度々申し訳ありません、 同じく自己参照構造体のリスト処理についてです。
皆様のお陰で構造体の宣言は出来たのですが、実際にそれらを使ったプログラムを組んでみたところ、上手く処理することができませんでした。
リスト構造については参考書やネットで検索して知識をつけているつもりなのですが、それらを龍神録プログラムに組み込む方法が分かりません。具体的には「動的に確保したメモリをリストの最後尾に追加」する方法と、また通常の龍神録の館で行われているような「繰り返しによる出力」の方法です。
前者はリストの先頭ポインタを関数に与え、while分でNULLに行き当たるまでループさせ、そこに動的確保したメモリのポインタを代入することでできると思っているのですが、具体的なアルゴリズムが分かりませんでした。
後者は、表示段階よりも前の処理で弾を移動制御する部分においてポインタの「現在位置(上手い表現が出てきません;)」をリスト最後尾まで移動してしまっており、表示処理の繰り返しに入る前の判断式while(bullet != NULL)の時点ではじかれてしまい表示処理に入ることができません。移動制御においてグローバル宣言されたリストを直接操作しなければ良いのでは、とは思うのですが移動制御は構造体内の変数を変更する処理(座標の代入とか)があるので直接操作してしまっています。扱っているのはポインタなので、通常の構造体のように直接操作する必要はないと思うのですが、ポインタについて理解が不十分なためどうしたらいいか分からないのです。
自分でも良く分からなくてソースもわやくちゃなので具体例を挙げることができないのですが、方法論だけでも教えていただけたら幸いです。
536ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(8,679ポイント)
Date: 2009/02/25(水) 16:53
No:29345
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
拙いコードで申し訳ないですが、自分の勉強も兼ねてリスト構造のサンプルを作ってみました。
理解の手助けになれば幸いです。
21ポイント を手に入れた。
|
|
|
|
|
Name: 御津凪 [URL] ..熟練のプログラマー(61,877ポイント)
Date: 2009/02/25(水) 17:00
No:29349
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
前者の方法は SCI さんの添付されたコードの通りで実装できます。
後者においては、以下のような方法で処理すると良いかもしれません。
// sHead という struct bullet_t *型のグローバル変数があると仮定
void BulletMove( void ){
struct bullet_t *blt = sHead; // 一時変数にて作業。グローバル変数は基本弄らない。
while( blt != NULL ){ // blt が NULL でない間、
/* blt に対する処理 */
blt = blt->next; // 次のデータへ移動する。
}
}
こうすればグローバル変数を操作することなく処理できます。
描画時でも同様に一時変数で作業を行なえば問題ないでしょう。
337ポイント を落としてしまった。
|
|
|
|
|
Name: 桃印 ..初心者(5,794ポイント)
Date: 2009/02/25(水) 23:29
No:29403
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
SCIさん、御津凪さん、回答ありがとうございます。
>SCIさん
わざわざサンプルまで作っていただいてありがとうございます。
とても読みやすいコードで参考になりました!
>御津凪さん
なるほど先頭ポインタを明け渡せばいいのですね。ポインタなので一時変数でもそのポインタをいじることには変わりないと。勉強になりました〜。
さて、こちらコードを元に「リスト最後尾に新しい構造体を追加し、その構造体のポインタを返す関数」を作成してみました。が、上手く動きません……どうやらリスト先頭がNULLのまま変わらずになっているようで、下記の御津凪さん案参考の繰り返しにも入ることができません。
ソースはこんな感じです。
bullet_t *bullet_set()
{
bullet_t *p = new bullet_t; // 新しいデータ
bullet_t *pCur = head; // リスト上の現在の位置
// 新しいデータの初期化
memset(p, 0, sizeof(bullet_t));//この初期化は正しい? 正しくない?
p->next = NULL;
if (pCur) // 先頭があったら
{
//最後尾までpCurを動かす。
while (pCur->next) pCur = pCur->next;
pCur->next = p; // 最後尾の次に、新しいデータを追加
}
※ else // 先頭がなかったら
{
head = p; // 新しいデータを先頭にします。
}
return p;
}
そして、return で戻したポインタに
bullet_t *p;
p = bullet_set(head);
p->x =100;
p->y =100;
p->size =2.0;
のような方法で弾をセットしていきます。
しかし調べてみたところ、何度弾がセットされてもbullet_set関数の※の部分の処理に飛んでしまいます。
それはif(pCur)のelse――もといif (pCur == NULL)であるからですよね。処理を繰り返しているとプログラムが凄く重くなるので、メモリは確保されているがポインタ受け渡しが上手くいっていないようです。
また、セット時の構造体初期化は龍神録の通りにmemset関数で0を代入したので良いのでしょうか?(一応この処理がなくてもエラーは出ませんでしたが……)。
先頭ポインタを参照して一時変数でいじるというのは理解しましたので、この処理で正しくポインタさえ代入できてしまえば、リスト構造での弾宣言ができると思うのですが……どうしたら良いのでしょうか……。
841ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(9,525ポイント)
Date: 2009/02/25(水) 23:44
No:29405
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
つまり、headがずっとNULLのままなんですね?
memsetは問題ないです。
headがグローバル変数なら、そのコードで書き換えが出来ていると思うのですが、headはグローバルな位置に宣言してありますか?
引数で渡すとしたら、ポインタのポインタにする必要があります。
79ポイント を手に入れた。
|
|
|
|
|
Name: 桃印 ..初心者(5,496ポイント)
Date: 2009/02/25(水) 23:56
No:29407
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
SCIさん、素早い回答ありがとうございます。
headは龍神録コードに則り、struct.hで
typedef struct _bullet_t{
double x, y; //座標
//そのほか色々な変数
_bullet_t *next; /* 自己参照構造体 */
}bullet_t;
GLOBAL bullet_t *head;
このように宣言され、ini.cppのfirst_ini()でhead = NULL;と代入しています。first_iniは初回のみしか実行されませんので、この部分でNULLを代入してしまっているということはないと思います。これでグローバル宣言できていると思うのですが……。
ポインタのポインタというのは、*演算子が二つ付いてるやつですよね。
bullet_setの仮引数部分をbullet_set(bullet_t **head)として先頭ポインタを渡すということでしょうか?
298ポイント を落としてしまった。
|
|
|
|
|
Name: 桃印 ..初心者(5,842ポイント)
Date: 2009/02/26(木) 00:17
No:29411
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
すいません、先頭がNULLのままの問題は自己解決しました!
どうやらコードの解釈を間違えていたようで、変な部分を変更していました。
正しく修正してみたところ、弾の発生と移動処理、そして描画処理もしっかり行われました!
が、しかしここでまた問題が……。
今度は弾消滅の際に「ポインタで受け渡した構造体を消去し、リストを繋げ直す」処理が出来ませんでした。
void eff_free(bullet_t *p)
{
bullet_t *pCur = p; // リスト上の現在の位置
bullet_t *pNext; // 削除の前にポインタを保存するため
// リストのすべての要素を解放します。
pNext = pCur->next;
delete pCur;
pCur = pNext;
}
SCIさんのサンプルにあった消去関数を参考にしたのですが、この方法だと上手く連結が出来ていないようで、一度でも消去の処理が実行されると繰り返しで迎えた移動制御の際にエラーが出てしまいます。エラーの内容がポインタ違反云々なので空のポインタに行き当たってしまったのだと思います(つまり連結が出来ていない)。
これはSCIさんが仰る「引数で渡すとしたら、ポインタのポインタにする必要があります」という部分が関わっていると思うのですが……多重間接参照がどう使ってやればいいのかがわかりません。受け渡した指定のポインタをbullet_t **pなりで受け取ってやるのでしょうか?
346ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(9,739ポイント)
Date: 2009/02/26(木) 00:35
No:29412
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
実は、今回作ったリストは「単方向リスト」と言うもので、途中の要素を削除したり、途中に要素を挿入したりするには「双方向リスト」を作る必要があります。
今回の構造体は「自分の次」だけ分かっている状態ですよね?
途中の要素を削除するには、「前」と「次」を繋がなければならないので、「自分の前」というデータも持っている必要があるんです。
さっきのソースをいじって双方向リストに作り変えることも出来るんですが、ここまで大丈夫ですか?
214ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(9,896ポイント)
Date: 2009/02/26(木) 01:04
No:29414
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
さっきのコードに「指定したデータを削除する関数」を追加しました。バグがあったらごめんなさい(泣
途中に追加する処理は入れてませんが、削除するときと同じように、NULLポインタに注意しながらつなぎかえることで実現できます。
また、環状リスト(って言うのかな?)やダミーを使ったり、先頭ポインタだけでなく最後尾ポインタも保存したりという方法もあります。
//でわ、私はもう寝ちゃいます。。
157ポイント を手に入れた。
|
|
|
|
|
Name: BEMANI ..上級者(17,510ポイント)
Date: 2009/02/26(木) 01:31
No:29417
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
プログラム書いていて、頭の中で処理が出来なければ
絵にかいてみることをお勧めします。
簡単な絵で結構です。
頭の中が整理できて、結構やりやすいですよ^^
やりたいことを絵に書いてみました。
エラーの原因なんですけど、
// リストのすべての要素を解放します。
pNext = pCur->next;
delete pCur;
pCur = pNext;
pCur を delete したあとで、pCur に代入しようとしているのが原因ではないでしょうか?
59ポイント を落としてしまった。
|
|
|
|
|
Name: 桃印 ..初心者(6,077ポイント)
Date: 2009/02/26(木) 07:42
No:29432
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
CSIさん、BEMANIさん、回答ありがとうございます!
>CSIさん
なるほど、やはり双方向でなければいけないのですね。実は元々双方向での考え方でやっていたのですが、どうにも混乱してしまって、こちらで相談するに至ったのです。しかし皆さんの協力のお陰でちょっとずつ理解できてきましたので、CSIさんのサンプルを元にコードを書いてみたいと思います。
出来ましたらまたご報告させていただきます。
>BEMANIさん
わ、これは分かりやすいですね。最初から図にしていれば良かったです。
最前後の場合を全く考えていなかったので、ここあたりがエラーの原因なのかもしれません。
それでは早速プログラムを組んでみたいと思います。
ありがとうございました!
235ポイント を手に入れた。
|
|
|
|
|
Name: 桃印 ..初心者(6,666ポイント)
Date: 2009/02/26(木) 10:45
No:29436
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
一応プログラムを組んでみました。
が、やっぱり削除が出来ておらず、制御・表示系突入時の判断式while(p != NULL)をスルーして突入してしまい、アクセス違反が発生してしまいます。やはり制御と表示はできているので、メモリを開放するだけなですが……。
一応プログラムを載せておきます。
void free(bullet_t *p)
{
bullet_t *pCur = p; // リスト上の現在の位置
if(pCur->prev == NULL){ //先頭
head = NULL;
}
else{
pCur->prev->next = pCur->next;
}
if(pCur->next == NULL){ //最後尾
pCur->prev->next = NULL;
}
else{
pCur->next->prev = pCur->prev;
}
delete pCur;
}
なお、弾構造体のセットは
bullet_t *bullet_set()
{
bullet_t *p = new bullet_t; // 新しいデータ
bullet_t *pCur = eff_head; // リスト上の現在の位置
// 新しいデータの初期化
memset(p, 0, sizeof(bullet_t));
p->prev = NULL;
p->next = NULL;
if (pCur != NULL) // 先頭があったら
{
//最後尾までpCurを動かす。
while (pCur->next) pCur = pCur->next;
p->prev = pCur;
pCur->next = p; // 最後尾の次に、新しいデータを追加
}
else // 先頭がなかったら
{
head = p; // 新しいデータを先頭にします。
}
return p;
}
このような方法で行っています。
589ポイント を手に入れた。
|
|
|
|
|
Name: 御津凪 [URL] ..熟練のプログラマー(63,223ポイント)
Date: 2009/02/26(木) 11:36
No:29439
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
データを削除する時に、対象が先頭データの場合だと head を NULL にしてしまい、リストがなくなってしまいます。
ここは 一つしかない場合(次が NULL のとき)に NULL にして、そうでない時は head を次のデータに移動させます。
また、先頭でも最後尾でもある場合(一つしかないデータ)の処理に問題があります。
(このときにアクセス違反が出ています)
ちなみに、下記のコードは双方向リストを循環的につなげる(最後尾と先頭をつなげる)形式の処理です。
// p を最後尾に追加
void AddList( bullet_t *p ){
if( head == NULL ){ // head が NULL なら、
head = p->prev = p->next = p; // head に代入(自分自身を指すようにもする)
} else { // head が NULL でないなら、
// (リストの最後尾は head の前のデータ)
p->next = head; // p の次を head に
p->prev = head->prev; // p の前を head の前に
head->prev->next = p; // headの前の次を p に
head->prev = p; // headの前を p に
}
}
// p を削除
bullet_t *RemoveList( bullet_t *p ){
if( head == p ){ // 削除対象が head の場合、
if( head == head->next ){ // 自分自身の循環参照(一つしかない)なら
delete p; // 削除。
head = NULL; // head を NULL にする。
} else { // 二つ以上ある場合は
head = head->next; // head を次のデータにする。
}
}
if( head != NULL ){ // head が NULL でない場合
bullet_t *ret = p->next; // 戻り値のための一時変数。
p->prev->next = p->next; // p の前の次を p の次に
p->next->prev = p->prev; // p の次の前を p の前に
delete p; // 削除。
return ret; // 削除対象の次のデータを返す。
}
return NULL; // データがないので NULL を返す。
}
// ループ処理
void MoveList( void ){
bullet_t *p = head;
if(p){
do{
/* 移動処理 */
if(/*移動処理内で削除依頼があったら*/){
p = RemoveList(p); // 削除
}
else p = p->next; // 次のデータへ
}while(p != head); // 一周するまで繰り返す
}
}
循環形式の場合だと、最後尾への追加で検索をせずに行なえます。
1,146ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(10,440ポイント)
Date: 2009/02/26(木) 14:53
No:29454
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
コンソールばかりではあれなので、実際にDxLibを使って弾を撃つプログラムを作りました。
最小限の内容を詰め込んだので、コンソールのときと見比べてみるとよく分かるかもしれません。
慣れてきたら、いろいろ改造してみるのもいいですね。
・ある程度間隔をあけて撃てるようにする
・発射位置にキャラクターを表示する
・循環リストにする
・リストの先頭にダミーを使う
などなど・・・
148ポイント を手に入れた。
|
|
|
|
|
Name: 桃印 ..初心者(5,459ポイント)
Date: 2009/02/26(木) 16:01
No:29456
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
御津凪さん、SCIさん回答ありがとうございます。
>御津凪さん
なるほど、リストをつなげて扱うなんて方法もあるんですね。これならリスト自体が動こうと、再び自分まで戻ってきたら一周と判断できますね。
早速御津凪さんのコードを組み込んでみました。動的にメモリ確保したポインタを取得し、そのポインタに必要数値をセット、そのポインタをAddList関数に渡してリスト登録。制御関数ではリスト一周分を繰り返し、削除したい場合はフラグを立て、フラグが立っていたらRemoveList関数を通し、そうでなければ次のポインタへ。
動作確認してみたところ、制御・表示ともに動作しました!
……んですが、なにやら弾がガクガクした動きになります。メモリリークでもして処理落ちしているのかと思いましたが、登録した玉のカウンタを表示してみたところ、どうやら「RemoveList関数を迎えると制御ループを飛び出してしまう(必ずNULLが帰ってきている?)」ようです。
カウンタを見たところ、玉が発生すると弾構造体数がガンガン増える(当然ですが)→ガクガクしはじめる→弾を止めてみる→ゆっくりと構造体数が減っていく(速度的に1フレームにつき1つづつぐらい?)ようでした。なので、制御構文自体が強制的なループ脱出によって1フレーム1回しか動作してないのかな、と。
実際、消去フラグを立てなければ、当然構造体は消去されませんでした、ガクつくことはありませんでした……。
問題部分のコードはこちらです。
bullet_t *RemoveList( bullet_t *p ){
if( head == p ) // 削除対象が head の場合、
{
if( head == head->next ) // 自分自身の循環参照(一つしかない)なら
{
delete p; // 削除
head = NULL; // head を NULL にする。
}
else // 二つ以上ある場合は
{
head = head->next; // head を次のデータにする。
}
}
if( head != NULL ) // head が NULL でない場合
{
bullet_t *ret = p->next; // 戻り値のための一時変数。
p->prev->next = p->next; // p の前の次を p の次に
p->next->prev = p->prev; // p の次の前を p の前に
delete p; // 削除
return ret; // 削除対象の次のデータを返す
}
return NULL; // データがないので NULL を返す。
}
void bullet_main()
{
int free_flag;
bullet_t *p = head;
if(p){
do{
//削除フラグの初期化
free_flag = 0;
//計算処理
p->x+=cos(p->angle)*p->spd;
p->y+=sin(p->angle)*p->spd;
p->cnt++;
//演出種類ごとの処理
switch(bullet->knd)//ここら辺は適当で
{
case 0:
if(削除する場合は)
free_flag = 1;
break;
}
if(free_flag != 0)
p = RemoveList(p); //削除
else
p = p->next;
}while(p != head);
}
}
移植する際に、どこか解釈を間違えてしまっているのでしょうか。
ずっと試行錯誤してみましたが、分かりませんでした。度々申し訳ありません;
>SCIさん
おお、仕事速いですね〜。
こちらのプログラムを使って、ちょっと色々ためしてみたいと思います!
まずはポインタが正しく理解できるようにならないとなぁ……。
1,207ポイント を落としてしまった。
|
|
|
|
|
Name: 御津凪 [URL] ..熟練のプログラマー(63,398ポイント)
Date: 2009/02/26(木) 16:39
No:29457
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
(上記のコードを実行できる環境でないので)頭の中でデバッグしていたところ、
先頭(head)のデータが削除される時にループを抜けてしまうようですね。
こちらが用意したコードにバグがあったということです。
すみません。
具体的な現象ですが、
・head を RemoveList 関数で削除
・head が一つ先にずれる
・削除されるのは元 head だったデータ
・その次が head なので、この状況に削除対象データは末尾データと同義になる。
・返されるデータは head になる。
・結果、while から抜ける
といった感じです。
対処としては以下の三箇所を修正してください。
void bullet_main()
{
int free_flag;
bullet_t *p = head;
bullet_t *top;
if(p){
do{
top = head; // 先頭位置の参照を保持
//削除フラグの初期化
free_flag = 0;
//計算処理
p->x+=cos(p->angle)*p->spd;
p->y+=sin(p->angle)*p->spd;
p->cnt++;
//演出種類ごとの処理
switch(bullet->knd)//ここら辺は適当で
{
case 0:
if(削除する場合は)
free_flag = 1;
break;
}
if(free_flag != 0)
p = RemoveList(p); //削除
else
p = p->next;
}while(p != top);
}
}
削除処理中に head が変わってもいいように一時変数に保持し、その変数で比較しています。
175ポイント を手に入れた。
|
|
|
|
|
Name: 桃印 ..初心者(5,671ポイント)
Date: 2009/02/26(木) 16:53
No:29458
| 解決!
|
Title: Re:自己参照構造体のリスト処理について
|
|
御津凪さん、回答ありがとうございました!
早速コードを組み込んでみました。確かにカクつかず動作します。が、ショットが全て消えた瞬間にアクセス違反が発生しました。
たぶん最後の最後でtopに空っぽのポインタが入ったんじゃ、と思ったのでtop = head;の直後にif(top == NULL) break;を入れてみたところ、アクセス違反は発生しませんでした。描画・カウント数も正しいものでしたし、メモリリークも発生していませんでした(連続的に発生させてる最中に、タスクマネージャでプログラムの使用メモリがばこばこ増えなかったら大体オッケーでいいんですよね?)。
ともあれこれで無事リスト構造は完成だと思います。
何だかほとんど皆さんのお力に頼りきりになってしましましたが、教えていただいたことを参考にさらに勉強していきたいと思いますので、今後また何かあればよろしくお願いいたします。
でわでわ。
212ポイント を手に入れた。
|
|
|
|
|
Name: 御津凪 [URL] ..熟練のプログラマー(63,563ポイント)
Date: 2009/02/26(木) 17:14
No:29463
|
|
Title: Re:自己参照構造体のリスト処理について
|
|
> 最後の最後でtopに空っぽのポインタが入ったんじゃ
その通りでしたね。やはり脳内デバッグでは無理があったかなと。
> 連続的に発生させてる最中に、タスクマネージャでプログラムの使用メモリがばこばこ増えなかったら大体オッケーでいいんですよね?
大体大丈夫でしょう。
ちなみに、メモリリークが発生しているかチェックする関数が VC++ にあります。
<crtdbg.h> をインクルードし、
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
を起動直後に読み出すことで、終了時にメモリリークの発生状況を出力ウインドウに出すことが出来ます。
ただ、どのタイミングでメモリリークが発生したかまでは分かりませんが…。
165ポイント を手に入れた。
|
|
|
|
|
Name: 桃印 ..初心者(5,954ポイント)
Date: 2009/02/26(木) 17:25
No:29464
| 解決!
|
Title: Re:自己参照構造体のリスト処理について
|
|
いやはや、あれだけのことをちゃちゃっとやってのけるのには憧れます。
私も勉強しないとなーorz
>_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF);
ほうほう、そんな機能もあるのですね。安全に遊んでいただくためにもメモリリークは起こしたくないバグなので、これらを使って注意深く作業していきたいと思います。
しっかし、まだ半分もできてないSTGなのにメモリ使用量は東方風神録の二倍…一体どんなマジックを使ってるんでしょうかねぇ。弾やエフェクトなど数用意するものをリスト構造に置き換えて、背景などはステージごとに別個で読み込むぐらいしかメモリの節約方法を思いつきませんw
皆さんありがとうございました!
283ポイント を手に入れた。
|
|
|
|
Name: ひよこ ..中級者(14,500ポイント)
Date: 2009/02/26(木) 13:27
No:29442
|
|
Title: かんたんな横スクロール
|
|
画像が動いたらスクロールする。そんなかんたんな横スクロールを作りたいのですが、本家のスクロールはわかりにくくて、単純に横に動いたらスクロールする。をつくるにはどうすればいいでしょうか?
2倍のポイントを手に入れた! 108ポイント を手に入れた。
|
|
|
Name: あまぞん ..ぴよぴよ(152ポイント)
Date: 2009/02/25(水) 02:44
No:29295
|
|
Title: 可変長引数を表示するプログラムでのコンパイルエラー
|
|
#include <stdio.h>
#include <stdarg.h>
void sub(char a[3],int b, ...);
int main(void)
{
sub("abc",4,9,6);
return 0;
}
void sub(char a[3],int b, ...)
{
va_list va;
int i;
va_start(va,b);
for (i = 0;b[i] != '\0';i++){ /*ここのb[i] != '\0'がいけないんだと思う*/
printf("%d\n",va_arg(va,int));
}
va_end(va);
}
エラーメッセージ
エラー E2062 va_arg.c 20: 無効な間接参照(関数 sub )
使用OS:Windows XP SP3
使用コンパイラ:borland C++ Compiler
タイトルの通り、可変長引数を表示したいのですが、うまく表示できません。
***************************
4
9
6
***************************
みたいな感じに表示させたいです。
できればですが、なぜエラーになるか教えてほしいです。
いろいろすみません。。。
152ポイント を手に入れた。
|
|
|
|
Name: toyo ..プログラマー(26,403ポイント)
Date: 2009/02/25(水) 08:56
No:29298
|
|
Title: Re:可変長引数を表示するプログラムでのコンパイルエラー
|
|
引数の個数を渡さないと引数が何個あるかを関数側では知ることが出来ませんよ
#include <stdio.h>
#include <stdarg.h>
void sub(char a[3],int num, ...);
int main(void)
{
sub("abc",3,4,9,6);
return 0;
}
void sub(char a[3],int num, ...)
{
va_list va;
int i;
va_start(va,num); /* numは引数の個数 */
for (i = 0;i < num;i++){
printf("%d\n",va_arg(va,int));
}
va_end(va);
}
171ポイント を手に入れた。
|
|
|
|
|
Name: non ..プログラマー(37,969ポイント)
Date: 2009/02/25(水) 09:02
No:29300
|
|
Title: Re:可変長引数を表示するプログラムでのコンパイルエラー
|
|
>引数の個数を渡さないと引数が何個あるかを関数側では知ることが出来ませんよ
もしくは、リストの最後に終わりの印をつけることですね。例えば9999とか
sub("abc",4,9,6,9999);
"abc"は使ってないけど何?ここをprintfのように
"%d%d%d"みたいにして個数を知ることもできますね。
136ポイント を手に入れた。
|
|
|
|
|
Name: toyo ..プログラマー(26,455ポイント)
Date: 2009/02/25(水) 09:07
No:29301
|
|
Title: Re:可変長引数を表示するプログラムでのコンパイルエラー
|
|
nonさんの回答を見てひょっとして
va_start(va,a);
for (i = 0;a[i] != '\0';i++){
みたいなことがやりたかったのでしょうか
52ポイント を手に入れた。
|
|
|
|
|
Name: non ..プログラマー(38,013ポイント)
Date: 2009/02/25(水) 09:24
No:29304
|
|
Title: Re:可変長引数を表示するプログラムでのコンパイルエラー
|
|
ああ、なるほど。。。。。
"abc"ってそういうことですか?
2倍のポイントを手に入れた! 44ポイント を手に入れた。
|
|
|
|
|
Name: 初級者 ..入門者(4,129ポイント)
Date: 2009/02/25(水) 09:47
No:29305
|
|
Title: Re:可変長引数を表示するプログラムでのコンパイルエラー
|
|
可変長引数を指定できる代表格のprintf関数で
引数の個数を渡さずにすんでいることから見て、「引数の個数が必要」という指摘は的はずれだと思います。
それよりは、3バイト確保した領域に
"abc" という、終端の '\0' を含む4バイトを渡している方が
よほど問題かと。
28ポイント を手に入れた。
|
|
|
|
|
Name: Mist ..熟練のプログラマー(52,185ポイント)
Date: 2009/02/25(水) 10:07
No:29306
|
|
Title: Re:可変長引数を表示するプログラムでのコンパイルエラー
|
|
> 引数の個数を渡さずにすんでいることから見て、「引数の個数が必要」という指摘は的はずれだと思います。
そんなことはないです。
printfは例えば"%d %d\n"のように書式指定文字列の内容から引数の個数を判断しています。
va_argは引数の数以上に実行すると予測しないエラーを起こすため今回のようなやり方をする場合は引数の個数は必要です。
nonさんがおっしゃられているように終りがわかる印を付けるなどしなければならないでしょう。
122ポイント を手に入れた。
|
|
|
|
|
Name: Mist ..熟練のプログラマー(52,332ポイント)
Date: 2009/02/25(水) 10:18
No:29308
|
|
Title: Re:可変長引数を表示するプログラムでのコンパイルエラー
|
|
ためしに以下のようなプログラムを組んでみてください。
int main(void) {
printf("%d %d\n", 10);
return 0;
}
コンパイルエラーにはならず、2個目は不定値が表示されます。
つまり、実際に渡した引数は1個ですがprintfは渡された引数は2個だと判断して動作しています。
147ポイント を手に入れた。
|
|
|
|
|
Name: toyo ..プログラマー(26,480ポイント)
Date: 2009/02/25(水) 12:03
No:29316
|
|
Title: Re:可変長引数を表示するプログラムでのコンパイルエラー
|
|
関数の引数の char a[ 3 ] は char* a になるので実害はないですよね
可変引数は型と個数が合わないとバグになるし関数側で型を知ることが出来ないのであまりよくないんですよね
25ポイント を手に入れた。
|
|
|
|
|
Name: 初級者 ..入門者(4,199ポイント)
Date: 2009/02/25(水) 12:28
No:29319
|
|
Title: Re:可変長引数を表示するプログラムでのコンパイルエラー
|
|
私のようなうつけ者が差し出がましいことを申しまして失礼しました。
2倍のポイントを手に入れた! 70ポイント を手に入れた。
|
|
|
|
|
Name: 通りすがり ..中級者(14,329ポイント)
Date: 2009/02/26(木) 09:15
No:29433
|
|
Title: Re:可変長引数を表示するプログラムでのコンパイルエラー
|
|
みんなミスリーディングされすぎです。
可変長引数とか関係ないよ。
int b に対して b[i]なんてやってるから文句言われてるだけでしょ。
2倍のポイントを手に入れた! 140ポイント を手に入れた。
|
|
|
|
|
Name: TOMONORI ..かけだし(2,289ポイント)
Date: 2009/02/26(木) 13:32
No:29443
|
|
Title: Re:可変長引数を表示するプログラムでのコンパイルエラー
|
|
char a[3] → const char *
として下さい。
それからbの値は通常引数の数を格納するものなので、vaはbの次の要素から
ポイントします。構造上bの値は引数の数でなければならないという制限は無い為
無視しても動くことは動きます。しかしそのコードはよーく隠して下さい。
渡された引数はいったん何らかのコンテナ(今回ならベクタで十分)に格納すると
良いと思います。
#include <stdio.h>
#include <stdarg.h>
#include <vector>
void sub(const char *, int b, ...);
int main() // Cではないのでvoidは書かない
{
sub("abc", 1, 9, 6);
return 0;
}
void sub(const char * s, int b, ...)
{
va_list va;
va_start(va, b);
std::vector<int> v;
v.push_back(b);
while(v.size() < sizeof(s) - 1) // 改行コードの分-1
{
v.push_back(va_arg(va, int));
}
for(std::vector<int>::iterator i = v.begin();
i < v.end();
++ i)
{
printf("%d\n", *i); //! std::coutの方が柔軟
}
}
可変長引数の型は組み込み型以外は未定義っぽいので気をつけて下さい。
逆に組み込み型なら安全に動作するらしいです(JISX3010参照)。
363ポイント を手に入れた。
|
|
|
|
Name: TH ..かけだし(1,244ポイント)
Date: 2009/02/25(水) 21:29
No:29384
|
|
Title: 永夜抄の使い魔のような物の作り方
|
|
毎度毎度質問ばかりで申し訳ございません…
例によって永夜抄での使い魔らしきものを作ろうと思ったのですが
足掻いてもできなかったので再びご教授願おうと思ってきた次第であります。
龍神録プログラミングの館26章から以下のように改変してきたのですが…。
1・使い魔の構造体を作る(内容はフラグ、x座標、y座標)
*SERVANT_MAX(定数10)によって10個ほど作りました。
2・関数search_servantで空き番号を探させる
使い方はsearch_boss_shotなどと同じで手当たり次第空き番号を探し、
空いていた番号を返り値として渡します
3・関数(void)summonと(int)summon_callで呼べるようにする
input_phy関数とinput_phy_pos関数が非常に便利そうだったのでやろうと思ったのですが…
summon_call(double x,double y)と呼び出すことでフラグを1にし、x座標をx,y座標をyに設定します。
summon_callの中で関数summonを実行するだけで返り値は求めてません。
さて、問題なのは2と3を如何につなぐか、ということです。
一つだけ出すのならsummon_callだけでどうにかなるのですが、
二つ以上出す場合、どうしていいのか分からなくなってしまいます。
拙い文章で分かりにくい点が多いと思いますが
ご指導お願いします・・・
519ポイント を手に入れた。
|
|
|
|
Name: BEMANI ..上級者(16,093ポイント)
Date: 2009/02/25(水) 22:04
No:29392
|
|
Title: Re:永夜抄の使い魔のような物の作り方
|
|
>>THさん
永夜抄やっておいてなんですが、
使い魔と言うのが良く分からないのでイメージできませんでした;
それは置いといて、気になったので質問なのですが、
「一つの使い魔を呼ぶ場合」と「二つ以上の使い魔を呼ぶ場合」の違いと言うのは何でしょうか?
配列の空きを検索して、空きがあるのなら summon_call を呼び出し、
フラグを立て、x, y座標を設定するのですよね?
二つ以上でも変わらないように感じるのですが、なにか特別な設定がいるのでしょうか;
それと、summon_callの中で呼ばれる関数、summonとは具体的に何をするのでしょうか?
特にこちらが解らなくても大丈夫な関数でしょうかね;
理解力乏しくて申し訳ないです;
2倍のポイントを手に入れた! 88ポイント を手に入れた。
|
|
|
|
|
Name: TH ..かけだし(1,742ポイント)
Date: 2009/02/25(水) 22:32
No:29397
|
|
Title: Re:永夜抄の使い魔のような物の作り方
|
|
>>BEMANIさん
使い魔…ボスが出してくる高速時は丸い玉、低速時には魔方陣のような姿をしている物体です。
ボスとは別に弾を撃ってくるやつですね。
試行錯誤を重ねたらややこしくなってしまい、初期の質問と条件が違うのですが…
一つの使い魔を出す場合、servant[n](コレは構造体、.x や .flagに続く)のnの中が
一つに固定されるのでsummon_call(x,y)で呼び出した後、
boss_shot.bullet[k].x boss_shot.bullet[k].y(龍神録プログラムより、弾の初期位置)にservant[n]の
x座標、y座標を入れることで、そこから弾を出すことができます。
一方で二つ以上の使い魔を出す時、servant[n]のnは(二つ出す場合は)0と1の二つに分かれます。
少し話が離れますが
summon_call(x,y)ではservant[n]のフラグを1(オン)にし、
summon(double x,double y,int n)を呼び出します。
このsummonの中のxはsummon_callのx、yはsummon_callのy、nはsearch_servantで空いていた番号で、
summon関数ではservant[n]のx座標、y座標にsummon_call(x,y)を呼び出したときに使ったx,yを代入します。
他にやり方がわからないので二つ以上呼び出すときには例として以下のようにします
summon(FX+10,ch.y); (画面左端で自機と同じ高さ)
summon(FMX-10,ch.y); (画面右端で自機と同じ高さ)
二つ並べて書いています。(コレでいいのかさえ分からない…)
summonでの返り値をn(空いているservant[n]のnの値)とし、
boss_shot.bullet[k]のx座標、y座標にservant[n]を指定した時、二つ並べて書いているために
下のsummon(FMX-10,ch.y)の返り値だけが適用されるため、弾の発射場所がすべて右側になってしまいました…。
と、カッコで補足を加えて結局グダグダになってしまったのですが…。
質問をまとめると
・二つ以上のservant[n]が存在するとき、boss_shot.bullet[k]のx座標、y座標を二つのservant[n]にあわせたい。nの値をどうすればいいか。
ということです…。
前回の投稿で弾を出したいと書いてなかったのでまったく違う質問になってしまった気がします。
本当に申し訳ございません…
498ポイント を手に入れた。
|
|
|
|
|
Name: yu [URL] ..上級者(18,108ポイント)
Date: 2009/02/26(木) 00:03
No:29409
|
|
Title: Re:永夜抄の使い魔のような物の作り方
|
|
自分が作成したものでは
boss_shotの構造体の中に
bullet_t assist[BOSS_ASSIST_MAX];
を追加して弾のように軌道を計算しました。
物理的に動かす場合は
input_phy関数に登録番号を渡してやればできました。
高速か低速かで変化させたいのであれば、キャラが高速中のときは1になる変数を作って
アシストに当たり判定をつけてやればいいと思います。(あと、弾の種類の変更も
array様の龍神録の支館の
「アシストを作ってみる」
が参考になると思いますので、是非一度見られてはいかがですか?
32ポイント を手に入れた。
|
|
|
|
|
Name: BEMANI ..上級者(17,569ポイント)
Date: 2009/02/26(木) 01:08
No:29415
|
|
Title: Re:永夜抄の使い魔のような物の作り方
|
|
>>THさん
あの透明になるやつですか・・・(合ってるかな)
やりたいことってこの、添付ファイルのようなもので合ってますか?
そうであるという前提でお話します。
↓サンプルソースを書いていました
//************************************************************
// 使い魔を生成し、その作成された番号を返す
// 引数 : なし
// 戻り値 : 生成された使い魔の番号
//************************************************************
int GetCreateServent(void)
{
for(int n=0; n<使い魔の最大数; n++)
{
if(配列が空いていれば)
{
使い魔を生成する();
return n;
}
}
return 使い魔の最大数+1; // 配列に空きがなかった
}
//************************************************************
// 使い魔の位置に弾を生成する
// 第一引数 : 生成された使い魔の番号
// 戻り値 : なし
//************************************************************
void SetServentBullet(int n)
{
for(int k=0; k<弾の最大数; k++)
{
if( boss_shot_bulletの空きを検索する() && n<使い魔の最大数 )
{
// 配列が空いていれば弾の座標を使い魔の位置へ格納
boss_shot_bullet[k].x = servent[n].x;
boss_shot_bullet[k].y = servent[n].y;
}
}
}
あとは、下のように呼ぶだけで、
使い魔を生成し、弾の座標が使い魔の位置になります。
SetServentBullet(GetCreateServent());
SetServentBullet()の引数が、GetCreateServentの戻り値です。
この戻り値と言うのは、上にも書いてますが使い魔が生成された番号です。
その番号を元に、servent[n].x と servent[n].y を弾の座標に格納します。
後はこの弾を動かせば、使い魔から弾発射されたようになると思います。
注意としては、使い魔が生成された瞬間、弾がセットされるということです。
時間をおいて発射させたいなら、別途THさんで拡張させてみて下さいませ。
こんなので大丈夫でしょうか・・・?
2倍のポイントを手に入れた! 1,476ポイント を手に入れた。
|
|
|
|
|
Name: めいらる ..かけだし(1,647ポイント)
Date: 2009/02/26(木) 05:30
No:29430
|
|
Title: Re:永夜抄の使い魔のような物の作り方
|
|
私は敵機の構造体をそのまま使い魔にも使えるようにしてますね。行動パターンも敵と同じように設定できます
「コースに敵機を配置する関数」があるのですがそれをちょっといじって「敵が敵を配置する関数」みたいにしてます
敵機と使い魔はお互いの構造体配列ポインタを持っているのでどちらかが消えたら両方消えるとか、敵の周りを使い魔が回転するといったことも可能です
使い魔も敵機なのでHPの設定や射撃、当たり判定のサイズや有無も自由です
私のコードは龍神録とはまったく違う形になっていると思うので概念だけ説明させていただきました…^^;
258ポイント を手に入れた。
|
|
|
|
|
Name: TH ..かけだし(2,159ポイント)
Date: 2009/02/26(木) 11:12
No:29438
| 解決!
|
Title: Re:永夜抄の使い魔のような物の作り方
|
|
>>yuさん
支館があっただなんて…!
なるほど、弾のように計算する方法があったとは…
ご回答ありがとうございました。
>>BEMANIさん
戻り値で使い魔の番号を指定できましたか…
言われてみれば他の処理でもそうなっているみたいですね…
わざわざサンプルまで作っていただきありがとうございました。
>>めいらるさん
「敵が敵を配置する関数」…非常に便利そうですけど
そんな事ができる技術は無さそうですorz
ですが考え方としては非常に有用そうです。いづれそのような物を作ってみたいですね…
ご回答、ありがとうございました。
皆様のおかげで無事解決できました。感謝します。
224ポイント を手に入れた。
|
|
|
|
Name: dic ..中級者(14,306ポイント)
Date: 2009/02/25(水) 20:39
No:29376
|
|
Title: 初歩的な質問ですが
|
|
#include <stdio.h>
#include <string.h>
class Task
{
char str[80];
public:
static void Run();
void push();
};
void Task::push() { strcpy( str, "test" ); }
void Task::Run() { printf( "Run - %s\n", str ); }
void main()
{
}
上記のソースをコンパイルすると
error C2597: 'Task::str' : スタティック メンバ関数内の不正なデータ メンバへの参照です
とコンパイルエラーがでます
static 関数から Taskクラスのメンバ変数にアクセスするにはどうすればよいのでしょうか?
char str[80]; を public にしてもダメでした
使用コンパイラ VC++6,0 です
96ポイント を落としてしまった。
|
|
|
|
Name: SCI ..中級者(9,038ポイント)
Date: 2009/02/25(水) 20:51
No:29377
|
|
Title: Re:初歩的な質問ですが
|
|
静的メンバ関数は、オブジェクトを実体化しなくても実行できるので、実体が作られなければ存在しないメンバ変数にアクセスできません。
どうしてもアクセスしたい場合、メンバ関数のポインタを介する方法があります。
56ポイント を手に入れた。
|
|
|
|
|
Name: dic ..中級者(14,586ポイント)
Date: 2009/02/25(水) 21:27
No:29383
|
|
Title: Re:初歩的な質問ですが
|
|
#include <stdio.h>
#include <string.h>
class Task
{
char str[80];
void (Task::*func1)();
void (Task::*func2)();
void push();
void print();
public:
static void Run();
void Init();
};
void Task::push(){
strcpy( str, "test" );
}
void Task::print(){
printf( "%s\n", str );
}
void Task::Run() {
func1(); // error C2064
func2(); // error C2064
}
void Task::Init(){
func1 = &Task::push;
func2 = &Task::print;
}
void main()
{
Task *task = new Task;
task->Init();
task->Run();
delete task;
}
上記のようにしましたがコンパイルエラー
error C2064: 関数ポインタとして評価されない式を使って、関数を呼び出そうとしました。
とでます
どのように関数ポインタを呼び出せばよいのでしょうか?
280ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(321,893ポイント)
Date: 2009/02/25(水) 21:39
No:29388
|
|
Title: Re:初歩的な質問ですが
|
|
>どのように関数ポインタを呼び出せばよいのでしょうか?
Run関数が staticでなければ、
(this->*func1)();
(this->*func2)();
でいいのですが、staticがついているので、どのインスタンスでそのメンバ関数を呼び出すのかを
決めないと……。
つまり、Run関数から staticを外すか、Run関数の引数に Taskクラスのポインタが参照を
渡せばいいのではないか、と思います。
48ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..中級者(9,426ポイント)
Date: 2009/02/25(水) 21:51
No:29389
|
|
Title: Re:初歩的な質問ですが
|
|
dicさん
関数ポインタはなんか別の件と混同してました・・・
で、ちょっと実験してみたんですが、やはり、どこかで実体を作るより方法はないでしょう。
74ポイント を手に入れた。
|
|
|
|
|
Name: dic ..中級者(14,708ポイント)
Date: 2009/02/25(水) 21:56
No:29390
|
|
Title: Re:初歩的な質問ですが
|
|
Justyさん回答ありがとうございます
そうなんですよ 他の方のソースを見ていてて気になったもので 改良もかねていじっていたのです
そこで私が本で学んでいない static メンバ関数が使われていたので
メンバ関数を static にする理由がしりたいのです
なので Justyさんのおっしゃるとおり static 修飾しをはずせばコンパイルが通るのですが
staticメンバ関数にすることにより発生する利点とは何でしょうか?
122ポイント を手に入れた。
|
|
|
|
|
Name: dic ..中級者(14,806ポイント)
Date: 2009/02/25(水) 22:00
No:29391
|
|
Title: Re:初歩的な質問ですが
|
|
SCIさん回答ありがとうございます
やはりコンストラクタを利用されますか
私にとって処理の流れのトレースが多少複雑になるのでスマートに書きたいのですが
ちょっとスレ違いしましたが、staticメンバ関数にする理由が知りたいのです
98ポイント を手に入れた。
|
|
|
|
|
Name: 御津凪 [URL] ..熟練のプログラマー(62,050ポイント)
Date: 2009/02/25(水) 22:14
No:29393
|
|
Title: Re:初歩的な質問ですが
|
|
> staticメンバ関数にすることにより発生する利点
たとえば、クラスで共有するデータ(これも static メンバ変数)の初期化や、
クラスメンバ関数や変数に依存しないが、クラス内でのみ使用する関数などがあります。
下記はぱっと思いついて考えた使用例です。
class Resource {
public:
Resource( int data ):mData(data){++sCount;}
~Resource( void ){--sCount;}
int GetData( void )const{return mData;}
void SetData( int data ){mData = data;}
static int GetResouceCount( void ){return sCount;}
private:
static int sCount;
int mData;
};
int Resource::sCount = 0;
Resource クラスを精製するたびに sCount が増加し、開放するたびに sCount が減少します。
Resource::GetResouceCount 関数を呼ぶことで、現在の Resource インスタンスの数を返します。
そんな感じのものです。
173ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(322,165ポイント)
Date: 2009/02/25(水) 22:22
No:29395
|
|
Title: Re:初歩的な質問ですが
|
|
>staticメンバ関数にすることにより発生する利点とは何でしょうか
インスタンスを生成することなく使えるので、
名前空間の代わりに使われたり、何かの理由でコンストラクタを
隠蔽したいときとか、自分自身の生成したりとか。
ぱっと思いついた例をあげると、
// 日付クラス
class Date
{
int year_, month_, day_;
public:
Date(int year, int month, int day);
static Date Today(); // 今日の日付を返す
int Year() const;
int Month() const;
int Day() const;
};
とか。
272ポイント を手に入れた。
|
|
|
|
|
Name: dic ..中級者(14,991ポイント)
Date: 2009/02/26(木) 06:26
No:29431
| 解決!
|
Title: Re:初歩的な質問ですが
|
|
>御津凪さん Justyさん 回答ありがとうございます
なるほど オブジェクトのカウンタに使ったり 名前空間に使ったりするんですね
後々にはちょっと応用が必要になってくるかもしれないですね
staticメンバ関数の仕組みを使って処理する必要は
今のところあまり感じられません
使われる人は使うのでしょうが
実体がなくても実行できるという点は初耳でした
ありがとうございました
185ポイント を手に入れた。
|
|
|
|
Name: AC ..初心者(5,517ポイント)
Date: 2009/02/25(水) 12:07
No:29317
|
|
Title: fstreamの効率のいい使い方
|
|
どうも御世話になっております。
とりあえずソースからいきます。
#include <tchar.h>
#include <windows.h>
#include <iostream>
#include <string>
#include <fstream>
// tchar.h 的に使えるようにする
#ifdef _UNICODE
#define _tcout std::wcout
#define _tstring std::wstring
#define _tfstream std::wfstream
#else
#define _tcout std::cout
#define _tstring std::string
#define _tfstream std::fstream
#endif
// prototype
void InsertText(_tstring dir, DWORD pos, _tstring txt);
// main
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
std::locale loc = std::locale();
loc = std::locale(loc, "japanese", std::locale::ctype);
std::locale::global(loc);
// テキストを任意の位置で追記
InsertText(_T("書き出し.txt"), 6, _T("test"));
return 0;
}
void InsertText(_tstring dir, DWORD pos, _tstring txt)
{
// ファイルストリーム
_tfstream fs(dir.c_str(), std::ios::in | std::ios::out);
// pos
_tfstream::pos_type insert_pos = pos;
// 一時的な保持用
_tstring str1, str2, tmp;
while(true)
{
fs >> tmp;
str1 += tmp;
if(fs.tellg() > insert_pos)
{
// pos位置までに削る
if(str1.size() > pos)
{
// char
str1 = str1.substr(0, pos);
}
else
{
// wchar_t
str1 = str1.substr(0, (DWORD)(pos/2));
}
// pos位置へ移動
fs.seekg(insert_pos);
while(!fs.eof())
{
// 終わりまで読み込む
fs >> tmp;
str2 += tmp;
}
break;
}
}
// debug
_tcout << str1 << txt << str2 << std::endl;
// 最初へ移動
fs.seekp(0, std::ios::beg);
fs << str1 << txt << str2 << std::endl;
}
少々長くなりましたが、テキストを任意の位置に追加(挿入)するようなプログラムを書いたつもりなのですが、debugと書いたcoutによる出力では、ちゃんとできていることが確認できるのですが、最後のfsによる書き込みが正常に出来ていないようです。
どこに問題があるのでしょうか?
それと、途中に挿入するような場合はわざわざこんな風にしないといけないのでしょうか?
もっと簡単にはできないのでしょうか(std::ios::appだと最後にしか書き込めないので…)?
効率のいい使い方等ありましたら、よろしくお願いします。
773ポイント を手に入れた。
|
|
|
|
Name: Mist ..熟練のプログラマー(52,403ポイント)
Date: 2009/02/25(水) 12:23
No:29318
|
|
Title: Re:fstreamの効率のいい使い方
|
|
preタグの中に文章を書く場合は自動改行されませんので適宜改行してください。
「少々長くなりましたが、〜」の行の後半が読めなくて質問内容がわかりません。
71ポイント を手に入れた。
|
|
|
|
|
Name: AC ..初心者(5,780ポイント)
Date: 2009/02/25(水) 12:29
No:29320
|
|
Title: fstreamの効率のいい使い方
|
|
あれ?
私の環境ではブラウザを小さくしても普通に見られるのですが。。。
preも閉じたはずです。
一応最後のところだけ再掲しておきます(適宜改行も入れておいたのでこれで大丈夫かな)。
(再掲)
少々長くなりましたが、テキストを任意の位置に追加(挿入)するようなプログラムを書いたつもりなのですが、
debugと書いたcoutによる出力では、ちゃんとできていることが確認できるのですが、
最後のfsによる書き込みが正常に出来ていないようです。
どこに問題があるのでしょうか?
それと、途中に挿入するような場合はわざわざこんな風にしないといけないのでしょうか?
もっと簡単にはできないのでしょうか(std::ios::appだと最後にしか書き込めないので…)?
効率のいい使い方等ありましたら、よろしくお願いします。
(ここまで)
ではよろしくお願いいたします。
263ポイント を手に入れた。
|
|
|
|
|
Name: Mist ..熟練のプログラマー(52,459ポイント)
Date: 2009/02/25(水) 12:55
No:29322
|
|
Title: Re:fstreamの効率のいい使い方
|
|
書き込めない原因は調査中です。
挿入については以下でいいと思います。
// 全部読みこんで
fs >> str1;
// 挿入
str1.insert(6, _T("test"));
56ポイント を手に入れた。
|
|
|
|
|
Name: GPGA ..熟練のプログラマー(58,266ポイント)
Date: 2009/02/25(水) 13:00
No:29323
|
|
Title: Re:fstreamの効率のいい使い方
|
|
質問内容とは別件ですが、tellgが返す値が文字数と同一の場合というのは
バイナリモードで開いたときのみで、テキストモード開いたときの値は環境依存になったはずです。
何をもって効率が良いと言うかによりますが
メモリに余裕があるのであれば、私なら
1:バイナリモードでファイルを開いてメモリに一括で読み込む
2:読み込んだデータをinsert_posまで書き込む
3:txtを書き込む
4:読み込んだデータをinsert_posから終端まで書き込む
5:ファイルを閉じる
とします。改行を1文字と考えないならば、2の前にinsert_posの値を修正します。
196ポイント を手に入れた。
|
|
|
|
|
Name: GPGA ..熟練のプログラマー(58,317ポイント)
Date: 2009/02/25(水) 13:07
No:29324
|
|
Title: Re:fstreamの効率のいい使い方
|
|
>>Mistさん
>fs >> str1;
ifstreamのoperator>>は改行があると、そこで読み込みを終了するので
この一文で全てを読み込むことはできません。
51ポイント を手に入れた。
|
|
|
|
|
Name: Mist ..熟練のプログラマー(52,512ポイント)
Date: 2009/02/25(水) 13:59
No:29329
|
|
Title: Re:fstreamの効率のいい使い方
|
|
すいません、コメントが悪かったですね。
方法説明ということでテキスト内の一行が挿入位置よりも長いという前提で簡易に書きました。
53ポイント を手に入れた。
|
|
|
|
|
Name: AC ..初心者(6,147ポイント)
Date: 2009/02/25(水) 14:22
No:29331
|
|
Title: Re:fstreamの効率のいい使い方
|
|
GPGAさん、Mistさんレスありがとうございます。
>1:バイナリモードでファイルを開いてメモリに一括で読み込む
>2:読み込んだデータをinsert_posまで書き込む
>3:txtを書き込む
>4:読み込んだデータをinsert_posから終端まで書き込む
>5:ファイルを閉じる
ですが、1の手順の良い方法が解らないのです。
getline()で読みこむのでしょうか?
でもgetlineの第一引数にstd::string(例のプログラムの場合_tstring)が使えれば一番なのですが、どうも使えないようなので
(試しにやってみたらwchar_t*に変換できないといわれたので)、
データサイズを取得して、その分をmallocでTCHAR*で確保して…という風にするしかなさそうなのですが、
もっと簡単にやる方法とかもあるのでしょうかね。
とりあえず、もうちょっと色々調べて検討してみます。
それと、
fs << str1 << txt << str2 << std::endl;
がうまく動作してない原因のわかる方がいましたら、そっちの方もよろしくお願いします。
367ポイント を手に入れた。
|
|
|
|
|
Name: AC ..初心者(6,296ポイント)
Date: 2009/02/25(水) 14:29
No:29332
|
|
Title: Re:fstreamの効率のいい使い方
|
|
連投すいません、ちょっとだけ補足です。
>質問内容とは別件ですが、tellgが返す値が文字数と同一の場合というのは
>バイナリモードで開いたときのみで、テキストモード開いたときの値は環境依存になったはずです。
についてですが、最初バイナリモードで開いて色々やっていて、途中で普通のテキストモードにしたら、エラーが出て
というようないきさつがありました。
ここら辺についてももうちょっと調べてみます。
何かありましたら回答のほどよろしくお願いします。
149ポイント を手に入れた。
|
|
|
|
|
Name: Mist ..熟練のプログラマー(52,594ポイント)
Date: 2009/02/25(水) 16:26
No:29340
|
|
Title: Re:fstreamの効率のいい使い方
|
|
str1 += txt + str2;
事前に結合してから出力するか
fs << str1;
fs << txt;
fs << str2;
分けて出力すれば動作しますね。
82ポイント を手に入れた。
|
|
|
|
|
Name: GPGA ..熟練のプログラマー(58,536ポイント)
Date: 2009/02/25(水) 20:52
No:29378
|
|
Title: Re:fstreamの効率のいい使い方
|
|
>ですが、1の手順の良い方法が解らないのです。
以下、一例です。
void InsertText(_tstring dir, DWORD pos, _tstring txt) {
std::ifstream ifs(dir.c_str(), std::ios::in | std::ios::binary);
ifs.seekg(0, std::ios::end);
std::vector<char> buf(ifs.tellg());
ifs.seekg(0, std::ios::beg);
ifs.read(&buf[0], buf.size());
ifs.close();
std::ofstream ofs(dir.c_str(), std::ios::out | std::ios::binary);
#ifdef _UNICODE
pos *= 2;
const unsigned long len = txt.length() * 2;
#else
const unsigned long = txt.length();
#endif
ofs.write(&buf[0], pos);
ofs.write((char*)txt.c_str(), len);
ofs.write(&buf[pos], buf.size() - pos);
}
219ポイント を手に入れた。
|
|
|
|
|
Name: AC ..初心者(6,601ポイント)
Date: 2009/02/26(木) 03:38
No:29428
| 解決!
|
Title: Re:fstreamの効率のいい使い方
|
|
みなさん回答再びありがとうございます。
>事前に結合してから出力するか
>分けて出力すれば動作しますね。
とのことですが、自分の環境では結局変わりませんでした(環境を書き忘れてましたがVistaでVC++2008EEです)。
とりあえず、ifstreamとofstreamに分ければ正常に読み書きできるのでそうしておきます。
>書き込み時にUNICODE対応してませんが、そこは流してください。
GPGAさんのソースを見ながら、かなりいろいろいじくってみましたが、結局のところtcharとの共存は
やめた方がいいっぽいですね…。実装があまりにめんどくさすぎるので。
それと、unicode対応させようとしたのですが、テキストファイルの文章がマルチバイトだと、
文字数取得が難しく無理でした。
(ifs.seekg(0, std::ios::end);でファイルサイズを取得できますが、
それが文字数と全然関係ないため最後にヌル文字が大量にでてしまったりしました。
また、文字列取得を ifs >> で取得する手も考えましたが、全角スペースとかがあると
そこで一旦読み込みが止まるので、最終的に改行になるなどして上手くいきませんでした。)
ということで、大体納得しましたので一応解決とさせていただきます。
(それにしてもファイルの途中への文字の追記というのはあまりしないのですかね。追記が最後尾しかできないというのは変なように思えるのですが…。
305ポイント を手に入れた。
|
|
|
|
Name: ぽてまよ ..ぴよぴよ(281ポイント)
Date: 2009/02/25(水) 23:08
No:29400
|
|
Title: 玉の発射について
|
|
こんばんわ、初めまして。
C言語を勉強し始めたばかりで、このHPを参考に簡単なシューティングゲームを作ってみてるのですが、玉の発射でつまずいてしまいました。
特にエラーなどはでないのですが、どこを変えればいいでしょうか。
アドバイスや、ご指摘などよろしくお願いします。
OS WindowsXP
コンパイラ VC++ 2008EE
#include "DxLib.h"
#define MAX_FIELD_X 550
#define MAX_FIELD_Y 450
#define MIN_FIELD_X 10
#define MIN_FIELD_Y 10
#define PLAYER_SPEED 2*2
struct PlayerData{
int x;
int y;
int image;
int flag;
};
//プロトタイプ宣言
void PlayerShot();
//グローバル変数
struct PlayerData player_move;
struct PlayerData player_shot;
int WINAPI WinMain(HINSTANCE hI,HINSTANCE hP,LPSTR lpC,int nC)
{
ChangeWindowMode(TRUE); //ウィンドウモードで起動
if(DxLib_Init()==-1)return(-1); //DXライブラリ初期化
player_move.image=LoadGraph("image/neko.png");
player_move.x=MAX_FIELD_X/2;
player_move.y=MAX_FIELD_Y;
player_shot.image=LoadGraph("image/shot.png");
SetDrawScreen(DX_SCREEN_BACK);
while(ProcessMessage()==0&&CheckHitKey(KEY_INPUT_ESCAPE)==0){
ClsDrawScreen();
//自キャラ移動
if(CheckHitKey(KEY_INPUT_RIGHT)>0)
{
if(player_move.x>=MAX_FIELD_X)
{
player_move.x=MAX_FIELD_X;
}
else {
player_move.x+=PLAYER_SPEED;
}
}
if(CheckHitKey(KEY_INPUT_LEFT)>0)
{
if(player_move.x<=MIN_FIELD_X)
{
player_move.x=MIN_FIELD_X;
}
else {
player_move.x-=PLAYER_SPEED;
}
}
DrawGraph(player_move.x,player_move.y,player_move.image,TRUE);
ScreenFlip();
}
DxLib_End();
return(0);
}
/*-------------------------------------------------------------------*/
/* プレイヤー攻撃 */
/*-------------------------------------------------------------------*/
void PlayerShot(){
//発射
if(CheckHitKey(KEY_INPUT_Z)>0)
{
if(player_shot.flag==0)
{
player_shot.flag=1;
player_shot.x=player_move.x-12;
player_shot.y=player_move.y+6;
}
}
if(player_shot.flag==1)
{
player_shot.y-=12;
DrawGraph(player_shot.x,player_shot.y,player_shot.image,TRUE);
if(player_shot.y<MIN_FIELD_Y)
{
player_shot.flag=0;
}
}
}
281ポイント を手に入れた。
|
|
|
|
Name: TH ..かけだし(1,913ポイント)
Date: 2009/02/25(水) 23:50
No:29406
|
|
Title: Re:玉の発射について
|
|
if(player_shot.flag==1) この時行われる移動に関する処理は
「player_shot.y-=12」これが一回だけです。
つまり、フラグが立っていたからといって何度も移動するわけではないんですね。
一度移動したあとに繰り返すような命令が無いため一度移動したらそれで終わりになっています。
while(player_shot.flag==1)
これをいれれば フラグが立っている間は処理を繰り返すために移動させられると思います。
一発しか撃てないのが問題であるならばplayer_shot[n]のようにplayer_shotを増やす必要がありますが…
171ポイント を手に入れた。
|
|
|
|
|
Name: BEMANI ..上級者(17,702ポイント)
Date: 2009/02/26(木) 01:47
No:29420
|
|
Title: Re:玉の発射について
|
|
>>ぽてまよさん
一応、何がどうなった、動かないのか・・・
という情報があれば凄く助かるかな〜と思われます。
次回質問時は「ここをこうしたけど、こうなりませんでした!」
という事を書いてみましょう><
で、問題ですが。
PlayerShot() が呼ばれていないようなので、
while(ProcessMessage()==0&&CheckHitKey(KEY_INPUT_ESCAPE)==0)
{
PleyrShot()をこの中に入れれば動くのではないかな・・・
}
>>THさん
PlayerShotを呼び出せば、一発だけ画面外に出るまで移動しますよ^^
192ポイント を手に入れた。
|
|
|
|
|
Name: ぽてまよ ..ぴよぴよ(435ポイント)
Date: 2009/02/26(木) 02:07
No:29424
| 解決!
|
Title: Re:玉の発射について
|
|
>>THさん
アドバイスありがとうございます!
今はとりあえず1発ずつでいいかなって思ってたので
数発打つようにしたいとき、配列にして試してみますね。
>>BEMANIさん
ご指摘ありがとうございました!
飛ばせるようになりました^^
まさかそんなことだったなんて思いませんでした・・・(汗
それから、掲示板の質問の仕方についてのアドバイスもありがとうございます。
次質問するときは、どんな状況かもう少し詳しく書こうと思います。
154ポイント を手に入れた。
|
|
|
|
Name: kayama ..かけだし(2,239ポイント)
Date: 2009/02/25(水) 17:19
No:29354
|
|
Title: 何故かフリーズします。
|
|
FF風のメッセージウィンドウを作成しようと思い以下の様なプログラムを組んだのですが。。
ファイル1
#include "DxLib.h"
extern void WndGrpPri(double,double,double,double);
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode( TRUE ) ;//ウィンドウモードに変更する関数
if( DxLib_Init() == -1 ) return -1;//初期化処理する関数
WndGrpPri(50,50,100,100);
WaitKey() ;//何か入力があるまで待つ関数
DxLib_End() ;//終了処理をする関数
return 0 ;
}
ファイル2
#include "DxLib.h"
#define COLOR_MAX 255
#define COLOR_PLU 1
void WndGrpPri(double X,double Y,double H,double W){
H += X;
W += Y;
double P = ( W - X ) / COLOR_MAX / COLOR_PLU ;
int color,var,cnt;
for (cnt=0 ; cnt < COLOR_MAX ; cnt+=COLOR_PLU ){
if (cnt<=COLOR_PLU*2) {
X++;
Y++;
H--;
W--;
var = (cnt - 1) * (cnt - 1) * -10 + 200;
color = GetColor(var,var,var);
}else{
H -= P;
Y += P;
color = GetColor(0,0,COLOR_MAX-cnt);
}
DrawBox (X,Y,W,H,color,TRUE);
WaitKey(); // 動作を確認するために毎回停止
}
}
何故かフリーズしてしまいます。
実行中に左下のバーの自動変数のところにcntが値が-858993460と出ています。
cntの値を直接変更しているのはfor文のパラメータのところだけなはずなのですが、何故こうなるのでしょうか?
522ポイント を手に入れた。
|
|
|
|
Name: kayama ..かけだし(2,012ポイント)
Date: 2009/02/25(水) 17:22
No:29355
|
|
Title: Re:何故かフリーズします。
|
|
void WndGrpPri(double X,double Y,double H,double W){
double P = ( W - X ) / COLOR_MAX / COLOR_PLU ;
H += Y;
W += X;
int color,var,cnt;
for (cnt=0 ; cnt < COLOR_MAX ; cnt+=COLOR_PLU ){
if (cnt<=COLOR_PLU*2) {
X++;
Y++;
H--;
W--;
var = (cnt - 1) * (cnt - 1) * -10 + 200;
color = GetColor(var,var,var);
}else{
H -= P;
Y += P;
color = GetColor(0,0,COLOR_MAX-cnt);
}
DrawBox (X,Y,W,H,color,TRUE);
WaitKey();
}
}
でした。
どちらにせよフリーズしますが。。
227ポイント を落としてしまった。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(65,336ポイント)
Date: 2009/02/25(水) 18:28
No:29366
|
|
Title: Re:何故かフリーズします。
|
|
フリーズっというか、キーを255回押すとWndGrpPri
をぬけて、(その間の暗くなり方がちょっと魅力的ですw)
もう一度キーを押すと終了っというプログラムですが・・・?(255+1回押すまでは終了しない)
本当はどういう動作を期待しているのでしょうか?
89ポイント を手に入れた。
|
|
|
|
|
Name: kayama ..かけだし(2,243ポイント)
Date: 2009/02/25(水) 18:42
No:29367
|
|
Title: Re:何故かフリーズします。
|
|
私の環境で実行すると何故かフリーズしてしまいます。。
実行直後急に重くなりウィンドウが消えてしまうので、
タスクバーから終了をすると
「このプログラムは応答していません。」
とでてしまいます。
ループ毎にWaitKey()を入れてるのは動作を確認するためです。
因みに本当は
┏━━━━━┓
┃メッセージ┃
┃ウィンドウ┃
┃(グラデ)┃
┗━━━━━┛
こんな感じに(分かりにくいですけど)ゲームウィンドウを作りたかったです。
フリーズさえなければ動作を改善できるのですがorz
まともに実行できないので成功してるのかどうかすら分かりません。。
231ポイント を手に入れた。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(65,748ポイント)
Date: 2009/02/25(水) 20:08
No:29374
|
|
Title: Re:何故かフリーズします。
|
|
自分の環境ではどこで止まっているのかがわからないので、
デバッグの際に、すべての行を見ていってください。
環境は何ですか?VC++ならブレークポイントがそれにあたります。
実行して反応がなかったらそこが原因です。
>実行中に左下のバーの自動変数のところにcntが値が-858993460と出ています
for文のcnt=0が実行されていない可能性がります。(あくまで可能性です。)
ちなみに、BrawBox()の第一〜四引数はint型です。
176ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(8,982ポイント)
Date: 2009/02/25(水) 20:21
No:29375
|
|
Title: Re:何故かフリーズします。
|
|
フリーズするのは、ProcessMessage()関数を呼んでいないからですね。
まずは、基本的なループを組んでから、中身を作っていくといいと思います。
50ポイント を手に入れた。
|
|
|
|
|
Name: kayama ..かけだし(1,716ポイント)
Date: 2009/02/25(水) 21:04
No:29380
|
|
Title: Re:何故かフリーズします。
|
|
>>kazuoniさん
int型にキャストしたらフリーズしなくなりました。
ありがとうございました。
>>SCIさん
そう言えばProcessMessageを忘れてました。
ちゃんと入れておきます。
ありがとうございました。
こんな感じになりましたがプログラムに問題はないでしょうか?
#include "DxLib.h"
extern int WndGrpPri(double,double,double,double);
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode( TRUE ) ;//ウィンドウモードに変更する関数
if( DxLib_Init() == -1 ) return -1;//初期化処理する関数
LoadGraphScreen( 0 , 0 , "test1.bmp" , TRUE ) ;//画像を表示する関数
WndGrpPri(50,50,100,100);
WaitKey() ;//何か入力があるまで待つ関数
DxLib_End() ;//終了処理をする関数
return 0 ;
}
#include "DxLib.h"
#define COLOR_MAX 255
#define COLOR_PLU 1
int WndGrpPri(double X,double Y,double H,double W){
double P = ( W - COLOR_PLU * 4 ) / COLOR_MAX * COLOR_PLU ;
double X2,Y2,W2,H2;
H += Y; W += X;
int color,var,cnt;
for (cnt=0 ; cnt < COLOR_MAX/COLOR_PLU ; cnt+=COLOR_PLU ){
if (ProcessMessage()){return -1;}
if (cnt<=COLOR_PLU*2) {
X++; Y++; H--; W--;
var = (cnt - 1) * (cnt - 1) * 10 + 200;
color = GetColor(var,var,var);
}else{
Y += P;
//H -= P;
color = GetColor(0,0,COLOR_PLU-cnt);
}
X2 = X; Y2 = Y; W2 = W; H2 = H;
DrawBox ((int)X2,(int)Y2,(int)W2,(int)H2,color,TRUE);
// WaitKey();
}
return 0;
}
527ポイント を落としてしまった。
|
|
|
|
|
Name: SCI ..中級者(9,171ポイント)
Date: 2009/02/25(水) 21:14
No:29381
|
|
Title: Re:何故かフリーズします。
|
|
これって、枠が出てグラデーションが内側に向かっていけばいいんですよね?
私もいろいろ考えてみましたが、DrawBoxで描画した矩形を保持しようとすると、どうしても方法が複雑になってしまいそうなんです。
(私の力不足・・・泣)
グラデーションを画像で用意すれば、もう少し単純な感じに出来そうなんですけど、このコードのように細かく指定できるほうがいいですか?
133ポイント を手に入れた。
|
|
|
|
|
Name: kayama ..かけだし(1,766ポイント)
Date: 2009/02/25(水) 21:23
No:29382
| 解決!
|
Title: Re:何故かフリーズします。
|
|
う〜ん。。強引すぎますかね。
一応結果さえ得られればいいのですが、この方法だと毎回描写するにも処理に時間がかかりますし、やはりグラデ画像を使うべきなんでしょうか。
50ポイント を手に入れた。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(65,723ポイント)
Date: 2009/02/25(水) 21:32
No:29385
|
|
Title: Re:何故かフリーズします。
|
|
まず、今後の為にも、裏描写のSetDrawScreen( DX_SCREEN_BACK )
を使うようにしたほうが良いと思います。
詳細は本家へ。
ttp://homepage2.nifty.com/natupaji/DxLib/function/dxfunc_graph.html#R4N6
なぜっと思ったらゲームプログラミングの館1〜13章までささっと読んでみてください。
http://dixq.net/g/#13
自分もやはりグラデーション画像を用意したほうが効率的かと思います。
何度も同じところを描写していることになるので、ちょっと非効率な気がします。
25ポイント を落としてしまった。
|
|
|
|
|
Name: SCI ..中級者(9,352ポイント)
Date: 2009/02/25(水) 21:34
No:29386
|
|
Title: Re:何故かフリーズします。
|
|
一応、想定しているような表示になるコードはかけたのですが、描画が一通り終わると、その後の更新がされないんです。
つまり、描画が終わった後は矩形が消されると再描画されなくなってしまいます。
画像の場合、同じドットを毎フレーム描画すればいいんですけど、今回の場合はそうはいかないかも知れません。
例えば、完成形のグラデーションを毎フレーム作るか、描画が終わった段階の矩形をそのままコピーしておくか・・・
181ポイント を手に入れた。
|
|
|
|
|
Name: kayama ..かけだし(1,848ポイント)
Date: 2009/02/25(水) 21:38
No:29387
|
|
Title: Re:何故かフリーズします。
|
|
>>kazuoniさん
アドバイスありがとうございます。
一度全部読み直して見ます。
>>SCIさん
やはり厳しいですよねorz
素直に画像を使うことにします。
82ポイント を手に入れた。
|
|
|
|
Name: ユカイ ..ぴよぴよ(381ポイント)
Date: 2009/02/25(水) 15:48
No:29334
|
|
Title: 敵キャラの増やし方
|
|
度々すみません。敵キャラの増やし方を教えていただけませんか?とりあえず、スタート時に6匹(人?)ほどいえて、捕まえるとフワっと消える感じで^^;
48ポイント を手に入れた。
|
|
|
|
Name: SCI ..初心者(8,635ポイント)
Date: 2009/02/25(水) 16:01
No:29336
|
|
Title: Re:敵キャラの増やし方
|
|
ざっとしか見ていませんが、以下の点を考えてみるといいかも知れません。
・複数の「敵データ(ch_t構造体)」は、配列で管理できそうです。
・配列にしたら、敵の移動処理や衝突判定はその数分、繰り返す必要があります。
それから、構造体を値渡ししている箇所がありますが、読み取り専用の場面においてもポインタ渡しで平気ですよ。
むしろ、値渡しより処理が高速になります(差はごく僅かですが)。
173ポイント を手に入れた。
|
|
|
|
|
Name: ユカイ ..ぴよぴよ(425ポイント)
Date: 2009/02/25(水) 16:30
No:29341
|
|
Title: Re:敵キャラの増やし方
|
|
ん〜〜 わかりませんね〜
単純にenemy2と増やしただけなんですが、エラーになります。
44ポイント を手に入れた。
|
|
|
|
|
Name: ユカイ ..ぴよぴよ(620ポイント)
Date: 2009/02/25(水) 16:46
No:29343
|
|
Title: Re:敵キャラの増やし方
|
|
z:\c言語\cpp_game\ch5\main.cpp(171): error C2065: 'enemy' : 定義されていない識別子です。
z:\c言語\cpp_game\ch5\main.cpp(171): error C2227: '->walking_flag' : 左側がクラス、構造体、共用体へのポインタではありません。型は ''unknown-type'' です。
z:\c言語\cpp_game\ch5\main.cpp(215): error C2065: 'enemy2_exist' : 定義されていない識別子です。
z:\c言語\cpp_game\ch5\main.cpp(220): error C2065: 'enemy2_image' : 定義されていない識別子です。
といった感じです。
195ポイント を手に入れた。
|
|
|
|
|
Name: ユカイ ..ぴよぴよ(597ポイント)
Date: 2009/02/25(水) 16:49
No:29344
|
|
Title: Re:敵キャラの増やし方
|
|
それでもって、ランダムに6匹の敵をマップに配置できればいいんですが・・・・
23ポイント を落としてしまった。
|
|
|
|
|
Name: SCI ..初心者(8,726ポイント)
Date: 2009/02/25(水) 16:56
No:29346
|
|
Title: Re:敵キャラの増やし方
|
|
ランダム配置は「乱数生成」の方法でできますよ。座標情報に乱数を使えばいいです。
ちょっとソースのコンパイルとか確認してみますねv
47ポイント を手に入れた。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(65,163ポイント)
Date: 2009/02/25(水) 16:58
No:29348
|
|
Title: Re:敵キャラの増やし方
|
|
作っておいた本人がいうのもなんですが・・・
このままだとこれから実装したいものすべてここで解決してもらう
ってなりそうです。
構造体、ポインタあたりの勉強は済まされました?
少なくとも変数宣言のところでは躓かないと思いますので。。
一度入門のページで
構造体
ポインタ(文字列操作)
あたりを勉強して、それからもう一度取り組んではどうですか?
>SCIさん
>構造体を値渡ししている箇所がありますが、読み取り専用の場面においてもポインタ渡しで平気ですよ。
高速化の面は知りませんでした^^;
ただ、「この引数は値変更はしないよ!」
っというのを明示したかっただけなんです。
っといいながらも、外部変数でキー監査してしまっているという矛盾・・・。w
やはりキー監査はクラス化したほうが無難な気がします。
260ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(8,910ポイント)
Date: 2009/02/25(水) 17:03
No:29351
|
|
Title: Re:敵キャラの増やし方
|
|
コンパイルしてみました。エラーの原因は全部「入力ミス」のようです(笑)
「ドット」が「アンダースコア」になってたり、「enemy2」と書くべきところを「enemy」と書いていたり、です。
kazuoniさん
私はまだ勉強中なので、あまり大げさに断言できませんが・・・
構造体や配列は、基本的に値渡しはしないと思います。
「値渡し」は、すなわち仮引数(関数定義のカッコの中の変数)に値をコピーすることなので、
サイズの大きい構造体や配列を渡すより、一定サイズのポインタ変数にするほうがいいみたいですよ。
184ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(8,932ポイント)
Date: 2009/02/25(水) 17:16
No:29353
|
|
Title: Re:敵キャラの増やし方
|
|
そしたら、constを使ってみたらどうでしょう?
ポインタ変数のコンストって混乱しがちですが、
const 型 *p;
は、実体が定数、
型 * const p;
とすると、アドレスが定数、という感じです。
22ポイント を手に入れた。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(65,136ポイント)
Date: 2009/02/25(水) 17:34
No:29357
|
|
Title: Re:敵キャラの増やし方
|
|
万事解決いたしました^^;
恥ずかしい限りです。。
const型じゃなくても関数の引数でconstにできたんですねw
今まで型の不一致と勝手に認識していました。。
これで自分の場合のメリットは0ですね^^;
関数中でconst_castしない限りは安全ですね。
#こんな自分が熟練のプログラマとは・・・w
129ポイント を落としてしまった。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(65,572ポイント)
Date: 2009/02/25(水) 19:12
No:29370
|
|
Title: Re:敵キャラの増やし方
|
|
一応参考までにサンプルは作りました。
今回はコメントは入れてないので、自分で解析してください。
この演算子なに?等はネット等で調べてください。
これで、基礎の勉強がはかどってもらえると何よりです。
っというのも、自分もゲームプログラミングの館から
C言語の基礎の勉強をし始めました。
こんな風にしたいんだけど、どうしたら?っと思うと
ポインタが絡んでいたり、ファイル出力が絡んでいたり、文字列だったり、配列だったり・・・
分からなくなったら基礎を勉強しなおして、再度挑戦っとしてました。
今現在でも自分は↑のレスのようにまだまだ初心者です。
やはり基礎が大事だと思います。
(っていいながらまだまだ自分も怪しいですが・・。)
がんばってください。
236ポイント を手に入れた。
|
|
|
|
|
Name: ユカイ ..ぴよぴよ(685ポイント)
Date: 2009/02/25(水) 19:17
No:29371
| 解決!
|
Title: Re:敵キャラの増やし方
|
|
本当に申し訳ないです。ありがとうございます。
教科書とか見ると、何をやっているのかはだいたいわかるんですが、いざ自分で作るとなるとできないんですよね・・・
67ポイント を手に入れた。
|
|
|
|
Name: hide ..ぴよぴよ(96ポイント)
Date: 2009/02/25(水) 16:57
No:29347
|
|
Title: 実行ファイルの作り方
|
|
ゲームプログラムを作ったのですが実行ファイルの作り方がわかりません。
プログラミングの舘のt4にあるように、exeファイルをつくるのでしょうか?
どなたかよろしくお願いします。
環境 windows vc2008 DXライブラリ
96ポイント を手に入れた。
|
|
|
|
Name: hide ..ぴよぴよ(147ポイント)
Date: 2009/02/25(水) 17:39
No:29358
|
|
Title: Re:実行ファイルの作り方
|
|
入っていましたが、実行しようとすると開けないと出ました。
何も知らない初心者でほんと申し訳ないです。
51ポイント を手に入れた。
|
|
|
|
|
Name: hide ..ぴよぴよ(192ポイント)
Date: 2009/02/25(水) 18:11
No:29362
|
|
Title: Re:実行ファイルの作り方
|
|
いや自分の勘違いだとおもうんでもう一度見てみます。
ほんとに申し訳ないです。
37ポイント を手に入れた。
|
|
|
|
|
Name: toyo ..プログラマー(26,523ポイント)
Date: 2009/02/25(水) 18:15
No:29363
|
|
Title: Re:実行ファイルの作り方
|
|
画像ファイルが開けないとかじゃないでしょうか
.exeと同じ場所に必要なファイルをコピーすればうまくいくことが多いです
43ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 ..ぴよぴよ(236ポイント)
Date: 2009/02/25(水) 18:19
No:29364
|
|
Title: Re:実行ファイルの作り方
|
|
実行ファイルを一つ上の階層にコピーして実行してみてください。
6ポイント を手に入れた。
|
|
|
|
|
Name: hide ..ぴよぴよ(233ポイント)
Date: 2009/02/25(水) 18:25
No:29365
|
|
Title: Re:実行ファイルの作り方
|
|
toyoさん返答ありがとうございます。
使っている画像は、全部同じ場所にあります。
もう一度自分で調べてみたいと思います。ありがとうございました。
41ポイント を手に入れた。
|
|
|
|
|
Name: 管理人 ..ぴよぴよ(293ポイント)
Date: 2009/02/25(水) 18:43
No:29368
|
|
Title: Re:実行ファイルの作り方
|
|
私の回答は・・^^;
きっとDebugフォルダかReleaseフォルダに生成されている実行ファイルをそのまま実行してるんだと思います。
プロジェクトと同じフォルダから実行しないとデータファイルなどの相対パスが狂うので
プロジェクトファイルがあるフォルダにコピーして実行してみてください。
普通ならひとつ上のフォルダにコピーすればOKです。
プロジェクトファイルを別のフォルダに作っている場合はその中に入れてください。
57ポイント を手に入れた。
|
|
|
|
Name: JT ..入門者(3,446ポイント)
Date: 2009/02/25(水) 13:45
No:29326
|
|
Title: MFC Winsockコントロール
|
|
こんにちは^^ 今MFC(VC++6.0)のWinsockソケットコントロール(高度な機能)を使用してサーバとクライアントを作成し実装しているのですが画面操作はできるのですが処理に難航しています、、どなたかサンプルを実装していただけたら幸いです(商業用ではありません、ネットでサンプルを検索してもありませんでした><) 恐縮なお願いですがお願いいたします
108ポイント を手に入れた。
|
|
|
|
Name: JT ..入門者(3,469ポイント)
Date: 2009/02/25(水) 13:52
No:29327
| 解決!
|
Title: Re:MFC Winsockコントロール
|
|
すみませんでした>< ここで書くことではない事ですよね 自力で頑張ります
23ポイント を手に入れた。
|
|
|
|
|
Name: バグ ..ハッカー(148,962ポイント)
Date: 2009/02/25(水) 13:57
No:29328
|
|
Title: Re:MFC Winsockコントロール
|
|
どの程度のレベルのものを求めているかにもよりますが、簡単なものでしたら、『MFC CSocket』でググったら、結構ヒットしましたよ(^-^)
40ポイント を手に入れた。
|
|
|
|
|
Name: JT ..入門者(3,599ポイント)
Date: 2009/02/25(水) 14:00
No:29330
|
|
Title: Re:MFC Winsockコントロール
|
|
ありがとうございます 画面的にはクライアントボタンとサーバボタンと中断ボタンがあり、それぞれの作業を一画面で作成したいんです。現在はサーバ側のListenで悩んでいます
2倍のポイントを手に入れた! 130ポイント を手に入れた。
|
|
|
|
|
Name: JT ..入門者(3,626ポイント)
Date: 2009/02/25(水) 17:29
No:29356
|
|
Title: Re:MFC Winsockコントロール
|
|
自力でやっていたのですが C2065エラーになってしまいます。 どなたかご教示ください
27ポイント を手に入れた。
|
|
|
|
Name: yama ..初心者(6,061ポイント)
Date: 2009/02/24(火) 19:30
No:29256
|
|
Title: 続「12.画像を動かす」の初期化
|
|
先ほど「12.画像を動かす」の初期化 のタイトルで質問したものです。
SCIさんのおかげで、二回目のプレイ時x=0からできるようになりましたが、
二回目のプレイ時、画面が明るく暗くなり次の画面にいけません。拙い文章
また続けて質問ですみませんが、どなたかよろしくお願いします。
環境 windoes vc2008 DXライブラリです。
#include "DxLib.h"
int function_status=0,White,Yellow,G_Blue,Red,c;
char KeyBuf[ 256 ] ;
int PointX = 0;
void Opening(){
SetFontSize( 30 ) ; //サイズを20に変更
SetFontThickness( 1 ) ; //太さを1に変更
ChangeFont( "HGS創英角ポップ体" ) ; //HGS創英角ポップ体に変更
ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE );//アンチエイリアス&エッジ付きフォントに変更
DrawString(50,300," PUSH Z KEY",GetColor(255,255,255));
if(KeyBuf[KEY_INPUT_Z]==1)
function_status=1;
}
void Menu(){
LoadGraphScreen( PointX , 350 , "囚人.png" , TRUE );
Yellow = GetColor( 255 , 255 , 0 ) ; // 赤色の値を取得
G_Blue = GetColor( 128 , 128 , 128 ) ; // 緑と青の混合色の値を取得
White = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
DrawBox ( 400 , 200 , 440 , 700 , G_Blue , TRUE ) ; // 四角形を描画(塗りつぶし)
DrawCircle( 550 , 30 , 30 , Yellow , TRUE) ; // 円を描画(塗りつぶし)
DrawString( 0, 0, "level 1" , White); //文字列表示
PointX++;
if(PointX==290)
function_status=2;
}
void Danjon(){
LoadGraphScreen( PointX , 350 , "囚人.png" , TRUE );
if(c>=0 && c<256) //cが0~256の時
SetDrawBright( c , c , c ); //段々あかるく(c= 0->255)
if(c>=256 && c<400) //cが256~400の時
SetDrawBright( 255 , 255 , 255 ); //通常の明るさ
if(c>=400 && c<400+256) //cが400~400+256の時
SetDrawBright( 255-(c-400) , 255-(c-400) , 255-(c-400) );//段々暗く(c= 255->0)
DrawBox( 0 , 0 , 640 , 480 , White , TRUE) ; //画面全体に白い四角形を描画
c+=3;
PointX++;
if(PointX==410)
function_status=3;
}
void attack(){
SetFontSize( 30 ) ; //サイズを20に変更
SetFontThickness( 1 ) ; //太さを1に変更
ChangeFont( "HGS創英角ポップ体" ) ; //HGS創英角ポップ体に変更
ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE );//アンチエイリアス&エッジ付きフォントに変更
DrawString(50,300," PUSH X KEY",GetColor(255,255,255));
if(KeyBuf[KEY_INPUT_X]==1)
function_status=0;
PointX=0;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode( TRUE ) ; //ウィンドウモードに変更
if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了
White = GetColor( 255 , 255 , 255 ) ; //色の取得
SetDrawScreen( DX_SCREEN_BACK ) ; // 描画先を裏画面に設定
while( 1 ){
ClearDrawScreen(); // 裏画面のデータを全て削除
GetHitKeyStateAll( KeyBuf ) ; // すべてのキーの状態を得る
switch(function_status){
case 0:
Opening();
break;
case 1:
Menu();
break;
case 2:
Danjon();
break;
case 3:
attack();
break;
default:
DxLib_End() ; // DXライブラリ使用の終了処理
return 0;
break;
}
if( ProcessMessage() == -1 ) break ; //エラーが起きたら終了
ScreenFlip() ; // 裏画面データを表画面へ反映
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
2,101ポイント を手に入れた。
|
|
|
|
Name: SCI ..初心者(8,462ポイント)
Date: 2009/02/24(火) 23:07
No:29285
|
|
Title: Re:続「12.画像を動かす」の初期化
|
|
まず、
if(KeyBuf[KEY_INPUT_X]==1)
function_status=0;
PointX=0; この部分、中括弧をつけるべきです(今回はなくてもたまたま上手くいきますが)。
それで、今回は、if(KeyBuf[KEY_INPUT_X]==1) {
function_status=0;
PointX=0;
c = 0;
} のように付け加えてみてください。
今回の件で薄々気づくかもしれませんが、「最初」に戻るときには使った変数の値は「最初」の状態に戻す必要があります。
変数は宣言時に初期化が出来ますが、今回のように何度も最初から繰り返す場合、初期化は初期化で実行できるようにするといいでしょう。
298ポイント を手に入れた。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(64,707ポイント)
Date: 2009/02/24(火) 23:35
No:29288
|
|
Title: Re:続「12.画像を動かす」の初期化
|
|
>画面が明るく暗くなり次の画面にいけません。
void Danjon()で使用しているcとは何ですか?
まずコンパイルすら通らないと思いますが・・・?
まず、しっかり宣言されているとしてですが。
Danjon()のSetDrawBright()で、暗→明→暗
として、最後Color(0,0,0)で終わっています。
これでは次の描写は真っ暗です。
輝度のデフォルトは255なので、
if(PointX==410)
{
function_status=3;
SetDrawBright(255,255,255)
}
としてみてください。
235ポイント を手に入れた。
|
|
|
|
|
Name: yama ..初心者(6,197ポイント)
Date: 2009/02/25(水) 16:20
No:29339
| 解決!
|
Title: Re:続「12.画像を動かす」の初期化
|
|
SCIさんkazuoniさん返答ありがとうございました。
問題解決しましたまた、勉強になりました。冷静に考えれば。。。という話しで恥ずかしい限りです。
今回は諸事情ではやく作りたかったので、みなさんの力をかりさしていただきました。
特にSCIさんありがとうございます。これからは、みなさんに頼るだけでなく、自分で解決できるよう
力をつけたいと思います。ありがとうございます。
136ポイント を手に入れた。
|
|
|
|
Name: TH ..ぴよぴよ(505ポイント)
Date: 2009/02/22(日) 00:03
No:29135
|
|
Title: error D8016「/MTd' と '/clr' は同時に指定できません」とエラーが出ます
|
|
以前もお世話になりました、THです。
例によって龍神録プログラムの館で記載されているプログラムを見ては
それを手打ちで入力している作業をしていたところ、このエラー
(error D8016 : コマンド ライン オプション '/MTd' と '/clr' は同時に指定できません)
が出てきました。
原因はfunc.hを作る際に、
1、ソリューションエクスプローラのソースファイルの上で右クリック
2、追加→新しい項目
3、func.hをファイル名として追加
という見当違いのことをやってしまった時に何かのエラーが出たのを適当にクリックして
やり過ごしてしまった事だと思います。
調べてみたところ、新しいプロジェクトを作成するとき「CLRコンソールアプリケーション」を選んでいたらしいのですが
(起こったエラーが同じで、何となく記憶にあるだけなので違うかもしれません)解決方法が載っていませんでした
。
プロパティを見てもランタイムライブラリは/MTdとなっています。
また、その後「ソースファイル」フォルダ内にできたfunc.hを右クリック→削除→削除と完全に削除したにもかかわらず直りません。
すごく初歩的なことのような気がしまうが、何卒力を貸していただきたいと思います。
505ポイント を手に入れた。
|
|
|
|
Name: cosmo ..入門者(2,978ポイント)
Date: 2009/02/22(日) 00:19
No:29137
|
|
Title: Re:error D8016「/MTd' と '/clr' は同時に指定できません」とエラーが出ます
|
|
新しいプロジェクトを作成する時、
CLRコンソールアプリケーションでは無く、
Win32アプリケーションを選択していますか?
↑この辺りに原因がありそうですが。
CLRコンソールアプリケーションではmain関数のプログラムを動かすことは出来ますが、
Winmain関数のあるプログラムを動かすことは出来ません。
153ポイント を手に入れた。
|
|
|
|
|
Name: TH ..ぴよぴよ(676ポイント)
Date: 2009/02/22(日) 00:35
No:29140
|
|
Title: Re:error D8016「/MTd' と '/clr' は同時に指定できません」とエラーが出ます
|
|
追記
手打ちしている作業〜 と書いてあったのにどこまで
進めたのか記載するのを忘れてました…
現在24章のボスのところです。
>>cosmoさん
私は新しいプロジェクトを作成するつもりは無かったのです…
原因となりそうな作ってしまったプロジェクトは削除したのに
既存のプロジェクトのビルドができなくなってしまったのです(このエラーのせいで)
171ポイント を手に入れた。
|
|
|
|
|
Name: cosmo ..入門者(3,089ポイント)
Date: 2009/02/22(日) 01:07
No:29141
|
|
Title: Re:error D8016「/MTd' と '/clr' は同時に指定できません」とエラーが出ます
|
|
VC++ EEをお使いですか?
調べてみたところ、
/MT,/MTd(静的ライブラリ)は、VC++ EEからは/clrと同時に指定が出来ないようです。
それと同じような質問のスレがありました。
参考にしてみてください。↓
ttp://hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=659
111ポイント を手に入れた。
|
|
|
|
|
Name: TH ..ぴよぴよ(701ポイント)
Date: 2009/02/25(水) 03:17
No:29296
| 解決!
|
Title: Re:error D8016「/MTd' と '/clr' は同時に指定できません」とエラーが出ます
|
|
>>cosmoさん
ありがとうございます。
無事解決しました!
25ポイント を手に入れた。
|
|
|
|
|
Name: TH ..ぴよぴよ(725ポイント)
Date: 2009/02/25(水) 16:03
No:29337
| 解決!
|
Title: Re:error D8016「/MTd' と '/clr' は同時に指定できません」とエラーが出ます
|
|
>>cosmoさん
ありがとうございます。
無事解決しました!
24ポイント を手に入れた。
|
|
|
|
Name: DIAMOND ..ぴよぴよ(45ポイント)
Date: 2009/02/24(火) 21:05
No:29265
|
|
Title: 関数について
|
|
はじめまして
この度、ゲームを作ろうと調べていたらここにたどり着きました。
サイト全体を拝見してみたところ、ゲームプログラミングの館が一番理解しやすそう
だったので参考にしながら選択画面の作り方あたりまで勉強したので簡単なゲームを
作っていけたらいいな〜と思っているのですが、DXライブラリの使い方などはわかりました。
ただ、ゲームを作成するときの処理の流れがイマイチ理解できていません。
ゲーム等を作るときって関数の中に関数を入れていって処理するんでしょうか?
例えば
全体の関数{
{Aのキャラクターが歩く計算}
{Bのキャラクターが歩く計算}
{Aの描画}
{Bの描画}
}
こんな感じで{}は関数を表してるんですが・・・・
見当違いな事を言っていたら申し訳ないのですがイマイチ言語と処理の流れのイメージがつかめていません。
ご指導よろしくお願いします。
45ポイント を手に入れた。
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(63,855ポイント)
Date: 2009/02/24(火) 21:15
No:29267
|
|
Title: Re:関数について
|
|
自分はですが、
あまりいろいろな物をごちゃまぜにしないほうが良いと思います。
・他に応用がきく関数
・プログラムを簡潔に見せる関数
とりあえずはこの二つですかね。(まだまだ初心者なんで、適切ではないかと思いますが。。)
応用がきく関数は例えばですが、
RPGで町キャラクター、自キャラの動かし方は同じです。
(自動、手動は違いますが、大本は http://dixq.net/g/#22 と同じ)
町人ごとに歩くアルゴリズム書いていたらとんでもないことになります。
そこで関数化を図り、無駄な記述を少なくすることができます。
簡潔に見せる関数は、
例えばmain()にすべての処理を書いてある場合と、
それぞれの関数を分けてmain()で各関数を呼び出す場合を
考えたら一目瞭然です。
ただ、これは見た目の問題なんで、個人のやりやすいようにしたほうがいいと思いますが。
初心者の分際なんで、参考にならないかも知れませんが・・・。
329ポイント を手に入れた。
|
|
|
|
|
Name: Mato ..ぴよぴよ(95ポイント)
Date: 2009/02/24(火) 21:27
No:29270
|
|
Title: Re:関数について
|
|
はじめまして。
別にキューさん(管理人)の回し者ではないですが、ゲームプログラミングの館は理解重視で作られてますので、オススメです(´▽`)
全体の関数{
{Aのキャラクターが歩く計算}
{Bのキャラクターが歩く計算}
{Aの描画}
{Bの描画}
}
というイメージの掴みは良いと思います。
もし、”{Aのキャラクターが歩く計算}”や”{Aの描画}”というのを関数化しない場合を考えます。
その場合、実際にプログラミングすると、”全体の関数”というのが膨大な行の関数になってしまいます。
後で自分が見直した場合に、「このプログラムは何をしたいのか」が分からなくなってきます。
他にも関数化の利点は色々とあります。
そういうわけで、その色々なメリットを利用しない手はない、ということで関数が使われます。
もちろん、WinMain関数にずらずらーっと書き連ねても、ゲームは作れます。
関数がなくてはプログラムは動かないというわけではない、ということですね(WinMain関数だけは使って頂きたいところですが)。
400ポイント を落としてしまった。
|
|
|
|
|
Name: 御津凪 [URL] ..熟練のプログラマー(61,881ポイント)
Date: 2009/02/24(火) 21:39
No:29275
|
|
Title: Re:関数について
|
|
C 言語では、関数の中に関数を書くことは出来ません。
(書くことのできる言語はあります)
void function( int arg ){
printf("input arg of %d.\n", arg);
}
上記のような構造を一括りで関数とし、関数の処理の中で別の関数を呼び出すことで、それぞれの処理を
行なうことができます。
つまり、
Aのキャラクターが歩く計算 の関数{処理}
Bのキャラクターが歩く計算 の関数{処理}
Aの描画 の関数{処理}
Bの描画 の関数{処理}
全体の関数{
Aのキャラクターが歩く計算 を呼び出す
Bのキャラクターが歩く計算 を呼び出す
Aの描画 を呼び出す
Bの描画 を呼び出す
}
のような関係になります。
もし、C言語についての書き方を基礎から覚えたい場合は、
入門書を読むか、「C言語 入門」で検索して気に入った入門系サイトを探すと良いでしょう。
(さすがに全てをここで覚えるわけにはいかないと思いますので…)
プログラムとしての大まかな処理の流れとしては、
・初期化処理(データの読み込みなども含む)
・主要処理(移動・描画など)
・終了(後始末)処理
と、なっています。
これは、ゲームやソフトとして、また関数ごとの流れとしても当てはまります。
# どのような処理を関数に分けるのか、という考えは kazuoni さんの方法が無難ですね。
> Mato さん
> もちろん、WinMain関数にずらずらーっと書き連ねても、ゲームは作れます。
> 関数がなくてはプログラムは動かないというわけではない、ということですね(WinMain関数だけは使って頂きたいところですが)。
単純な処理でない限り、絶対スパゲッティコード(処理が関数内でごちゃごちゃ)になるので厳禁であることを私から付け加えておきます。
451ポイント を手に入れた。
|
|
|
|
|
Name: DIAMOND ..ぴよぴよ(577ポイント)
Date: 2009/02/25(水) 09:01
No:29299
| 解決!
|
Title: Re:関数について
|
|
>kazuoniさん
確かに町の1人1人に歩くアルゴリズムを割り当ててたら大変ですね;
>・他に応用がきく関数
>・プログラムを簡潔に見せる関数
ほかに応用が利く関数と言うのは歩くアルゴリズム、ショット等のアルゴリズム
戦闘時の計算アルゴリズムみたいな感じですかね。
プログラムを簡潔に見せる関数は、シューティングの館、龍神録プログラムの館
等で出てくる、キャラクター移動、描画、当たり判定、ショットアルゴリズムなどが
当てはまるのでしょうかね?
分かりやすい回答ありがとうございました。
>Matoさん
>全体の関数{
>{Aのキャラクターが歩く計算}
>{Bのキャラクターが歩く計算}
>{Aの描画}
>{Bの描画}
>}
>というイメージの掴みは良いと思います。
>もし、”{Aのキャラクターが歩く計算}”や”{Aの描画}”というのを関数化しない場合を考えます。
>その場合、実際にプログラミングすると、”全体の関数”というのが膨大な行の関数になってしまいます。
>後で自分が見直した場合に、「このプログラムは何をしたいのか」が分からなくなってきます。
>他にも関数化の利点は色々とあります。
イメージのつかみ方が合ってたのでホッっとしました。
問題はイメージをどうやってプログラムに組み直すかですね。
やはり全体の関数の中にすべての処理を書くのは無理だと思いつつ書いてました。
特にRPGなどはMAPが2次元配列なので分けないととんでもないことになりそうです。
関数の利点が理解しやすい内容でしたので助かりました。ありがとうございました。
>御津凪さん
>C 言語では、関数の中に関数を書くことは出来ません。
できないのですか〜残念。
>関数の処理の中で別の関数を呼び出すことで、それぞれの処理を
>行なうことができます。
調べてみると関数は別のcppファイルからでも呼び出せるとか。
一度ゲーム館の中にある簡単なプログラムを別のファイルに書いて分割したり
関数を呼び出す練習をして行こうと思います。
関数をどう扱えばいいのか分かったのでよかったです。
ありがとうございました。
PS
>単純な処理でない限り、絶対スパゲッティコード(処理が関数内でごちゃごちゃ)になるので厳禁であること>を私から付け加えておきます。
なんでスパゲッティーコードって言うんでしょう?
やっぱりアジアなら一本麺って表現が合ってる様にも思います(笑)
532ポイント を手に入れた。
|
|
|
|
|
Name: 御津凪 [URL] ..熟練のプログラマー(62,140ポイント)
Date: 2009/02/25(水) 10:26
No:29309
|
|
Title: Re:関数について
|
|
>なんでスパゲッティーコードって言うんでしょう?
>やっぱりアジアなら一本麺って表現が合ってる様にも思います(笑)
由来は、処理がスパゲッティのように絡み合い、どこか一箇所を修正しようとすると、
全体に影響が出る(引きずられる)状態から来ているそうです。
確かに一本麺でも表現は似てますね。本数は違いますが。
91ポイント を手に入れた。
|
|
|
|
Name: ユカイ ..ぴよぴよ(108ポイント)
Date: 2009/02/24(火) 15:03
No:29221
|
|
Title: 無題
|
|
はじめまして、ユカチです。早速なのですが、今、C++で敵を捕まえるというゲームを製作しています。
ここのサイトで、ステージと自分が操作するキャラと行けない範囲の作り方を参考にさせていただきました。
そこでなのですが、肝心の敵が表示できないでいます。マップ内を敵が自動的に動き、自分が敵に触れたら敵が消滅するようにしたいと思っていますが、わかりません。教えていただけませんか?
108ポイント を手に入れた。
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(62,605ポイント)
Date: 2009/02/24(火) 16:10
No:29228
|
|
Title: Re:無題
|
|
まず、題名は質問内容の内容がわかるような題名にしてください。
もう少し具体的に説明するとよい回答が得られるかも知れません。
画像が表示できない理由といってもいろいろあります。
まず、環境はなにですか?
サイト参考なのでDXライブラリ+C++と仮定して、
画像の保存先正しいですか?
まず一度画像の表示だけを実行してみてください。
ps:ユカイさんですよね?^^;
150ポイント を手に入れた。
|
|
|
|
|
Name: ユカイ ..ぴよぴよ(146ポイント)
Date: 2009/02/24(火) 16:33
No:29233
|
|
Title: Re:無題
|
|
すみません、環境はDXライブラリですね。
いろいろと試しましたが、エラーになるか自分自身が敵の画像になったりしてしまいます。
38ポイント を手に入れた。
|
|
|
|
|
Name: ユカイ ..ぴよぴよ(176ポイント)
Date: 2009/02/24(火) 16:48
No:29236
|
|
Title: Re:無題
|
|
とりあえず、main.cppを添付してみましたが、見れますかね?
2倍のポイントを手に入れた! 30ポイント を手に入れた。
|
|
|
|
|
Name: ユカイ ..ぴよぴよ(263ポイント)
Date: 2009/02/24(火) 17:06
No:29242
|
|
Title: Re:無題
|
|
すみません、エラーとかになるので、その辺の処理は消しました。とりあえず自分が動かせるのみのプログラムです。
この後、どういったことをすればよろしいでしょうか?
64ポイント を手に入れた。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(63,123ポイント)
Date: 2009/02/24(火) 20:40
No:29261
|
|
Title: Re:無題
|
|
返事が遅れました。。
必死に作りました。(1時弱・・・遅っ)
説明を書いていたら時間が^^;
とりあえず実行してみてください。
敵キャラは自キャラと同じです。
なので、自キャラが表示できたら自動的に敵がでてきます。(たぶん)
参考にしてください。(参考になるかな?)
追記
C++だったんですね^^;すいません。。
あげてもらったコードがC言語中心だったんで、ついそのままC言語で書いてしまいました。。
142ポイント を手に入れた。
|
|
|
|
|
Name: ユカイ ..ぴよぴよ(333ポイント)
Date: 2009/02/25(水) 09:09
No:29302
| 解決!
|
Title: Re:無題
|
|
おはようございます!! 大変助かりました。 本当にありがとうございます。
また質問するかもしれませんが、その時はまたお願い致します。
70ポイント を手に入れた。
|
|
|
|
Name: 馬鹿太郎 ..ぴよぴよ(703ポイント)
Date: 2009/02/24(火) 21:21
No:29268
|
|
Title: ポインタ
|
|
以下はポインタを使って西暦y年m月d日の≪前の日≫あるいは≪次の日≫の日付を求めてプログラムです。
<pre>
#include <stdio.h>
int day[2][13] = {
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
};
/*-- yearが閏年であれば1そうでなければ0を返す --*/
int isleap(int year)
{
return (year % 4 == 0 && year % 100 != 0 || year % 400);
}
/*-- 受け取った日付の前の日を求める --*/
void yesterday(int *y, int *m, int *d)
{
if (*d != 1) {
(*d)--;
}
else {
if (*m != 1) {
(*m)--;
}
else {
(*y)--;
*m = 12;
}
*d = day[isleap(*y)][*m];
}
}
/*-- 受け取った日付の次の日を求める --*/
void tommorow(int *y, int *m, int *d)
{
if (*d != day[isleap(*y)][*m]) {
(*d)++;
}
else {
if (*m != 12) {
(*m)++;
}
else {
(*y)++;
*m = 1;
}
*d = 1;
}
}
int main(void)
{
int y, m, d;
int ay, am, ad;
int by, bm, bd;
printf("年:"); scanf("%d", &y);
printf("月:"); scanf("%d", &m);
printf("日:"); scanf("%d", &d);
ay = by = y;
am = bm = m;
ad = bd = d;
yesterday(&ay, &am, &ad);
tomorrow(&by, &bm, &bd);
printf("前の日:%d年%d月%d日\n", ay, am, ad);
printf("次の日:%d年%d月%d日\n", by, bm, bd);
return 0;
}
<質問>
・*d = day[isleap(*y)][*m];
たとえば、日付が2000年3月31日だとして、isleap関数に引数として2000が渡されますよね?
そして、閏年かどうかの判断がされて、この場合閏年なので1が返されます。
*d = day[1][3]?となりますよね?
そして、day関数に[1][3]が渡されますよね?
int day[2][13] = {
{ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
{ 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
};
この場合、[1][3]といったら、29なのに31になってません?
あと、day関数でreturnで数値を返していないのはどうしてでしょうか?
1,162ポイント を落としてしまった。
|
|
|
|
Name: box ..ハッカー(136,125ポイント)
Date: 2009/02/24(火) 21:29
No:29272
|
|
Title: Re:ポインタ
|
|
> *d = day[1][3]?となりますよね?
> そして、day関数に[1][3]が渡されますよね?
dayという名前の関数はありません。
> int day[2][13] = {
> { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
> { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
> };
> この場合、[1][3]といったら、29なのに31になってません?
C言語の配列はゼロ始まりであることを再確認してください。
>あと、day関数でreturnで数値を返していないのはどうしてでしょうか?
引数でアドレスを渡しているからです。
83ポイント を手に入れた。
|
|
|
|
|
Name: box ..ハッカー(136,183ポイント)
Date: 2009/02/24(火) 21:35
No:29274
|
|
Title: Re:ポインタ
|
|
ついでに…
> { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
> { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
この2行でコンパイルエラーが出ることにも留意してください。
下段の28は29が正しいですね。
それから、tomorrow関数のスペルが、実体と呼び出す箇所とで食い違っています。
>return (year % 4 == 0 && year % 100 != 0 || year % 400);
最後の条件はyearが400で「割り切れない」ことを意味します。
本来の意図とは逆のはずです。
2倍のポイントを手に入れた! 58ポイント を手に入れた。
|
|
|
|
|
Name: Kou ..かけだし(2,124ポイント)
Date: 2009/02/24(火) 21:56
No:29276
|
|
Title: Re:ポインタ
|
|
> *d = day[1][3]?となりますよね?
> そして、day関数に[1][3]が渡されますよね?
box様のご指摘のように、day関数はありませんね。
このプログラムで関数として存在しているのは、
・閏年を求める関数
・前日と次の日を求める関数
・main関数
上記の4種類だけで、dayは配列としてしか存在していません。
> { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
> { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
> この場合、[1][3]といったら、29なのに31になってません?
これも配列の始まりは 0からなので、2行目左から0、1、2、と数えると、day[1][3]は31になりますね。
260ポイント を手に入れた。
|
|
|
|
|
Name: 馬鹿太郎 ..ぴよぴよ(828ポイント)
Date: 2009/02/24(火) 22:27
No:29278
|
|
Title: Re:ポインタ
|
|
box様、kou様回答ありがとうございます。
・前の日付を求める関数で
たとえば日付が2000年3月1日だとすると、
*d = day[1][3]
{ 0, 31, 29, 31, 30, 31…}
左から4番目で31になりますよね?
でも、前の日付なので、29にならないといけないですよね?
この場合、どうしたらいいのでしょうか?
・(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
これで、どうして閏年が求められるのですか?
101ポイント を手に入れた。
|
|
|
|
|
Name: box ..ハッカー(136,411ポイント)
Date: 2009/02/24(火) 22:43
No:29282
|
|
Title: Re:ポインタ
|
|
> ・前の日付を求める関数で
> たとえば日付が2000年3月1日だとすると、
> *d = day[1][3]
> { 0, 31, 29, 31, 30, 31…}
> 左から4番目で31になりますよね?
> でも、前の日付なので、29にならないといけないですよね?
根本的に理解できていないようです。
yesterday関数において、
*y==2000, *m==3, *d==1 ですね。
このとき、最初のif文のelse句を通ります。
そうすると、*mが2になりますね。
そして、2000年はうるう年ですので、day[1][2]を参照します。
この値はうるう年の2月の日数(つまりうるう年の2月の最終日)ですので、
結果として、2000年3月1日の前日は2000年2月29日となります。
コンピューターになったつもりで、ソースコードの一行一行を
じゅうぶんに吟味してください。
> ・(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
> これで、どうして閏年が求められるのですか?
うるう年の定義がそうなっているからです。
西暦年が4で割り切れて100で割り切れない場合、うるう年とする。
ただし、西暦年が400で割り切れる場合、うるう年とする。
この文章で書いたことをC言語のソースに落とし込んだだけです。
228ポイント を手に入れた。
|
|
|
|
Name: AC ..入門者(4,419ポイント)
Date: 2009/02/25(水) 00:19
No:29291
|
|
Title: strcpyについて
|
|
毎度お世話になってます。
初心に帰って標準入出力をやってて引っかかったところを質問させていただきます。
とりあえずソースです。
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
TCHAR* str;
str = (TCHAR*)malloc(sizeof(TCHAR));
if(!str) exit(EXIT_FAILURE);
//_tcscpy_s(str, sizeof(str)/sizeof(str[0]), _T(""));
// ↑だと、free()時に挙動がおかしくなる
str[0] = '\0';
_tprintf(_T("str = %s\n"), str);
free(str);
return 0;
}
コメントで書いた通りですが、_tcscpy_s(..., _T(""))だと、どうもfree()の時に、処理が止まってしまいます。
なぜダメなのでしょう?
ちなみに
str = (TCHAR*)malloc(sizeof(TCHAR) * 2);
if(!str) exit(EXIT_FAILURE);
_tcscpy_s(str, sizeof(str)/sizeof(str[0]), _T("x"));
_tprintf(_T("str = %s\n"), str);
free(str);
は大丈夫でした。_T("x")の場合はメモリ上に"x\0"が確保されて、それをstrにコピーするという手順を踏んでいると思うのですが、_T("")はメモリ上に'\0'が確保されるわけではないのでしょうか?
1.free()で処理が止まっているとき、いったい何をやっているのか(またはなぜプログラムが進まないのか)
2._T("")ではなぜだめなのか
の2点、ご教示のほどよろしくお願いします。
391ポイント を手に入れた。
|
|
|
|
Name: AC ..入門者(4,744ポイント)
Date: 2009/02/25(水) 01:00
No:29294
| 解決!
|
Title: strcpyについて
|
|
通りすがりさん回答ありがとうございます。
そういえばそうでした・・・。
x86でTCHAR = wchar_tだとすれば、
sizeof(str) / sizeof(str[0]) = sizeof(wchar_t*) / sizeof(wchar_t) = 4 / 2 = 2 ....
ですね…。やってしまった、という感じです。
_tcscpy_s(str, sizeof(str)/sizeof(str[0]), _T("x"));
がたまたま通ったのが、混乱のもとでした。
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
TCHAR* str;
str = (TCHAR*)malloc(sizeof(TCHAR));
if(!str) exit(EXIT_FAILURE);
_tcscpy_s(str, 1, _T(""));
_tprintf(_T("str = %s\n"), str);
free(str);
return 0;
}
で正常に動作するのを確認いたしました。
これで解決とさせていただきます。あぁ空しい…orz。
325ポイント を手に入れた。
|
|
|
|
Name: はいかぜ ..ぴよぴよ(725ポイント)
Date: 2009/02/24(火) 20:15
No:29260
|
|
Title: キー入力の制御について
|
|
こんばんは。
現在、プログラミングの館を参考にしてゲームを作る基礎段階を勉強しているのものです。
一つのボタンで文字の表示、非表示を切り替えるようなプログラムを作りたいのですが上手く作れません。
ソースはこのようになっています。
#include "DxLib.h"
int Key[256];
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]){
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll( GetHitKeyStateAll_Key );
for(int i=0;i<256;i++){
if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
else GetHitKeyStateAll_InputKey[i]=0;
}
return 0;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
int para,white;
para=0;
white=GetColor( 255 , 255 , 255 ) ;
while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存 ↑ESCが押されていない
//ココ!!
if(para==1)
DrawFormatString(100,100, white , "ああああ");//文字列表示
if(Key[ KEY_INPUT_A] ==1 && para==0){
para=1;
}
if(Key[ KEY_INPUT_A] ==1 && para==1){
para=0;
}
ScreenFlip();
}
DxLib_End();
return 0;
}
このソースで動かすと何も反応がないように見えます。
また、過去ログのNo:18003に似たような症状に思えるものの解決策があったのですが…
その示されていた解決策である
1:次のページに移動するボタンと元のページに戻るボタンを別のものにする
2:ページを移動した後、しばらく全ての入力を受け付けないようにする
3:ボタンの押しっ放しを無効にする
のうち、1番は上手くできました。
しかし、やはり同じボタンで制御したいので2番か3番の方を試してみたいと思ったのですがどのように制御したらよいのかが分かりません。
または、他の方法があるのでしょうか?
どなたかアドバイスしていただけないでしょうか。
よろしくお願いします。
環境は
OS:Windows XP sp3
コンパイラ:コンパイラ名 : VC++ 2008EE
です。
725ポイント を手に入れた。
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(63,526ポイント)
Date: 2009/02/24(火) 20:58
No:29263
|
|
Title: Re:キー入力の制御について
|
|
とりあえず題意を満たしたいなら、
if(Key[ KEY_INPUT_A]==1 && para==0)
{
para=1;
}
else if(Key[ KEY_INPUT_A]==1 && para==1)
{
para=0;
}
としてください。
3はすでに解決しています。
GetHitKeyStateAll_2()は押している間ずっとインクリメントしています。
なのでKey[]==1としたら、押された瞬間を指しています。
>ページを移動した後、しばらく全ての入力を受け付けないようにする
これは確かに必要かも知れません。
ただ、例えば
メニュー画面
↓
セーブ画面
と変化するときを考えます。
メニュー画面で[A]を押して次に移動とします。
押しっぱなしでもすぐに一番上のセーブデータをロードすることはありません。
さっきもいいましたが、Key[]はずっとインクリメントされています。
なので、Key[]==1としておけば大丈夫です。
もし本当にこの機能を実装するならば、
GetHitKeyStateAll_2()をメインループの条件で呼び出しますので
実行後にすべてをゼロセットするがよいかなっと思います。
(ちょっと無駄が多いかもしれないですけど・・・)
403ポイント を手に入れた。
|
|
|
|
|
Name: Mato ..ぴよぴよ(761ポイント)
Date: 2009/02/24(火) 21:01
No:29264
|
|
Title: Re:キー入力の制御について
|
|
ソースを動かしてみずに発言しているので、間違っていたらすいません。
このソースでは、いくらAを押しても、paraは1になりえません。
正確に言いますと、
para = 1
と代入した直後に、
para = 0
が実行されるので、ほんの一瞬だけ、1になっていますが。
何故そうなってしまうかということについては、ソース内にコメントを埋めて説明したいと思います。
#Key[ KEY_INPUT_A]が1だとする(キーボードのAを押した直後)
#最初はparaが0なので、2つの条件を満たす
if(Key[ KEY_INPUT_A] ==1 && para==0){
#paraが1になる
para=1;
}
#paraが1になったので、2条件を満たす
if(Key[ KEY_INPUT_A] ==1 && para==1){
#paraが0になる
para=0;
}
という具合です。
507ポイント を手に入れた。
|
|
|
|
|
Name: Mato ..ぴよぴよ(495ポイント)
Date: 2009/02/24(火) 21:12
No:29266
|
|
Title: Re:キー入力の制御について
|
|
>もし本当にこの機能を実装するならば、
GetHitKeyStateAll_2()をメインループの条件で呼び出しますので
実行後にすべてをゼロセットするがよいかなっと思います。
(ちょっと無駄が多いかもしれないですけど・・・)
ゼロセットとは、Key[]の値のことでしょうか。
これらを0にすると、またKey[KEY_INPUT_A]の値が1になりかねないのでは……。
ですので、そういう場合では、メニュー→セーブの流れを1ループ内で納めなければKey[KEY_INPUT_A]==1という条件にしておけば、連続しないと思います。
何か見当違いなこと言ってたらすいません。
266ポイント を落としてしまった。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(64,236ポイント)
Date: 2009/02/24(火) 21:28
No:29271
|
|
Title: Re:キー入力の制御について
|
|
>これらを0にすると、またKey[KEY_INPUT_A]の値が1になりかねないのでは……。
自分の意図がうまく説明できていませんでした。。
例えばメニュー→縦シューティングゲームスタート
とします。そしてメニュー選択キーとショット発射キーが同じだったとします。
自機ショット発射が
if(Key[...]>=1)
で制御されているとしたら、メニュー移行押し続ければ、
いきなりショットが始まります。
これがボムキーだったら敵もいない画面でボム使ってしまいます。
(まぁ、こんな処理ないかと思いますけど・・・)
なのでちょっとの間キー無効にすればそんな心配もありません。
(ボムキーだけ無効でもいいかも知れませんが・・・。)
これを実装するには
GetHitKeyStateAll_2()
で各キーに監査の値代入後、
ゼロセットすれば、ループが戻ってくるまでKey[]のすべての値は0です。
こんなことを言いたかったんです^^;言葉不足で大変失礼しました。。
381ポイント を手に入れた。
|
|
|
|
|
Name: はいかぜ ..かけだし(1,370ポイント)
Date: 2009/02/24(火) 22:29
No:29279
| 解決!
|
Title: Re:キー入力の制御について
|
|
回答してくださった皆様方
ありがとうございました。
こんなにも早く答えていただいて感激です。
また、質問に来ると思いますがそのときもよろしくお願いします。
kazuoniさん
ご指摘の通りにソースを書き直したら、無事に目的にたどり着けました。
else文を使うことは思いつかなかったです^^;
普段、学校で行うプログラミングにelse文を滅多に使わないのでその存在を忘れかけていました。
勉強不足が堪えます。
疑問点が解決した後で恐縮なのですが…
>実行後にすべてをゼロセットする
GetHitKeyStateAll_2()を
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]){
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll( GetHitKeyStateAll_Key );
for(int i=0;i<256;i++){
if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
else GetHitKeyStateAll_InputKey[i]=0;
}
GetHitKeyStateAll_InputKey=0; //ここを追加
return 0;
}
というようにすればよいということなのでしょうか?
Matoさん
よく分かりました。
ソースの
if(Key[ KEY_INPUT_A] ==1 && para==1){
para=0;
}
の部分を
if(Key[ KEY_INPUT_A] ==500 && para==1){
para=0;
}
としたところ…
一回目のAを押した後、しばらく押しっぱなしにすることで文字が消えました。
というわけですから、おっしゃっていたことは間違いなかったと思います。
645ポイント を手に入れた。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(64,472ポイント)
Date: 2009/02/24(火) 22:47
No:29284
|
|
Title: Re:キー入力の制御について
|
|
>実行後にすべてをゼロセットする
>GetHitKeyStateAll_InputKey=0
GetHitKeyStateAll_InputKeyとはなんでしょうか?
少なくとも、DxLib.hには宣言されていませんでしたが・・・?
ゼロセットはキー監査の関数には書かないほうが良い気がします。
基本的には
for(i=0;i<256;++i)
Key[i]=0;
を関数化して、最初に呼び出されてから数十or数百ループの間はこの関数に入る
で良いと思います。
が、果たして、これが現時点で必要なのかどうか考えてみてください。
おそらく現時点では必要ない気がしますが・・・。
202ポイント を手に入れた。
|
|
|
|
|
Name: はいかぜ ..かけだし(1,659ポイント)
Date: 2009/02/24(火) 23:09
No:29286
|
|
Title: Re:キー入力の制御について
|
|
>GetHitKeyStateAll_InputKeyとはなんでしょうか?
int GetHitKeyStateAll_2()の引数がint GetHitKeyStateAll_InputKey[]になっていたので、
最初はGetHitKeyStateAll_InputKey[]=0というように書いたのですが…
そしたら「]」が不適切というようなエラーが起きたので「[]」を消してみたら実行できたので、
それをそのまま書いただけでした^^;
確認もせずに質問してしまって申し訳ないです。
仰るとおり現状では、このようなことはする必要はないと思います。
ただ、後ほど必要になったときになんらかの助けになるのではないかと思い、
少し浮かんだ疑問点を質問してみたところでした。
このような質問にも、丁寧にお答えいただきありがとうございました。
289ポイント を手に入れた。
|
|
|
|
|
Name: はいかぜ ..かけだし(1,725ポイント)
Date: 2009/02/25(水) 00:21
No:29292
|
|
Title: Re:キー入力の制御について
|
|
>ポインタ、文字列等復習をしてみてください。
>memset()という関数もありますので、調べてみてください。
了解です。
気長に学んでいくとします^^
アドバイスありがとうございました。
66ポイント を手に入れた。
|
|
|
|
Name: kayama ..かけだし(1,620ポイント)
Date: 2009/02/24(火) 18:59
No:29252
|
|
Title: ビルドできない
|
|
初歩的な質問で申し訳ございません。
VC++で「DxLib_VC2008_and_2005用のプログラム」をオープンし、ビルドすると正常に動作します。
しかし、新規でプロジェクトを作成し、別のディレクトリで同じプログラムを実行すると以下の様なエラーがでます。
LIBCMTD.lib(dbgheap.obj) : error LNK2005: __CrtSetCheckCount は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(crt0dat.obj) : error LNK2005: _exit は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(crt0dat.obj) : error LNK2005: __exit は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(crt0dat.obj) : error LNK2005: __cexit は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(crt0dat.obj) : error LNK2005: __amsg_exit は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(crt0dat.obj) : error LNK2005: __initterm_e は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(fflush.obj) : error LNK2005: _fflush は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(dbghook.obj) : error LNK2005: __crt_debugger_hook は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(invarg.obj) : error LNK2005: __invoke_watson は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(setlocal.obj) : error LNK2005: __configthreadlocale は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(tidtable.obj) : error LNK2005: __encode_pointer は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(tidtable.obj) : error LNK2005: __decode_pointer は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(sprintf.obj) : error LNK2005: _sprintf は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(crt0init.obj) : error LNK2005: ___xi_a は既に MSVCRTD.lib(cinitexe.obj) で定義されています。
LIBCMTD.lib(crt0init.obj) : error LNK2005: ___xi_z は既に MSVCRTD.lib(cinitexe.obj) で定義されています。
LIBCMTD.lib(crt0init.obj) : error LNK2005: ___xc_a は既に MSVCRTD.lib(cinitexe.obj) で定義されています。
LIBCMTD.lib(crt0init.obj) : error LNK2005: ___xc_z は既に MSVCRTD.lib(cinitexe.obj) で定義されています。
LIBCMTD.lib(hooks.obj) : error LNK2005: "void __cdecl terminate(void)" (?terminate@@YAXXZ) は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(winxfltr.obj) : error LNK2005: __XcptFilter は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(dosmap.obj) : error LNK2005: __errno は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(mlock.obj) : error LNK2005: __lock は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(mlock.obj) : error LNK2005: __unlock は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(vsprintf.obj) : error LNK2005: _vsprintf は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(errmode.obj) : error LNK2005: ___set_app_type は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(dbgrptw.obj) : error LNK2005: __CrtDbgReportW は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(typinfo.obj) : error LNK2005: "public: void __thiscall type_info::_type_info_dtor_internal_method(void)" (?_type_info_dtor_internal_method@type_info@@QAEXXZ) は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(typinfo.obj) : error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) は既に MSVCRTD.lib(ti_inst.obj) で定義されています。
LIBCMTD.lib(typinfo.obj) : error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) は既に MSVCRTD.lib(ti_inst.obj) で定義されています。
LIBCMTD.lib(getenv.obj) : error LNK2005: _getenv は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LIBCMTD.lib(abort.obj) : error LNK2005: _abort は既に MSVCRTD.lib(MSVCR90D.dll) で定義されています。
LINK : warning LNK4098: defaultlib 'MSVCRTD' は他のライブラリの使用と競合しています。/NODEFAULTLIB:library を使用してください。
LINK : warning LNK4098: defaultlib 'LIBCMTD' は他のライブラリの使用と競合しています。/NODEFAULTLIB:library を使用してください。
libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jtransform_execute_transformation が関数 _main で参照されました。
libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jcopy_markers_execute が関数 _main で参照されました。
libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jtransform_adjust_parameters が関数 _main で参照されました。
libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jtransform_request_workspace が関数 _main で参照されました。
libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _jcopy_markers_setup が関数 _main で参照されました。
libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _write_stdout が関数 _main で参照されました。
libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _read_stdin が関数 _main で参照されました。
libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _read_scan_script が関数 _parse_switches で参照されました。
libjpeg_d.lib(jpegtran.obj) : error LNK2019: 未解決の外部シンボル _keymatch が関数 _parse_switches で参照されました。
D:\My Documents\Program\BCC game programming\rpg\Debug\rpg.exe : fatal error LNK1120: 外部参照 9 が未解決です。
何か設定が間違っているのでしょうか。
DXライブラリの設定は完了しました。
ファイルを作成する際にもWin32プロジェクトを選択しましたし、
インクルードファイルに「プロジェクトに追加すべきファイル_VC用」のパスも設定しました。
どなたかご教授ください。
1,620ポイント を手に入れた。
|
|
|
|
Name: kayama ..かけだし(1,717ポイント)
Date: 2009/02/24(火) 20:11
No:29259
| 解決!
|
Title: Re:ビルドできない
|
|
ありがとうございます。
リンク先の項目をひとつひとつもう一度入念にチェックしてみたところ、
構成をReleseにする前にランタイムライブラリの変更をしていませんでした。
おかげで実行できました。
97ポイント を手に入れた。
|
|
|
|
Name: 初心者 ..プログラマー(28,231ポイント)
Date: 2009/02/22(日) 14:11
No:29149
|
|
Title: RPG
|
|
今、RPGゲームを作ろうと思っているんですが、参考になるページがあまりありません。
誰か、参考になるページがあれば教えてください。
2倍のポイントを手に入れた! 120ポイント を手に入れた。
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(62,292ポイント)
Date: 2009/02/22(日) 14:30
No:29150
|
|
Title: Re:RPG
|
|
確かにあまりない気がします。
http://dixq.net/g/
で導入なら見れますよ。
作る流れだけなら
ttp://wiki.game-develop.com/index.php?%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%2F%BD%E9%BF%B4%BC%D4%B8%FE%A4%B1%2F%A5%C1%A5%E5%A1%BC%A5%C8%A5%EA%A5%A2%A5%EB%2F%C3%CA%B3%AC%C5%AA%B3%D8%BD%AC%2FFF%C9%F7RPG%A4%F2%BA%EE%A4%EC#s4dd3d50
に載ってます。あくまで流れだけですw
あとは書籍ですかね^^;
115ポイント を落としてしまった。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(319,921ポイント)
Date: 2009/02/22(日) 22:17
No:29163
|
|
Title: Re:RPG
|
|
(探せばもっとあるかと思いますが)ソースを公開しているRPGです。
解析すればきっと参考になるでしょう。
Battle for Wesnoth
ttp://www.wesnoth.org/
PlaneShift - A 3D Fantasy MMORPG
ttp://www.planeshift.it/
Egoboo
ttp://egoboo.sourceforge.net/
90ポイント を落としてしまった。
|
|
|
|
|
Name: 初心者 ..プログラマー(28,661ポイント)
Date: 2009/02/23(月) 21:47
No:29192
|
|
Title: Re:RPG
|
|
返答ありがとうございます。
探してもらった、ページを基に作らせていただきます。
さっそく質問なんですが、
void MyMain(){
Vector curvec1 = {0,0};
int Key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
if( Key & PAD_INPUT_UP ){
curvec1 = AddVector( curvec1, JIKI_UP );
g_jikipos = AddVectorInFrameTime( g_jikipos, curvec1 );
DrawAnimation( g_jikipos.x, g_jikipos.y, 1, 0, FALSE,
&g_jikiimage[12], 4, 12 );
};
if( Key & PAD_INPUT_LEFT ){
curvec1 = AddVector( curvec1, JIKI_LEFT );
g_jikipos = AddVectorInFrameTime( g_jikipos, curvec1 );
DrawAnimation( g_jikipos.x, g_jikipos.y, 1, 0, FALSE,
&g_jikiimage[4], 4, 12 );
};
if( Key & PAD_INPUT_RIGHT ){
curvec1 = AddVector( curvec1, JIKI_RIGHT );
g_jikipos = AddVectorInFrameTime( g_jikipos, curvec1 );
DrawAnimation( g_jikipos.x, g_jikipos.y, 1, 0, FALSE,
&g_jikiimage[8], 4, 12 );
};
if( Key & PAD_INPUT_DOWN){
curvec1 = AddVector( curvec1, JIKI_DOWN );
g_jikipos = AddVectorInFrameTime( g_jikipos, curvec1 );
DrawAnimation( g_jikipos.x, g_jikipos.y, 1, 0, FALSE,
&g_jikiimage[0], 4, 12 );
};
while(ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 1){
ClsDrawScreen();
DxLib_End();
}
}
と書いてみましたが、キーを押したときしか、キャラが描画されません。
キーを押していなくても描画できる方法は、ありませんか?
410ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(7,759ポイント)
Date: 2009/02/23(月) 21:59
No:29195
|
|
Title: Re:RPG
|
|
フラグ変数を用意して、「入力」と「出力」の間にワンクッション置いてみてはどうでしょう。
「入力」→「出力」とすると、入力がなければ出力はされません。
「入力」→「状態をstatic変数で保存」→「変数の値によって出力」とすれば、期待したような状態になるのではないでしょうか。
98ポイント を手に入れた。
|
|
|
|
|
Name: Dixq (管理人) ..伝説なるハッカー(995,124ポイント)
Date: 2009/02/23(月) 22:20
No:29197
|
|
Title: Re:RPG
|
|
MyMainっていつ呼ばれるんでしょう?
処理の流れをよく考えて見ましょう。
まず入力状態を調べ、何か処理をした後、
メッセージ処理が正常でかつエスケープが押されている間
画面を消してDXライブラリの終了をし続ける
って意味になってしまっています。
DXライブラリの終了処理を何度もやっていることになってますが、DXライブラリの終了関数は本当に終わりたい時に呼んでください。
まずプログラムを書く前にどういう流れで処理を書きたいのか書いてみて実装してみるのがいいかもしれません。
161ポイント を手に入れた。
|
|
|
|
|
Name: 初心者 ..プログラマー(28,672ポイント)
Date: 2009/02/24(火) 18:55
No:29251
|
|
Title: Re:RPG
|
|
SCIさんへ
具体的に教えてください。
Dixq (管理人)さんへ
>メッセージ処理が正常でかつエスケープが押されている間
画面を消してDXライブラリの終了をし続ける
確かにそうですね。
11ポイント を手に入れた。
|
|
|
|
Name: yama ..入門者(3,274ポイント)
Date: 2009/02/24(火) 17:05
No:29240
|
|
Title: 「12.画像を動かす」の初期化
|
|
現在自分は、こちらのサイトを参考にさせていただきゲームを作成している初心者です。
ゲームを作成できたのですが、一回プレイし、二回目のプレイの際に問題が起きました。
うまく言えないので問題部分のプログラムをのせさせていただきます。
二回目のプレイする際、一回目と同じようにx=0から図を動かしたいとおもっています。
環境は、windows vc2008 DXライブラリ です。
拙い文章でほんとにすみません。よろしくお願いします。
#include "DxLib.h"
int function_status=0,White;
char KeyBuf[ 256 ] ;
void Opening(){
DrawString(100,100,"オープニング画面 (zをプッシュ)",White);
if(KeyBuf[KEY_INPUT_Z]==1)
function_status=1;
}
}
void Danjon(){
DrawString(100,180,"ダンジョン画面 (cをプッシュ)",White);
if(KeyBuf[KEY_INPUT_C]==1)
function_status=3;
}
void attack(){
DrawString(100,220,"戦闘画面 (vをプッシュ)",White);
if(KeyBuf[KEY_INPUT_V]==1)
function_status=4;
}
void Ending(){
DrawString(100,260,"エンディング画面 (bをプッシュ)",White);
if(KeyBuf[KEY_INPUT_B]==1)
function_status=5;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode( TRUE ) ; //ウィンドウモードに変更
if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了
White = GetColor( 255 , 255 , 255 ) ; //色の取得
SetDrawScreen( DX_SCREEN_BACK ) ; // 描画先を裏画面に設定
while( 1 ){
ClearDrawScreen(); // 裏画面のデータを全て削除
GetHitKeyStateAll( KeyBuf ) ; // すべてのキーの状態を得る
switch(function_status){
case 0:
Opening();
break;
case 1:
Menu();
break;
case 2:
Danjon();
break;
case 3:
attack();
break;
case 4:
Ending();
break;
default:
DxLib_End() ; // DXライブラリ使用の終了処理
return 0;
break;
}
if( ProcessMessage() == -1 ) break ; //エラーが起きたら終了
ScreenFlip() ; // 裏画面データを表画面へ反映
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
1,250ポイント を手に入れた。
|
|
|
|
Name: yama ..入門者(3,788ポイント)
Date: 2009/02/24(火) 17:07
No:29244
|
|
Title: Re:「12.画像を動かす」の初期化
|
|
すみませんプログラム間違えました。
#include "DxLib.h"
int function_status=0,White,Yellow,G_Blue,Red,c;
char KeyBuf[ 256 ] ;
int PointX = 0;
void Opening(){
SetFontSize( 30 ) ; //サイズを20に変更
SetFontThickness( 1 ) ; //太さを1に変更
ChangeFont( "HGS創英角ポップ体" ) ; //HGS創英角ポップ体に変更
ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE );//アンチエイリアス&エッジ付きフォントに変更
DrawString(50,300," PUSH Z KEY",GetColor(255,255,255));
if(KeyBuf[KEY_INPUT_Z]==1)
function_status=1;
}
void Menu(){
LoadGraphScreen( PointX , 350 , "囚人.png" , TRUE );
Yellow = GetColor( 255 , 255 , 0 ) ; // 赤色の値を取得
G_Blue = GetColor( 128 , 128 , 128 ) ; // 緑と青の混合色の値を取得
White = GetColor( 255 , 255 , 255 ) ; // 白色の値を取得
DrawBox ( 400 , 200 , 440 , 700 , G_Blue , TRUE ) ; // 四角形を描画(塗りつぶし)
DrawCircle( 550 , 30 , 30 , Yellow , TRUE) ; // 円を描画(塗りつぶし)
DrawString( 0, 0, "level 1" , White); //文字列表示
PointX++;
if(PointX==290)
function_status=2;
}
void Danjon(){
SetFontSize( 30 ) ; //サイズを20に変更
SetFontThickness( 1 ) ; //太さを1に変更
ChangeFont( "HGS創英角ポップ体" ) ; //HGS創英角ポップ体に変更
ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE );//アンチエイリアス&エッジ付きフォントに変更
DrawString(50,300," PUSH X KEY",GetColor(255,255,255));
if(KeyBuf[KEY_INPUT_X]==1)
function_status=0;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode( TRUE ) ; //ウィンドウモードに変更
if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了
White = GetColor( 255 , 255 , 255 ) ; //色の取得
SetDrawScreen( DX_SCREEN_BACK ) ; // 描画先を裏画面に設定
while( 1 ){
ClearDrawScreen(); // 裏画面のデータを全て削除
GetHitKeyStateAll( KeyBuf ) ; // すべてのキーの状態を得る
switch(function_status){
case 0:
Opening();
break;
case 1:
Menu();
break;
case 2:
Danjon();
break;
default:
DxLib_End() ; // DXライブラリ使用の終了処理
return 0;
break;
}
if( ProcessMessage() == -1 ) break ; //エラーが起きたら終了
ScreenFlip() ; // 裏画面データを表画面へ反映
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
514ポイント を手に入れた。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(62,981ポイント)
Date: 2009/02/24(火) 17:20
No:29245
|
|
Title: Re:「12.画像を動かす」の初期化
|
|
方向キーで捜査している箇所は省略しているのですかね?
キャラデータが記述されていないので、どうなっているか分かりませんが、
Menuの選択終了後、breakする前に、
キャラクラーX座標=0;
キャラクラーY座標=0;
という記述がいると思います。
まず、キャラデータをどう初期化しているのか気になりますが。。
134ポイント を手に入れた。
|
|
|
|
|
Name: yama ..入門者(3,893ポイント)
Date: 2009/02/24(火) 17:44
No:29248
|
|
Title: Re:「12.画像を動かす」の初期化
|
|
迅速な返答ありがとうございます。
自分のゲームは方向キーを使わず、決められた範囲のパラメーターを選択し、図が動きX=290になったら結果が出るというものです。一回はできるのですが、二回目にX=290からスタートしてしまいます。キャラデータの初期化は行ってないです。
初心者なので、プログラムの理解度が低いです。ほんとにすみません。
105ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(8,164ポイント)
Date: 2009/02/24(火) 17:48
No:29249
|
|
Title: Re:「12.画像を動かす」の初期化
|
|
if(KeyBuf[KEY_INPUT_X]==1)
function_status=0;
この部分を、とりあえず
if(KeyBuf[KEY_INPUT_X]==1) {
function_status=0;
PointX = 0;
}
として実行してみてください。
122ポイント を手に入れた。
|
|
|
|
|
Name: yama ..入門者(3,960ポイント)
Date: 2009/02/24(火) 18:02
No:29250
| 解決!
|
Title: Re:「12.画像を動かす」の初期化
|
|
SCIさんの言う通り変えてみたらできました。
Xボタンを押すと0に行く+x=0になるということですね。
ほんとにありがとうございます。これから勉強しまくってプログラム完璧に理解したいと思います。
67ポイント を手に入れた。
|
|
|
|
Name: dai ..ぴよぴよ(530ポイント)
Date: 2009/02/24(火) 14:43
No:29217
|
|
Title: 行列の読み込みについて
|
|
縦500、横400という行列を読み込もうと思っています。
縦は、繰り返し文(while)で番号がつくのですが、横についてうまく番号を付ける方法がわかりません。
要は、
2 3 4 5
4 5 5 6
5 4 8 3
といった行列をma[i][j]で呼び出せるようにしたいのですが、jをどうすればよいかわかりません。
このようなプログラムを書いてみたのですが、
seihouka-test4.txtは 5 2 3 4 6
という一行のものです。
#include <stdio.h>
int main(void)
{
FILE *finput;
int i,j,a;
int ma[8];
char str[100];
finput=fopen("seihouka-test4.txt","r");
i=0;
while(i<=2){
if(NULL==fgets(str,100,finput))
break;
for(a=0,j=0;a<=7,j<=7;a++,j++){
sscanf(&str[a],"%1d",&ma[j]);
}
i++;
}
printf("%d %d %d %d %d\n",ma[0],ma[1],ma[2],ma[3],ma[4]);
fclose(finput);
return(0);
}
出力結果は 5 2 2 3 3
となぜか二つ目以降2回繰り返してしまいます。
どなたか解決方法を教えていただけませんでしょうか?
よろしくお願いします。
530ポイント を手に入れた。
|
|
|
|
Name: SCI ..初心者(7,636ポイント)
Date: 2009/02/24(火) 14:58
No:29219
|
|
Title: Re:行列の読み込みについて
|
|
コード中に二次元配列がないんですけど、使わないんですか?
それと、コードは<pre>タグで括って掲載して貰えると嬉しいです。その方が多くの回答を得られると思いますよ。
88ポイント を手に入れた。
|
|
|
|
|
Name: バグ ..ハッカー(148,858ポイント)
Date: 2009/02/24(火) 15:03
No:29220
|
|
Title: Re:行列の読み込みについて
|
|
whileループでも出来ますが、今回のような場合はforループの方が分かり易いように思いますよ(^-^)
int i, j;
for (i = 0; i < 500; ++i)
{
for (j = 0; j < 400; ++j)
{
/* ここに目的の処理を書き込む */
}
}
107ポイント を手に入れた。
|
|
|
|
|
Name: dai ..ぴよぴよ(842ポイント)
Date: 2009/02/24(火) 15:08
No:29222
|
|
Title: Re:行列の読み込みについて
|
|
申し訳ありません。
はじめは簡単に・・・ということで一行にしたのですが・・・
プログラムを書き換えます。
seihouka-test1は
3 5 7 4 2
4 2 1 8 4
2 7 6 4 6
1 3 5 9 2
というものです。
#include <stdio.h>
int main (void)
{
FILE *finput; /*普通の行列 4*5 */
int i,j,a;
int ma[6][7];
char str[100];
finput=fopen("seihouka-test1.txt","r");
i=0;
while(i<=4){
if(NULL==fgets(str,100,finput))
break;
for(j=0,a=0;j<=5,a<=5;j++,a++){
sscanf(&str[a],"%1d",&ma[i][j]);
}
i++;
}
for (i=0;i<=3;i++){
for (j=0;j<=5;j++)
printf(" %2d",ma[i][j]);
printf("\n");
}
fclose(finput);
return(0);
}
この出力結果は
3 5 5 7 7 4
4 2 2 1 1 8
2 7 7 6 6 4
1 3 3 5 5 9
と、どうしても2文字以降2回繰り返してしまいます。
解決法のほう、よろしければよろしくお願いします。
312ポイント を手に入れた。
|
|
|
|
|
Name: toyo ..プログラマー(26,202ポイント)
Date: 2009/02/24(火) 15:24
No:29223
|
|
Title: Re:行列の読み込みについて
|
|
2個ずつ並ぶのは空白の部分で重複するからです
str[ 0 ]
5□2□3□4□6 => 5
str[ 1 ]
□2□3□4□6 => 2
str[ 2 ]
2□3□4□6 => 2
str[ 3 ]
□3□4□6 => 3
str[ 4 ]
3□4□6 => 3
個数が決まってるならforの2重ループでfscanf( )とか
81ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(7,762ポイント)
Date: 2009/02/24(火) 15:59
No:29226
|
|
Title: Re:行列の読み込みについて
|
|
いくつか仕様を挙げてみてはどうでしょう。
・行数と列数は固定か、可変か
・数字は必ず半角スペース1つで区切られるか
・数字の桁数は任意か、また小数を含むか
85ポイント を手に入れた。
|
|
|
|
|
Name: dai ..ぴよぴよ(985ポイント)
Date: 2009/02/24(火) 17:28
No:29247
| 解決!
|
Title: Re:行列の読み込みについて
|
|
いろいろな方法を挙げてくださってありがとうございます。
for文のaの増やし方が間違っていたようです。
それで解決しました。
ありがとうございました。
55ポイント を手に入れた。
|
|
|
|
Name: dai ..ぴよぴよ(950ポイント)
Date: 2009/02/24(火) 17:04
No:29239
|
|
Title: for文である数を1以上増やす方法について
|
|
たとえば、for文でiを1ずつ増やすときは
for(i=0;i<6;i++)
などと書きますが、
iを1より大きい数(6ずつとか)増やす時はどう表記すればよいのでしょうか?
初歩的な質問ですみません。
よろしくお願いします。
108ポイント を手に入れた。
|
|
|
|
Name: YuO ..プログラマー(30,186ポイント)
Date: 2009/02/24(火) 17:07
No:29243
|
|
Title: Re:for文である数を1以上増やす方法について
|
|
1増やしているのはi++ですから,ここを6なら6増やす式にすればよいです。
例としては,
・ for (i = 0; i < N; i += 6)
・ for (i = 0; i < N; i = i + 6)
などが挙げられます。
84ポイント を手に入れた。
|
|
|
|
|
Name: dai ..ぴよぴよ(930ポイント)
Date: 2009/02/24(火) 17:26
No:29246
| 解決!
|
Title: Re:for文である数を1以上増やす方法について
|
|
ありがとうございました。
これですべて解決しました。
20ポイント を落としてしまった。
|
|
|
|
Name: dic ..中級者(12,508ポイント)
Date: 2009/02/20(金) 20:36
No:29054
|
|
Title: 敵のパターンを実装する方法について
|
|
シューティングの基礎としては結構できあがったのですが
敵の種類を増やすことになり、敵のパターンをswitch-case文でソースコードで書いているのですが
最低24種類作りたいのですが、結構な量になり後々のゲームバランスなどを
考慮し、保守的な観点から見ると、修正に時間がかかり、デバックにも時間がかかりすぎることが
予想できますし、今やっているところなのですが、10種類も作ったら覚えきれず把握しきれません
そこで、敵の動きを数値化したいと考えているのですが
数値化できるものとして、始点、終点、速度、加速度、角度を考え付きました
しかし、これでは単純な動きしか実現できず、もうすこし複雑な動きを実現したいと考えていますが
どうすればよいのか分かりません
ベジェ曲線などを私が勉強し、理解していれば簡単なのかもしれませんが
中学生レベルで、直線、円を描く以外に敵の動きを実現する方法はどういった方法があるのでしょうか?
参考程度までに聞かせていただきたいです。
356ポイント を手に入れた。
|
|
|
|
Name: 御津凪 [URL] ..熟練のプログラマー(59,308ポイント)
Date: 2009/02/20(金) 21:29
No:29055
|
|
Title: Re:敵のパターンを実装する方法について
|
|
私なりの考えですが、
たとえば、敵の動作を関数単位で用意するようにし、下記のような定義をおこないます。
typedef struct _SEnemy;
typedef void (*EnemyMove)( struct _SEnemy *enemy );
typedef struct _SEnemy {
EnemyMove move; // 移動関数
int counter; // カウンタ
float x,y; // 敵の位置
float angle; // 移動角度
float speed; // 移動速度
} SEnemy;
そして、下記のような移動関数等を定義します。
// 移動計算
void EnemyUpdatePos( SEnemy *enemy ){
enemy->x += sinf(enemy->angle) * enemy->speed;
enemy->y += cosf(enemy->angle) * enemy->speed;
}
// カウントチェック。
// 指定値を超えたら次のフェイズへ
void EnemyCountCheck( int n ){
if(enemy->counter > n){
++enemy->phase;
enemy->counter = 0;
}
}
// 敵移動パターン 001
void EnemyMove001( SEnemy *enemy ){
++enemy->counter;
switch(enemy->phase){
case 0: // 30f 直線移動
EnemyCountCheck(30);
break;
case 1: // 30f カーブ
enemy->angle += M_PI_2 / 30;
EnemyCountCheck(30);
break;
case 2: // 30f 逆カーブ
enemy->angle -= M_PI_2 / 30;
EnemyCountCheck(30);
break;
case 3: // 以降加速しながら直線移動
enemy->speed += 0.01f;
}
// 移動計算
EnemyUpdatePos(enemy);
}
そして、以下のような関数で処理を行います。
// 敵移動更新
void EnemyUpdate( SEnemy *enemy, int count ){
int i;
for(i = 0;i < count; ++i){
if(enemy[i].move)
enemy[i]move(&enemy[i]);
}
}
EnemyUpdate 関数を毎フレーム実行すれば、登録された敵を移動させることが出来ます。
これなら難しい軌道計算を行なわなくても、複雑な軌道をとることが出来ます。
また、相対位置からの移動を行なうので、登録時のパラメータを変えれば軌道を調整できます。
(これは応用すれば弾のパターンにも使えます)
長くなりましたが、こんな方法はどうでしょうか?
# やっつけで書いたのでおかしいところがあるかもしれません。
580ポイント を手に入れた。
|
|
|
|
|
Name: めいらる ..かけだし(1,389ポイント)
Date: 2009/02/21(土) 00:21
No:29060
|
|
Title: Re:敵のパターンを実装する方法について
|
|
私のシューティングは今のところ敵に
x座標、y座標、移動方向(度数)、移動方向の角度変化量(度数)、移動速度、移動速度の変化量、グラフィックサイズ、グラフィック回転度、グラフィック回転度変化量、当たり判定サイズ、撃つ弾の初速、発射規準角度、発射基準角度変化量、
円形射撃か扇射撃かのフラグ、扇射撃時の間隔、way数、カウンター、制御用カウンター、HP、行動タイプ、
発射した弾の行動タイプ、攻撃回数カウンター、攻撃回数最大値、発射間隔、ロックオンフラグetc…
…とまぁものすごい数のステータスを与えることができるようにしてますww
このものすごい数のステータスはコース、難易度別に分けたファイルにswitch-case文とif文で敵機ひとつひとつ書いてますw後で苦労しそうな気もしますが自分はこれで…
どうも説明するのが難しいです^^;
あまり参考にならないですが図のcase8の敵を出現させると右下のようになります
上から出てきてゆっくり停止、一定時間後にレーザー射撃〜です
弾を針型にするのは弾の移動を書いたファイルにまとめてますw
283ポイント を手に入れた。
|
|
|
|
|
Name: Dixq (管理人) ..伝説なるハッカー(993,256ポイント)
Date: 2009/02/21(土) 17:51
No:29114
|
|
Title: Re:敵のパターンを実装する方法について
|
|
龍神録の館の12章のように私は敵の移動制御をしています。
switch文よりも、ファイルからとってきた敵の移動制御番号を関数ポインタの配列番号に入れてやると1行で済みますよ。
あと、複雑な軌跡の描き方ですが、角度の変更と、スピードの変更だけでかなり色んな動きが出来ますよ。
龍神録の弾幕の制御はほとんど角度の変更とスピードの変更だけで実装しています。
例えばどんな軌跡が描きたいのかを教えてもらえたら何かアドバイス出来るかもしれません。
180ポイント を手に入れた。
|
|
|
|
|
Name: dic ..中級者(13,150ポイント)
Date: 2009/02/21(土) 19:02
No:29116
|
|
Title: Re:敵のパターンを実装する方法について
|
|
>御津凪さん回答ありがとうございます
時間軸を追加してさらに枝分かれさせるというとこでしょうか?
時間も敵の情報を保持する構造体に入れているのですがそういった使い方は思いつきませんでした
ありがとうございます
>めいらるさん回答ありがとうございます
そうですね
私も構造体にほとんどの情報を入れれるようにしているのですが
やはりswitch-case文が多くなりますね
>管理人さん
回答ありがとうございます
switch-case文を使わないでファイルからということでスクリプト形式にするのでしょうか?
前にやったことがあるのですが、スクリプトにするのに必要となる情報の洗い出しに苦心し、
また、スクリプト解析などの作成にも苦労したわりにはあまり多くの動きを実現できませんでしたので
switch-case文でソースコード上で管理するようになったのです
どんな動きというと抽象的になってしまうのですが
敵に情報を与えたら自動で画面内を動くようにしたいのです
どんな動きでも実現できたらいいと思っているのですが、多分無理だと考えているので
制約をともなう動き、x座標、y座標、進む角度、速度、加速度、時間で実現できる動きになると
考えています
それを踏まえた上での動きとなってくるので(私の勉強不足ですが)
単調になってしまうのですし、複雑な動きをしようと思ったらソースの量が一気に増え
また管理も大変になるのでバランスが難しいといったところです
例を言うとゲーム「どどんぱち」にでてくるようなプレイヤーの前までにやってきて
弾をばらまき、画面外に逃げるというような動きを実現したいです
642ポイント を手に入れた。
|
|
|
|
|
Name: dic ..中級者(13,269ポイント)
Date: 2009/02/21(土) 21:51
No:29125
| 解決!
|
Title: Re:敵のパターンを実装する方法について
|
|
やりもしないのに結論を出すのは卑怯でしたね
すいませんでした
19ポイント を手に入れた。
|
|
|
|
|
Name: dic ..中級者(13,493ポイント)
Date: 2009/02/23(月) 19:06
No:29185
|
|
Title: Re:敵のパターンを実装する方法について
|
|
具体的に図に示すような軌道をえがく運動(移動)をさせたいのです
私の作成した基本物理エンジンでは細かく設定する必要があるので
幾何学的なアプローチを用いて解決できないかと考えています
なにはともあれ switch-case文が多くなっても大丈夫なように
大きめのモニターを購入予定です
2倍のポイントを手に入れた! 224ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(7,612ポイント)
Date: 2009/02/23(月) 19:22
No:29186
|
|
Title: Re:敵のパターンを実装する方法について
|
|
> dicさん
1と2の軌道、それぞれの関数は決まっていますか?
カウント(時間)を媒介変数とし、定義域を分けて関数形を決めるとよいでしょう。
また、物理エンジンという特性を生かして、物理現象に置き換えてみてもいいですね。
速度比例抵抗とかクーロン力を設定できるなら、運動方程式から関数が求まります。
幾何学的な方程式が求まればいいのでしょうか?
117ポイント を手に入れた。
|
|
|
|
|
Name: dic ..中級者(13,540ポイント)
Date: 2009/02/23(月) 20:18
No:29188
|
|
Title: Re:敵のパターンを実装する方法について
|
|
>SCIさん回答ありがとうございます
幾何学的な方程式は分かっても私の勉強不足により、ソースコードで表現することができないので
これは、今の現状では switch-case文で作ることにしようかと考えています
47ポイント を手に入れた。
|
|
|
|
|
Name: Dixq (管理人) ..伝説なるハッカー(995,212ポイント)
Date: 2009/02/23(月) 22:25
No:29198
|
|
Title: Re:敵のパターンを実装する方法について
|
|
物理エンジンってなんですか?
後、この軌跡は固定ですか?
私もSCIさんの意見に賛成で、カウントを媒介変数として定義域にわけ、関数で表現すればいいと思います。
・○〜○の時は速さアップ
・○〜○の時は速さ角度1°ずつ加算
・○〜○の時は減速しながら角度減算
みたいな感じです。
88ポイント を手に入れた。
|
|
|
|
|
Name: dic ..中級者(14,081ポイント)
Date: 2009/02/24(火) 04:01
No:29211
|
|
Title: Re:敵のパターンを実装する方法について
|
|
>管理人さん 回答ありがとうございます
物理エンジンについてですが私が勝手に作った言葉ですね
具体的に言うと 速度、角度、加速度、を設定し1フレームごとに物理エンジン(関数)を呼び出すと
物理エンジン(関数内で定義された規則どおりに)したがって計算されるというものです
私の説明不足でした すいません
軌跡についてですが固定の場合もあれば変動の場合もあります
固定の敵と、変動の敵、それぞれを組み合わせて敵のそれぞれ動かしたいと考えています
なるほど
固定の場合については 時間軸で制御を行うということですね
しかし、変動的つまり 非固定的なプレイヤーの位置の前までやってきて
弾をばらまいて そのまま画面の外にでるという動き
変動的に変わるプレイヤーの位置の前にくるという処理方法がしっくりきません
プレイヤーの座標をグローバル変数で宣言し、どこからでも参照できるようにしているのですが
これを汎用的に、
敵の動き1を実現する関数 move1
敵の動き2を実現する関数 move2
...
敵の動きXを実現する関数 moveX
とどの関数からも処理できる形にする方法が分からないのです
期待する動きとしては 指定したフレーム数でプレイヤーの前の位置 (x,y) に移動するように
したいのですが、逆算ができない状況です
541ポイント を手に入れた。
|
|
|
|
|
Name: 御津凪 [URL] ..熟練のプログラマー(61,430ポイント)
Date: 2009/02/24(火) 10:48
No:29213
|
|
Title: Re:敵のパターンを実装する方法について
|
|
> 期待する動きとしては 指定したフレーム数でプレイヤーの前の位置 (x,y) に移動する
であれば、
// 敵と自機との直線上で、自機の前の座標を計算する
float CalcPlayerBeforePos(
float enemyX, // 敵のX位置
float enemyY, // 敵のX位置
float playerX, // 自機のX位置
float playerY, // 自機のX位置
float length, // 自機と計算位置との距離
float* posX, // X位置を取得するポインタ
float* posY) // Y位置を取得するポインタ
{
float dir = atan2f(enemyY - playerY, enemyX - playerX); // 自機から敵への方向角度を得る
*posX = playerX + sinf(dir) * length; // 自機の前の座標を計算
*posY = playerY + cosf(dir) * length; // 自機の前の座標を計算
return dir; // 角度(自機から敵への方向角度)を返す
}
で、プレイヤーの前の位置を計算し、
自分(敵)と計算された座標との間を、指定したフレーム数で
線形補間なり、 sin, cos 関数で移動位置を計算するといいと思います。
この場合、計算時のプレイヤーの位置を計算するので、常にプレイヤーの前に来るわけではないです。
毎フレーム位置を計算しておけば、常にプレイヤーの前に張り付きに来ます。
その場合、プレイヤーが瞬間移動・高速移動をすると違和感はでてしまいますが。
(ちなみに距離を0にして、弾の軌道に毎フレーム計算するように使うと、回避不可のホーミング弾になります^^)
340ポイント を手に入れた。
|
|
|
|
|
Name: Dixq (管理人) ..伝説なるハッカー(995,657ポイント)
Date: 2009/02/24(火) 14:03
No:29214
|
|
Title: Re:敵のパターンを実装する方法について
|
|
どういう処理も美しい軌跡を描こうとすると難しくなったりします。
さしあたり4種類考えられると思います。
・敵が現れる瞬間、目標地点を設定し、等速直線でその地点へ移動する
・敵が現れる瞬間、目標地点を設定し、加速、減速してその地点へ移動する
・プレイヤーが動き回るごとに常に軌道修正し、等速で常にホーミングする
・プレイヤーが動き回るごとに常に軌道修正し、美しくホーミングする
上が簡単で、下に行くほど難しいと思います。
一番上は作れますか?
敵の座標と自機の座標から角度を出すにはatan2を使うと簡単です。
2番目は入門レベルの物理の知識があれば出来ると思います。
移動すべき合計距離は
v0を初速度、aを加速度、t1を加速する時間、t2を等速移動する時間とすると
※14:20訂正
このグラフのt2はt1+t2のこと、t3はt1+t2+t1のことです。訂正しますm(_ _)m
v1 = v0+a*t1
v2 = v1
v3 = v2+(-a)*t1
これらのtの積分の和になります。積分すると距離になるので
x1 = v0*t1 + 0.5*a*t1*t1(ピンクの部分)
x2 = v1*t2(青の部分)
x3 = v2*t1 - 0.5*a*t1*t1(緑の部分)
これをv0=0としわかりやすくすると
x = a*t1*t1 + v1*t2
となります。
こうしてaを導き出し、それにあった距離を計算してそちらに飛ばしてやったらよいでしょう。
363ポイント を手に入れた。
|
|
|
|
|
Name: dic ..中級者(14,402ポイント)
Date: 2009/02/24(火) 16:37
No:29234
|
|
Title: Re:敵のパターンを実装する方法について
|
|
>御津凪さん回答ありがとうございます
なるほど
プレイヤーの前の位置の座標を計算し、そこに進むようにすればいいのですね
細かい計算までありがとうございます
>管理人さん回答ありがとうございます
1敵が現れる瞬間、目標地点を設定し、等速直線でその地点へ移動する
2敵が現れる瞬間、目標地点を設定し、加速、減速してその地点へ移動する
3プレイヤーが動き回るごとに常に軌道修正し、等速で常にホーミングする
4プレイヤーが動き回るごとに常に軌道修正し、美しくホーミングする
4パターンあるんですね
難易度のもっとも高い4番を目指してました
1,2はなんとかできそうです
3,4はちょっと時間がかかりそうです
もう一度チャレンジしてみようかと思います
回答ありがとうございました
321ポイント を手に入れた。
|
|
|
|
Name: toshi ..ぴよぴよ(127ポイント)
Date: 2009/02/24(火) 14:15
No:29215
|
|
Title: コンマで区切られた入力
|
|
名前、学籍番号、得点(5教科)がコンマで区切られているデータが10人分ある。平均点の高い順にソートして、60点以上が合格する。1教科でも0点があれば、不合格となる。このプログラムを作成せよ。という問題なのですが、コンマで区切るのではなく、空白で区切る問題なら
#include <stdio.h>
#include <math.h>
#define N 50
main()
{
int i,l,n,s,j,m,max1,max4,max5,max6,max7,max8;
int E[N],K[N],M[N],R[N],S[N],G[N],H[N];
char *name[N][10], *bangou[N][10],*max2,*max3;
for(i=0;i<N;i++){
s=scanf("%s %s %d %d %d %d %d",&name[i][0],&bangou[i][0],&E[i],&K[i],&M[i],&R[i],&S[i]);
if(s == EOF) break;
}
n=i;
for(i=0;i<n;i++){
G[i] = E[i] + K[i] + M[i] + R[i] + S[i];
H[i] = G[i] / 5;
}
for(j=0;j<i;j++){
for(m=i;m>j;m--){
if(H[m] > H[m-1]){
max1 = H[m];
max2 = name[m][0];
max3 = bangou[m][0];
max4 = E[m];
max5 = K[m];
max6 = M[m];
max7 = R[m];
max8 = S[m];
H[m] = H[m-1];
E[m] = E[m-1];
K[m] = K[m-1];
M[m] = M[m-1];
R[m] = R[m-1];
S[m] = S[m-1];
name[m][0] = name[m-1][0];
bangou[m][0] = bangou[m-1][0];
H[m-1] = max1;
E[m-1] = max4;
K[m-1] = max5;
M[m-1] = max6;
R[m-1] = max7;
S[m-1] = max8;
name[m-1][0] = max2;
bangou[m-1][0] = max3;
}
}
}
for(l=0;l<i;l++){
if(H[i]<60 || K[i] = 0 || E[i] = 0 || S[i] = 0 || M[i] = 0 || R[i] = 0){
printf("%s,%s,%d,%d,%d,%d,%d,%d,不合格\n",
name[l],bangou[l],E[l],K[l],M[l],R[l],S[l],H[l]);
}
else printf("%s,%s,%d,%d,%d,%d,%d,%d,合格\n",
name[l],bangou[l], E[l],K[l],M[l],R[l],S[l],H[l]);
}
}
このようなプログラムで上手くいくのですが、コンマで区切られたデータを
scanf("%s %s %d %d %d %d %d",&name[i][0],&bangou[i][0],&E[i],&K[i],&M[i],&R[i],&S[i]);
のように変数に代入するには、どうすればいいのでしょうか。教えてください。
127ポイント を手に入れた。
|
|
|
|
Name: non ..プログラマー(37,833ポイント)
Date: 2009/02/24(火) 14:39
No:29216
|
|
Title: Re:コンマで区切られた入力
|
|
添付されたプログラムは正しく動かないのではないでしょうか?
とりあえず、動くプログラムにして、タグで囲ってプログラムを載せてもらえませんか。
59ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(7,548ポイント)
Date: 2009/02/24(火) 14:54
No:29218
|
|
Title: Re:コンマで区切られた入力
|
|
質問者さん
コードの掲載には<pre>タグを使ってもらえると嬉しいです。
> コンマで区切られたデータを
> scanf("%s %s %d %d %d %d %d",&name[i][0],&bangou[i][0],&E[i],&K[i],&M[i],&R[i],&S[i]);
> のように変数に代入する
とりあえず、コードは無視してこの部分だけ。
空白のときと同様に「基本的には」scanf("%d,%d,%d", ...)とすれば、カンマ区切りで入力できます。
だたし、「%s」(文字列)を受ける場合には、カンマも文字列として読み込んでしまうので、カンマは受け取らないようにする必要があります。
具体的には走査文字集合%[...] を使って、入力文字列%[^,\n] とでも指定すればいいわけです。
ただ、あまり一般的ではないので、手動で分割するかstrtok()関数を使ってみてもいいと思います。
211ポイント を落としてしまった。
|
|
|
|
|
Name: toshi ..ぴよぴよ(219ポイント)
Date: 2009/02/24(火) 15:27
No:29224
|
|
Title: Re:コンマで区切られた入力
|
|
返信ありがとうございます。
strtok(a,',');
のようにして、,区切りで分割した後にそれぞれの語句を
scanf("%s %s %d %d %d %d %d",&name[i][0],&bangou[i][0],&E[i],&K[i],&M[i],&R[i],&S[i]);
のように変数に代入することは出来るのでしょうか。教えてください。
92ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(7,677ポイント)
Date: 2009/02/24(火) 15:55
No:29225
|
|
Title: Re:コンマで区切られた入力
|
|
strtokで分割した語句は"text\0"のように、語句が一つの文字列になります。
文字列を数値に変換するには、atoi関数やstrtol関数を使用します。
41ポイント を手に入れた。
|
|
|
|
|
Name: kazuoni [URL] ..熟練のプログラマー(62,455ポイント)
Date: 2009/02/24(火) 16:00
No:29227
|
|
Title: Re:コンマで区切られた入力
|
|
とりあえずソートなしで作ってみました。
コメントなしなんで、解析頑張ってくださいw
(参考になるかといったらならないと思いますが・・・)
丸コピはやめたほうがいいです。
なんせ、人生で初めてgoto文(ジャンプ命令)をわざと使ったりしてますんでw
こういう課題は例外処理をつけてるとキリがないですね。
[,]が6個なかったら再入力を正しますけど、データの順番が
文列,文列,数字,...
でなくてもコンマ数さえ合ってれば通ってしまいます。
完全なる妥協です。ご勘弁。
>走査文字集合
ちょっとこれは知りませんでした・・・(えっ
参考になります^^;
163ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(7,944ポイント)
Date: 2009/02/24(火) 16:19
No:29230
|
|
Title: Re:コンマで区切られた入力
|
|
スキャン文字集合とも言いますね。
#include <stdio.h>
int main(void)
{
char str[32];
int a, b, c;
scanf("%[^,],%d,%d,%d", str, &a, &b, &c);
printf("%s,%d,%d,%d\n", str, a, b, c);
return 0;
} こんな感じです。
%[^,\n] のように改行文字を指定しても意味はないのでした(笑)
182ポイント を手に入れた。
|
|
|
|
|
Name: toshi ..ぴよぴよ(294ポイント)
Date: 2009/02/24(火) 16:20
No:29231
|
|
Title: Re:コンマで区切られた入力
|
|
返信ありがとうございます。strtokで,で区切られたデータを分解した後、どのようにすれば、文字列のまま使う分と、atoi関数を使い数値に変換する分を分ければよいのですか。教えてください。お願いします。
75ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(8,042ポイント)
Date: 2009/02/24(火) 16:23
No:29232
|
|
Title: Re:コンマで区切られた入力
|
|
toshiさん
文字列と数値の並び順が一定なら、ifで条件を分ければいいでしょう。あまりスマートではないかも知れませんが・・・
それと、言い忘れていましたが、コンマ区切りのデータを読み込む方法が龍神録プログラミングの方で紹介されています。
98ポイント を手に入れた。
|
|
|
|
Name: センター ..ぴよぴよ(4ポイント)
Date: 2009/02/24(火) 00:31
No:29201
|
|
Title: DxLib_VC2008_and_2005用.slnについて
|
|
DXライブラリをダウンロードしたのはいいのですが、
DxLib_VC2008_and_2005用.slnというファイルが開けません。
右クリックで開くを押しても駄目でした。
分かる人、教えてください。
4ポイント を手に入れた。
|
|
|
|
Name: cosmo ..入門者(3,893ポイント)
Date: 2009/02/24(火) 00:52
No:29202
|
|
Title: Re:DxLib_VC2008_and_2005用.slnについて
|
|
開発環境はインストールされていますか?
DXライブラリに加えて開発環境もインストールする必要があります。
Visual C++ 2008 Express Edition やその2005年版があれば、開けるはずですけど…
75ポイント を手に入れた。
|
|
|
|
|
Name: センター ..ぴよぴよ(22ポイント)
Date: 2009/02/24(火) 01:01
No:29203
|
|
Title: Re:DxLib_VC2008_and_2005用.slnについて
|
|
Visual C++ 2008 Express Edition はすでにインストールされています。
18ポイント を手に入れた。
|
|
|
|
|
Name: cosmo ..入門者(4,191ポイント)
Date: 2009/02/24(火) 01:17
No:29205
|
|
Title: Re:DxLib_VC2008_and_2005用.slnについて
|
|
荒療治ですが…、
slnファイルを削除してVC++プロジェクトの方をクリックして開くと言う方法もあります。
VC++ EE 2008でVisual Studio 2005で作成されたプロジェクトが開けないってことですか?
「vcprojはインストールされていません」というエラーメッセージならば、
上記の方法で解決出来るかもしれません。
2倍のポイントを手に入れた! 298ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(321,113ポイント)
Date: 2009/02/24(火) 01:27
No:29206
|
|
Title: Re:DxLib_VC2008_and_2005用.slnについて
|
|
>Visual C++ 2008 Express Edition はすでにインストールされています
なるほど。
では、別のアプローチでも。
slnファイルファイルを右クリックしてプロパティを選択して、そのファイルの
プロパティウインドウを表示してください。
そこで「プログラム」の項目が「Microsoft Visual Studio Version Selector」になって
いるかどうかを確認してください。
もし、そうなっていなければ変更する必要があります。
近くにある変更ボタンを押して「ファイルを開くプログラムの選択」
ダイアログを表示して、現れた一覧から「Microsoft Visual Studio Version Selector」を
探して選択してください。
一覧にない場合は「参照」ボタンを押して
C:\Program Files\Common Files\Microsoft Shared\MSEnv\VSLauncher.exe
の実行ファイルを選択してください。
これで「プログラム」の項目が「Microsoft Visual Studio Version Selector」になるので
この状態で最初のプロパティウインドウの「適用」ないしは「OK」を押せば完了です。
多分これでダブルクリックで開けるようになる……はずです。
「プログラム」の項目が「Microsoft Visual Studio Version Selector」だとしたら、
他の方が書かれているように VisualStudioのファイルメニューから開くようにするか、
VisualStudioのウインドウに Drag&Dropするか、或いは VisuaStudioを再インストールするか、
してみてください。
ところでOSは何ですか?
Vistaだとまた別の原因があったりするのですが。
2倍のポイントを手に入れた! 1,192ポイント を手に入れた。
|
|
|
|
|
Name: センター ..ぴよぴよ(112ポイント)
Date: 2009/02/24(火) 01:30
No:29207
| 解決!
|
Title: Re:DxLib_VC2008_and_2005用.slnについて
|
|
VC++から開いたらできました。
旧バージョンで作られていたので開けなかったようでした。
ありがとうございました。
2倍のポイントを手に入れた! 90ポイント を手に入れた。
|
|
|
|
|
Name: cosmo ..入門者(4,627ポイント)
Date: 2009/02/24(火) 01:45
No:29208
|
|
Title: Re:DxLib_VC2008_and_2005用.slnについて
|
|
すっかり忘れていたのですが、私の環境でもこの動作は起こります。
前にも投稿しました。
その時は直ったと思ったんですけど…
>>Justyさん
>「プログラム」の項目が「Microsoft Visual Studio Version Selector」になって
>いるかどうかを確認してください。
についてですけど、私の環境(XP SP3・Visual Studio Professinal アカデミック)の場合では、
Visual Studio 2005とVC++ EE 2005のソリューションの場合にのみ起きます。
VC++ 6.0・Visual Studio 2003版のプロジェクトは正常に変換できますけど…。
「プログラム」の項目が「Microsoft Visual Studio Version Selector」になっていても、
ダブルクリックしても開けません。
「vcprojはインストールされていません」というエラーメッセージが出て、
ソリューションエクスプローラに利用不可と出てしまいます。
slnファイルを削除してVC++プロジェクトの方をクリックして開くと無事に開けるんですけどね…。
う〜ん…Visual Studio 2008が2005年版のソリューション形式に対応していないという事でしょうか…?
436ポイント を手に入れた。
|
|
|
|
|
Name: Justy ..伝説なるハッカー(321,501ポイント)
Date: 2009/02/24(火) 02:19
No:29209
|
|
Title: Re:DxLib_VC2008_and_2005用.slnについて
|
|
>Visual Studio 2005とVC++ 2005のソリューションの場合にのみ起きます
うーん、不思議ですね。
>ソリューションエクスプローラに利用不可と出てしまいます
ということは slnは変換・開けていて、vcprojが読み込めていないという状態のようですね。
(多分問題ないとは思いますが)slnファイルをエディタで開いて vcprojファイルのパスとか名前、
GUIDとか構成が合っているかどうか、など見てみてはどうでしょうか。
>Visual Studio 2008が2005年版のソリューション形式に対応していないという事でしょうか
そんなことはない、と思うんですけどね。
うちの環境(XP sp3 / VS2008std sp1)では 2005は普通に変換できますんで。
TeamEditionだと 2005からの変換で何か問題があったようですが(SP1で修正)、
std/proだと関係ないでしょうし……。
388ポイント を手に入れた。
|
|
|
|
|
Name: cosmo ..入門者(4,822ポイント)
Date: 2009/02/24(火) 02:35
No:29210
|
|
Title: Re:DxLib_VC2008_and_2005用.slnについて
|
|
slnファイルをエディタで開いた時に
「Microsoft Visual Studio Solution File, Format Version 9.00」
の部分で、Format Version 9.00となっていると上手く読み込めないですが、
Format Version 8.00と変えてみると読み込めました。
龍神録プロジェクトの27章を使ってやってみました。
構成とかは特に問題なかったと思います。
VC++ 2008 EEを使っていた時はこんな事は起こらなかったんですけど…
すいません、開発環境は
Visual Studio 2008 Professioal アカデミック SP1
でした。
↑センターさんも同じエラーメッセージを出したんでしょうか…?
そんな雰囲気のお礼の書き込みですが。
195ポイント を手に入れた。
|
|
|
|
|
Name: cosmo ..入門者(4,998ポイント)
Date: 2009/02/24(火) 10:33
No:29212
| 解決!
|
Title: Re:DxLib_VC2008_and_2005用.slnについて
|
|
追記です。
私の環境ではVC++ EEではVS 2005のslnファイルを変換できた覚えがあったので、
Visual Studio 2008 Professional アカデミックと
VC++ EEを共存させるという方法を試みてみました。
Microsoft Visual Studio Version SelectorとVC++ EEの実行ファイルを
同じフォルダにインストールすると言うちょっと豪快な方法を試してみました。
すると、今までのエラーメッセージが出る事が無くなり、
無事にVS 2005のslnファイルを変換をVisual Studio 2008 Professional アカデミックで、
変換する事が出来ました。
本当は別のスレを立てるべきだったのでしょうけど…、
取り敢えず解決しました。
176ポイント を手に入れた。
|
|
|
|
Name: 馬鹿太郎 ..かけだし(1,794ポイント)
Date: 2009/02/23(月) 21:35
No:29190
|
|
Title: ポインタ
|
|
#include <stdio.h>
#include <string.h>
void main()
{
char array[7];
char *ptr;
/**
* char配列に、文字列をコピーする
*/
strcpy(array, "abcdef");
/**
* char ポインタに、char配列の先頭のアドレスをコピーする
*/
ptr = &(array[0]);
/**
* char ポインタに、文字列をコピーする
*/
strcpy(ptr, "ghijkl");
/**
* char 配列、char ポインタをそれぞれ文字列形式で表示する
*/
printf(" array = %s\n ptr = %s\n", array, ptr);
}
実行したら、
array=abcdef
ptr=ghijkl
となりました。
ポインタptrはアドレスしか格納できないですよね?
strcpy(ptr, "ghijkl");
は変数ptrにghijklをコピーするのでしょうか?
228ポイント を手に入れた。
|
|
|
|
Name: box ..ハッカー(136,042ポイント)
Date: 2009/02/23(月) 21:47
No:29193
|
|
Title: Re:ポインタ
|
|
全角空白で「インデントもどき」は、お控えいただけますでしょうか。
1)strcpy(array, "abcdef"); の実行後
+-----+-----+-----+-----+-----+-----+-----+
array | [0] | [1] | [2] | [3] | [4] | [5] | [6] |
| 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | '\0'|
+-----+-----+-----+-----+-----+-----+-----+
2)ptr = &(array[0]); の実行後
ptr
|
v
+-----+-----+-----+-----+-----+-----+-----+
array | [0] | [1] | [2] | [3] | [4] | [5] | [6] |
| 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | '\0'|
+-----+-----+-----+-----+-----+-----+-----+
3)strcpy(ptr, "ghijkl"); の実行後
ptr
|
v
+-----+-----+-----+-----+-----+-----+-----+
array | [0] | [1] | [2] | [3] | [4] | [5] | [6] |
| 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | '\0'|
+-----+-----+-----+-----+-----+-----+-----+
ptr が指している場所(つまり array[] の先頭)から7バイト分に
"ghijkl" (終端の'\0'を含む)を格納します。
2)を省略して3)を実行すると、どこを指しているかわからない ptr に
"ghijkl" を格納しようとするため、うまく実行できないことがあると思います。
2)を省略する場合は3)のかわりに
ptr = "ghijkl";
と書くのでありましょう。
93ポイント を落としてしまった。
|
|
|
|
|
Name: SCI ..初心者(7,661ポイント)
Date: 2009/02/23(月) 21:56
No:29194
|
|
Title: Re:ポインタ
|
|
その場合、ptrは「char配列の先頭へのポインタ」です。
つまり、ptr == &(array[0]) == array なので、strcpy(array, "ghijkl");と同じことです。
49ポイント を手に入れた。
|
|
|
|
Name: ホリック ..ぴよぴよ(829ポイント)
Date: 2009/02/22(日) 21:53
No:29159
|
|
Title: 初歩的な質問ですみませんが・・・
|
|
プログラミングの館を参考にしながら自分なりにすこしづつプログラムを作っているのですが、
背景がある場合とない場合によってキャラをキー操作によって動かしているときのスピードが違うのですが、
これを解消する方法はないでしょうか。
これからのことを考えるとそのうちキャラの動きがすごく遅くなるような気がするので、
早いうちに対処しておきたいです。
一応背景がある場合のプログラムを載せておきます。
#include "DxLib.h"
typedef struct{
int x,y,img;
}ch_t;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
int image[16];
char Key[256];
ch_t ch;
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
//if( DxLib_Init() == -1 ) return -1; //初期化処理
ch.x =320;
ch.y =240;
SetDrawScreen( DX_SCREEN_BACK ) ;//描画先を裏画面に設定
LoadDivGraph( "../../dat/char.png" , 16 , 4 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存
ch.img =image[8];
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されると終了
LoadGraphScreen( 0 , 0 , "../../dat/back0.png" , FALSE ) ;//背景
if ( Key[ KEY_INPUT_UP ] == 1 ){ //上ボタンが押されたら
ch.y--; //上向きならch.y座標を減らす
ch.img=image[0];
}
else if( Key[ KEY_INPUT_LEFT ] == 1 ){ //左ボタンが押されたら
ch.x--; //左向きならch.x座標を減らす
ch.img=image[4];
}
else if( Key[ KEY_INPUT_DOWN ] == 1 ){ //下ボタンが押されたら
ch.y++; //下向きならch.y座標を増やす
ch.img=image[8];
}
else if( Key[ KEY_INPUT_RIGHT] == 1 ){ //右ボタンが押されたら
ch.x++; //右向きならch.x座標を増やす
ch.img=image[12];
}
DrawGraph( ch.x , ch.y , ch.img , TRUE ) ;
ScreenFlip();
}
WaitKey() ; // キーが押されるまで待つ
DxLib_End(); //DXライブラリの終了処理
return 0;
}
775ポイント を手に入れた。
|
|
|
|
Name: Justy ..伝説なるハッカー(320,011ポイント)
Date: 2009/02/22(日) 22:14
No:29162
|
|
Title: Re:初歩的な質問ですみませんが・・・
|
|
>背景がある場合とない場合によってキャラをキー操作によって動かしているときのスピードが違う
背景の表示に LoadGraphScreen()が使われています。
この関数は呼ばれる度にファイルにアクセスし読み込み・展開してから表示するので
一般的にはメインループ内で使うことのない関数です。
LoadGraph()〜DrawGraph()などを使って読み込み&表示することで改善されると思います。
130ポイント を手に入れた。
|
|
|
|
|
Name: s-rush ..プログラマー(30,035ポイント)
Date: 2009/02/22(日) 22:27
No:29165
|
|
Title: Re:初歩的な質問ですみませんが・・・
|
|
背景を描画するのにLoadGraphScreen関数を使用しているからだと思います。
ファイルへのアクセス時間がかかってしまうために、動きが遅くなってしまいます。
メモリに保存して、それを表示するプログラムに改良すれば、動きがスムーズになりますよ。
詳しくはゲームプログラミングの館 第14章をご覧ください。
一応サンプル載せておきます。
#include "DxLib.h"
typedef struct{
int x,y,img;
}ch_t;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
int image[16];
int back; //背景の格納用変数
char Key[256];
ch_t ch;
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
//if( DxLib_Init() == -1 ) return -1; //初期化処理
ch.x =320;
ch.y =240;
SetDrawScreen( DX_SCREEN_BACK ) ;//描画先を裏画面に設定
LoadDivGraph( "../../dat/char.png" , 16 , 4 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存
back = LoadGraph( "../../dat/back0.png" ) ;
ch.img =image[8];
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されると終了
DrawGraph( 0 , 0 , back , FALSE ) ; //背景を表示
if ( Key[ KEY_INPUT_UP ] == 1 ){ //上ボタンが押されたら
ch.y--; //上向きならch.y座標を減らす
ch.img=image[0];
}
else if( Key[ KEY_INPUT_LEFT ] == 1 ){ //左ボタンが押されたら
ch.x--; //左向きならch.x座標を減らす
ch.img=image[4];
}
else if( Key[ KEY_INPUT_DOWN ] == 1 ){ //下ボタンが押されたら
ch.y++; //下向きならch.y座標を増やす
ch.img=image[8];
}
else if( Key[ KEY_INPUT_RIGHT] == 1 ){ //右ボタンが押されたら
ch.x++; //右向きならch.x座標を増やす
ch.img=image[12];
}
DrawGraph( ch.x , ch.y , ch.img , TRUE ) ;
ScreenFlip();
}
WaitKey() ; // キーが押されるまで待つ
DxLib_End(); //DXライブラリの終了処理
return 0;
}
875ポイント を手に入れた。
|
|
|
|
|
Name: Dixq (管理人) ..伝説なるハッカー(991,935ポイント)
Date: 2009/02/18(水) 19:56
No:28982
|
|
Title: Re:管理人さんへ、質問します。
|
|
技術というほどのスキルは持ち合わせていませんが、エフェクトの使い方、プログラムの書き方などはほとんど試行錯誤です。
龍神録はほとんど東方を模倣してるので、東方をかなり参考にしました。
他にもキレイなエフェクト作りたい時は、市販ゲームを見たりして参考にしてます。
格ゲーとかみてたら手軽にエフェクトが見れるので、よく格ゲーの動画とか見てキャプチャしてエフェクトがどうなってるか勉強したりします。
今現在で言えば、ホーミングミサイルのカッコイイ出し方試行錯誤してるんですが、
スパロボ、マクロス、エヴァ・・ネットにある板野サーカスみてどうすればいいか悩んでます。
簡単な方程式で導ける軌跡を描いたんじゃ面白くないので、
沢山軌跡の点を打ってベジェ曲線みたいな曲線でつなげるか、いくつかあらかじめパターンある軌跡を作っておくか、勢いよく発射することでホーミングしないでよくするか・・・沢山プログラム書いてみて、
採用できそうな方法を見つけ出そうとしています。
恐らく人が開拓した道を進むのも良い手段なのでしょうけど、私は試行錯誤するのが好きです。
35ポイント を手に入れた。
|
|
|
|
|
Name: taka41 ..ぴよぴよ(614ポイント)
Date: 2009/02/23(月) 19:48
No:29187
|
|
Title: Windowsプログラミングでしたか?
|
|
私は、Windowsプログラミングについては、全く知識ありません。管理人さんのソースコードを見て、初めて知りえました。恥ずかしい限りです。むしろ、見っともないです。私は、int,char,long,double,ポインタ、for,while等のループ,ファイルポインタの教育ばかりを強調されてきました。つまり、只の変数プログラムです。当時の私の周りの人間は、コンピューターは、おろかBasicすら扱う人間が、いませんでした。私の今の在住する地域には、昔からソフトウェアの概念すらなくて、産業といえば、機械・建築・土木、各種製造業の中心の街だったのでした。今も尚、その傾向があります。今は、パソコン文化が、ありますが、それでも、word,Excel,internet,PowerPointが、コンピューターと思っている方々が、幅を利かせている街です。IT文化の根付き難い土地柄です。つまり、生まれが、悪かったのです。
だから、管理人さんのホームページは、新鮮に感じたし、何よりも衝撃的でした。画像や音声を操れる、管理人さんのゲームのソースコードは、魅力的でした。
変数プログラミングばかりを強調されてきたために、ソフト会社への就職は、叶わず(それでも、過去に数度そのチャンスがありました。)、今も尚、ソフトとは、関係ない仕事をせざるを得ないのです。
Windowsプログラムは、知れば知るほど、きりがありませんが、ゲームが、自作できる環境が、ここにあることは、素晴らしい事です。
558ポイント を手に入れた。
|
|
|
|
|
Name: Dixq (管理人) ..伝説なるハッカー(994,963ポイント)
Date: 2009/02/23(月) 22:10
No:29196
|
|
Title: Re:Windowsプログラミングでしたか?
|
|
生まれって関係あるんですかねぇ・・。
親がパソコン持ってないと幼い頃パソコンを使う機会が無いとか、
田舎だとネットの回線が遅いとかそういう事はあるかもしれませんが、
地域の産業が機械・建築・土木・・・だったからってのは関係ないと思いますよ。
私の生まれた村なんて中国山地の山の奥、近くのコンビニには自転車で往復4時間かけていかないと無いほど近くになんにもない究極な田舎でした。
社会の教科書で「今過疎化が進んでる地域」と紹介されるほどに。
もちろんまわりにはパソコン使ってる人も居ないし、そんなIT企業なんてあるわけなく、みんな米作ってばっかりです。
逆にどんなにIT企業が発達している街中周辺で育ったとしても、例えば大阪で言ったら新大阪や本町のど真ん中のマンションで育ったとしても、家にいてその影響を受けてプログラムが出来るようになるかといったら疑問です。
パソコンってネットが繋がってたら世界に通じてるわけですし、あまり都会・田舎、まわりの発達してる産業がどうのってのは、それを職業にしない限り関係ないのでは?
>>....,long,double,ポインタ、for,while等のループ,ファイルポインタの教育ばかりを強調されてきました。
という事はそういう学校に通われたということでしょうか?
私もそうでした。データ構造やアルゴリズムなど、面白くないことばっかりでした。
線形リストだったり基数ソートだったり、散々悩んで変化させた変数の値を表示するだけで
全く魅力を感じませんでした。でもそれってただC言語の基礎なんですよね。
大学とかではゲーム制作関連のことは全く教わってません。そういう学科でも無いですし。
しかしせっかくC言語を学んでるのだから、もっと有効に使えないかと色々調べているうちにDXライブラリに出会い、ゲーム作成の面白さに惹かれました。
プログラムの本来の機能は数値計算ですし、(変数プログラミングという言葉があるのかどうか解りませんが、この言葉を借りるとすると)基礎である変数プログラミングを教わる事は当然であり、
そこから色んな可能性を広げていくのは自分の仕事だと思います。
中学の時、社会人として育っていく前に基礎的なことを教わりますよね。
社会人になってから、人から今就いている職業よりもっと面白そうな職業を聞いて興味持ったからといって中学の先生のせいじゃないと思います。
基礎を学んだら、次に何が出来るか調べるのは自分であり、みんなそうしていると思います。
同じ授業を受け、大学からはその変数プログラミングばかりを強調された環境にいましたが、
ゲームプログラムを自分で勉強してゲーム会社に行った奴はいます。
それにゲーム会社が求めている入社時のプログラミング能力なんてごく基礎的なもので、本気になれば1ヶ月もあれば辿りつくと思います。
むしろプログラミング能力を特に問わないところもありますし。
ですから
>>今も尚、ソフトとは、関係ない仕事をせざるを得ないのです。
とありますが、挑戦してみることもできるのではないでしょうか?
※
変数プログラミングっていうよりGUIやAPIを使わない標準関数のみで作るプログラムってことじゃないでしょうか?
変数を扱う量が多いかどうかは無関係な気がします。
1,016ポイント を手に入れた。
|
|
|
|
Name: lbfuvab ..上級者(18,222ポイント)
Date: 2009/02/22(日) 21:52
No:29158
|
|
Title: オセロでNegaAlpha法
|
|
オセロを組んでいて今までNegaMax法を使っていたのですが、
アルファベータ法の方が効率的ということで、http://ray.sakura.ne.jp/search_problem/を参考にアルファベータ法+ネガマックス法を組んでみたのですが
うまく行きません。
というのも、コンパイルはうまく行くのですが、NegaMax法の時と全然違う手を打ってきます。(深さ及び評価関数は同じ)
悪い点を教えてください。
環境はWinXP+VC++2008EEです。
#define SEARCH_DEPTH 6
bool CanPutAnyWhere(void); //どこかに打てるのか
bool CanPut(x,y); //そこに打てるのか
int Put(int x,int y); //駒を打つ
int UndoPut(int x,y); //打った駒を戻す
bool IsEnd(int *result); //終わっていたらtrueを返す。resultは勝ち負けの格納用
int Eval(void); //その時の評価値を返す
void PutCPU(void); //NegaAlphaの使用例
int NegaAlpha(int depth=0,int a=-10000,int b=10000); //問題の関数
typedef struct{
int x,y;
} Place_t; //場所用の構造体
int Board[8][8]; //オセロの盤
Place_t Next; //次の手の格納用
int NegaAlpha(int depth,int a,int b){
int x,y,val,result;
if(depth==0){ //最初に呼び出された時
for(x=0;x<8;x++){
for(y=0;y<8;y++){
if(CanPut(x,y)){
Put(x,y);
val =-NegaAlpha(depth+1,-b,-a);
UndoPut();
if(val>=a){
Next.x=x;
Next.y=y;
a=val;
}
if(a>=b){
Next.x=x;
Next.y=y;
return a;
}
}
}
}
return a;
}
else if(depth!=SEARCH_DEPTH){
if(IsEnd(&result)==false){
if(CanPutAnyWhere()){
for(x=0;x<8;x++){
for(y=0;y<8;y++){
if(CanPut(x,y)){
Put(x,y);
val =-NegaAlpha(depth+1,-b,-a);
UndoPut();
if(val>=a)
a=val;
if(a>=b)
return a;
}
}
}
return a;
}
else{
Pass();
val = -NegaAlpha(depth+1,-b,-a);
UndoPut();
return (a>val)?a:val;
}
}
else{ //既に終了
if(result==turn)
return 1000; //勝ってたら最高の評価
else if(result==DRAW)
return 0; //引き分けは・・・どうなんだろう?
else
return -1000; //負けは出来れば避けたい
}
}
else //葉の時は
return Eval();
}
void PutCPU(void){
NegaAlpha();
Put(Next.x,Next.y);
}
1,671ポイント を手に入れた。
|
|
|
|
Name: box ..ハッカー(136,135ポイント)
Date: 2009/02/22(日) 22:03
No:29160
|
|
Title: Re:オセロでNegaAlpha法
|
|
>int NegaAlpha(int depth=0,int a=-10000,int b=10000); //問題の関数
この関数の引数の意味を説明してくださると、
回答しようとしている方々の助けとなるかもしれません。
81ポイント を手に入れた。
|
|
|
|
|
Name: lbfuvab ..上級者(18,415ポイント)
Date: 2009/02/22(日) 22:23
No:29164
|
|
Title: Re:オセロでNegaAlpha法
|
|
あ、すいません。
depthは深度です。
ですから最初呼び出す時0です。
aはアルファ値です。
ですから最初は十分に小さくないといけないので-10000にしています。(どんなに悪い状況でも-10000を割る事はないので)
bはベータ値です。
ですから最初は十分に大きくないといけないので10000にしています。
デフォルト引数を付けたのはこっちのほうが呼び出す時に
NegaAlpha(0,-10000,10000);とするより
NegaAlpha();の方がすっきりすると思ったからです。
193ポイント を手に入れた。
|
|
|
|
Name: JT ..かけだし(2,296ポイント)
Date: 2009/02/18(水) 10:04
No:28927
|
|
Title: ソケット通信(vbからはじめる)
|
|
おはようございます。C言語のソケット通信を学び終え、人に教えようと分かりやすくVBで作成しているんですがwinsockコンとロールの使用方法のconnect処理が分かりません。場違いな質問ですいませんが教えていただけないでしょうか? 環境/vb6.0
115ポイント を手に入れた。
|
|
|
|
Name: JT ..かけだし(2,355ポイント)
Date: 2009/02/18(水) 10:29
No:28929
|
|
Title: Re:ソケット通信(vbからはじめる)
|
|
バグさんありがとうございます。ここを参考にしてローカルポートを取得しようとWin_recv.LocalPort = Txt3.Text という一文を書いているんですが既に値が入っていて中止になります。初期化はしているんですが疑問です
59ポイント を手に入れた。
|
|
|
|
|
Name: JT ..かけだし(2,454ポイント)
Date: 2009/02/18(水) 11:20
No:28930
|
|
Title: Re:ソケット通信(vbからはじめる)
|
|
画面上ではサーバとクライアントで一つずつコントロールを持っていてクライアントソケットボタン(コマンドボタン2)を押下したらテキストデータにいれた文字がサーバから返ってくる処理になります。会社で使っているものなのでここに置いてはいけないんですがsockman.exeという仮想通信で現在作成しているんですがクライアントの送受信が実行時エラー”400006”とでて解説を見たんですが理解できません ご教示お願いします
99ポイント を手に入れた。
|
|
|
|
|
Name: JT ..入門者(2,521ポイント)
Date: 2009/02/18(水) 15:39
No:28955
|
|
Title: Re:ソケット通信(vbからはじめる)
|
|
ソースは簡易版ですが上記のサイトに乗せたとおり書き終えたと思います。ただcomsockman.exeを用いてのTEST方法(仮想通信)が分かりません。クライアントとサーバが今ひとつわかっていないのかもしれないです
67ポイント を手に入れた。
|
|
|
|
|
Name: JT ..入門者(3,338ポイント)
Date: 2009/02/23(月) 15:53
No:29184
| 解決!
|
Title: Re:ソケット通信(vbからはじめる)
|
|
自己解決しました”ありがとうございます
2倍のポイントを手に入れた! 40ポイント を手に入れた。
|
|
|
|
Name: 選択画面 ..ぴよぴよ(13ポイント)
Date: 2009/02/23(月) 00:24
No:29168
|
|
Title: 選択画面の作り方
|
|
早速なんですが、「四聖龍神録」みたいにプログラム起動したら
「フルスクリーンで起動しますか?」で解像度が選べるような
小さいウィンドウを作りたいんですけど、
どうやればいいんでしょうか?
Cで、DXライブラリを使っています。
誰かよろしくお願いします。
13ポイント を手に入れた。
|
|
|
|
Name: 選択画面 ..ぴよぴよ(0ポイント)
Date: 2009/02/23(月) 00:41
No:29171
|
|
Title: Re:選択画面の作り方
|
|
すばやい返答ありがとうございます。
ぜんぜん気づきませんでした。
これは「はい」や「いいえ」が作れるみたいですけど、
ラジオボタンとかも作れるんでしょうか?
76ポイント を落としてしまった。
|
|
|
|
|
Name: cosmo ..入門者(3,379ポイント)
Date: 2009/02/23(月) 02:13
No:29173
|
|
Title: Re:選択画面の作り方
|
|
かなり調べました…orz
ソースコードの最初に
#include "shlwapi.h"
#pragma comment(lib,"shlwapi.lib")(←警告を消す為)
と書いて、
void SHMessageBoxCheck(){
int flag;
flag=SHMessageBoxCheck(
NULL ,
TEXT("フルスクリーンモードで起動しますか?(推奨)") ,
TEXT("スクリーン設定") ,
MB_YESNO | MB_ICONQUESTION ,IDNO,("{… …}));
}
そして、
WINAPI WinMain(〜) {
SHMessageBoxCheck();
… …
}
と記述すれば、チェックボックスありのメッセージボックスが作れます。
隠しに近いAPIだったので、探すのに苦労しました。
但し、SHMessageBoxCheck関数はVC++ EEでは使えるか分かりません。
VC++ EEにはATLが入っていなかったと思うので…
2倍のポイントを手に入れた! 76ポイント を手に入れた。
|
|
|
|
|
Name: 選択画面 ..ぴよぴよ(83ポイント)
Date: 2009/02/23(月) 03:06
No:29175
|
|
Title: Re:選択画面の作り方
|
|
わざわざすいません。ありがとうございます。
一応、チェックボックスは作成することができました。
添付した画像のように作りたいんですが、どうでしょうか?
83ポイント を手に入れた。
|
|
|
|
|
Name: cosmo ..入門者(3,677ポイント)
Date: 2009/02/23(月) 07:57
No:29176
|
|
Title: Re:選択画面の作り方
|
|
すいません、ラジオボタンを作りたかったんですよね…
何か勘違いをしてました…orz
ところで、選択画面さんの開発環境は何ですか?
>一応、チェックボックスは作成することができました。
これだけだと良く分からないのですが…
Visual Studioをお使いですか?
次回投稿する時は規約をもう少しきちんと読んでおいてください。
↓
http://dixq.net/board/board.html
>添付した画像のように作りたいんですが、どうでしょうか?
参考になりそうなページがありました。
↓
h ttp://web.kyoto-inet.or.jp/people/ysskondo/from16/chap16.html
このソースコードを実行した時の画面(…を少しいじくったもの)が
ゲーム本来の画面が起動するより前に起動するようにして、
その画面でユーザーがした行動をゲーム本体にメッセージを送るように実装すれば良いと思います。
213ポイント を手に入れた。
|
|
|
|
|
Name: 選択画面 ..ぴよぴよ(97ポイント)
Date: 2009/02/23(月) 08:26
No:29177
| 解決!
|
Title: Re:選択画面の作り方
|
|
はい、cosmoさんの言う通りでした。
Visual C++ 2008 Express Editionです。
今後、気をつけます><
リンク先のページでわかりました。ありがとうございます。
2倍のポイントを手に入れた! 14ポイント を手に入れた。
|
|
|
|
|
Name: cosmo ..入門者(3,737ポイント)
Date: 2009/02/23(月) 08:41
No:29178
|
|
Title: Re:選択画面の作り方
|
|
追記です。
上記のぺージのソースコードを参考にそれらしきものをやっつけで作ってみました。
ウィンドウの最大化ボタンを消す事は出来ませんでしたが、
参考までに…どうぞ。
60ポイント を手に入れた。
|
|
|
|
|
Name: SCI ..初心者(7,495ポイント)
Date: 2009/02/23(月) 09:44
No:29179
|
|
Title: Re:選択画面の作り方
|
|
ダイアログリソースのお話は出ましたか?
CreateWindowで作ってもいいんですけど、予めリソースを作っておけば、MessageBox()と同じように使えますよ。
2倍のポイントを手に入れた! 140ポイント を手に入れた。
|
|
|
|
|
Name: cosmo ..入門者(3,818ポイント)
Date: 2009/02/23(月) 10:05
No:29180
|
|
Title: Re:選択画面の作り方
|
|
>>SCIさん
>CreateWindowで作ってもいいんですけど、予めリソースを作っておけば、MessageBox()と同じように使えますよ。
そんな方法もあったんですか…知らなかった…。
う〜むまだまだ知らないことが多いです…(汗)
81ポイント を手に入れた。
|
|
|
|
|
Name: 選択画面 ..ぴよぴよ(185ポイント)
Date: 2009/02/23(月) 14:16
No:29183
|
|
Title: Re:選択画面の作り方
|
|
皆さん本当にありがとうございます><。
>cosmoさんと、toyoさんのサンプルを参考にさせてもらいました。
>SCIさん貴重な意見ありがとうございます。
2倍のポイントを手に入れた! 88ポイント を手に入れた。
|
|
|
|
|