ページ 1 / 1
3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月08日(火) 01:38
by ptolemy
僕は、もう、違う質問をしていますが、それ以前につまずいたので、もう一つの質問は、保留です。
モーションを
コード:
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(FALSE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
PLAYER=MV1LoadModel("GAME/PLAYER.x");//プレイヤーのモデルをロード
HAPPO_number=MV1GetAnimIndex(PLAYER, "発砲"); //アニメーション番号取得
KAMAE_number=MV1GetAnimIndex(PLAYER, "構え(銃)");
ZENSHIN_Z_number=MV1GetAnimIndex(PLAYER, "前進(銃)");
ZENSHIN_N_number=MV1GetAnimIndex(PLAYER,"前進");
ZENSHIN_N=MV1AttachAnim(PLAYER,ZENSHIN_N_number,-1,FALSE);//アニメーションをアタッチ
ZENSHIN_Z=MV1AttachAnim(PLAYER,ZENSHIN_Z_number,-1,FALSE);
KAMAE=MV1AttachAnim(PLAYER,KAMAE_number,-1,FALSE);
HAPPO=MV1AttachAnim(PLAYER,HAPPO_number,-1,FALSE);
KAMAE_Z_Total=MV1GetAttachAnimTotalTime(PLAYER,KAMAE_number);//アニメーションの総時間を取得
HASHA_Z_Total=MV1GetAttachAnimTotalTime(PLAYER,HAPPO_number);
ZENSHIN_Z_Total=MV1GetAttachAnimTotalTime(PLAYER,ZENSHIN_Z_number);
ZENSHIN_N_Total=MV1GetAttachAnimTotalTime(PLAYER,ZENSHIN_N_number);
while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
if(移動するとき){//Player_mode==1は、武器を持っていない状態。player_mode==2は、武器を持った状態
if(Player_mode==1){
ZENSHIN_N_Playtime+=1.0f;
if(ZENSHIN_N_Playtime>=ZENSHIN_N_Totaltime)
ZENSHIN_N_Playtime=0.0f;
}else{
ZENSHIN_N_Playtime=0.0f;
}
if(Player_mode==2){
ZENSHIN_Z_Playtime+=1.0f;
if(ZENSHIN_Z_Playtime>=ZENSHIN_Z_Total){
ZENSHIN_Z_Playtime=0.0f;
}else{
ZENSHIN_Z_Playtime=0.0f;
}
}
if(Player_mode==1&&2を押したら){
KAMAE_Z_Playtime+=1.0f; //武器を持つモーションをする
if(KAMAE_Z_Playtime>=KAMAE_Z_Total){
KAMAE_Z_Playtime=0;
}
Player_mode=2;//武器を持つ
}
if(Player_mode==2&&1を押したら){
Player_mode==1;
}
if(Player_Mode==2&&弾を撃ったら){
HAPPO_Playtime+=1.0f;//弾をうつモーション
if(HAPPO_Playtime>=HAPPO_Total){
HAPPO_Playtime=0.0f;
}
MV1SetAttachAnimTime(PLAYER,ZENSIN_N,ZENSHIN_N_Playtime);
MV1SetAttachAnimTime(PLAYER,KAMAE,KAMAE_Playtime);
MV1SetAttachAnimTime(PLAYER,HASHA,HAPPO_Playtime);
MV1SetAttachAnimTime(PLAYER,ZENSHIN_Z,ZENSHIN_Z_Playtime);
}
と武器を持つモーション、撃つモーション、普通の時の歩くモーション、武器を持った時の歩くモーションを
使い分けたいんですが、これだと、武器を持った状態でかわりません。(歩いた時も、足が動かない。)
どこを変えたらいいでしょうか?
この部分を解決しないともう一つの質問が先に進みません。
あと、プログラムに書いていないものがあったらすみません。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月08日(火) 09:11
by h2so5
playtimeを0にしてもアニメーションは適用されてしまいますよ。
不要なアニメーションはDetachするかブレンド率を0にする必要があります。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月08日(火) 09:34
by softya(ソフト屋)
この件に関してはh2so5さんの言われるとおりです。
ただ、武器を持たせる事とモーションのブレンドは本質的に別問題なので、こっちが先じゃないと出来ないというのはptolemyさんの勘違いかptolemyさんの思い込みです。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月08日(火) 16:07
by ptolemy2
確かに別問題ですね。
すみませんでした。
Detachしてみます。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月12日(土) 01:39
by ptolemy
確認なんですが、playtime=0 を書いている全てのしたに Detach関数を追加するんですよね?
Detachするのは、playtime=0にしているモーションですよね?
やってみたんですが、なぜか、モデルすら描画されなくなったのでかくにんしました。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月12日(土) 11:22
by softya(ソフト屋)
ソースコードを見せて下さい。
データとソースを添えて動く形でzipしてもらっほうが回答はしやすいです。
※ 余分なものを付けるとzipが添付不能になるので注意。ソースとデータだけで良いです。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月12日(土) 14:25
by ptolemy
いいですが数日してからじゃないとアップロードできません。
すいません。一週間くらいです。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月18日(金) 15:59
by ptolemy
これです。
添付のさい、モデルのパスを変更しましたのでそこだけちがいます。
また、余計なモデルは、添付していません。
いま、いろいろとテストしてまして、保留中のものがかなりあったり、
定義が、構造化してなかったり、インデントがおかしかったりと、いろいろなダメな点が
ありますがみにくかったら、僕が後日書き直ししてまた、添付してもいいです。
なにがうまくいかないかというと、プログラムを書いたんですが、モデルすら表示されません。
何もモーションをしてないときは、モデルの手が描画されるんですが、それすらされません。
悪い点は、
どこでしょうか。
分かりずらいかもしれませんが、よろしくお願いします。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月18日(金) 20:09
by softya(ソフト屋)
ご自身でも書いてますが問題点をテストする上でプログラムコードが複雑だと思います。
見難いのもそうですが、余分な所を削ぎ落とすのを他人がやるには分かりづらいです。
シンプルなコード作りなおすときに問題点に気づく場合も多いのでやってみてください。
ざっと見た感じではデタッチが足らない気がしたんですが未確認です。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月18日(金) 23:25
by ptolemy
カットを結構しましたが、細かいところは、まだカットしていません。
でも、これでいいですか?
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月19日(土) 00:08
by softya(ソフト屋)
問題はアニメ部分なので余分なコードはバグ追求を難しくします。と言う理由からまだまだ余分です。
本当に問題点の部分を抽出したコードで良いので、アニメ無しで表示、アニメあり(バグ再現)で表示を切り替えできる機能があれば良いです。
最悪それもなくて、バグ再現ありなしを#ifで切り替えるコードでも構いません。
この場合、カットするよ新しく組んだほうが早いかもしれません。
色々細かいと思うかもしれませんが、バグを追求するためにはできるだけシンプルすることが大切なのです。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月19日(土) 02:36
by ptolemy
わかりました。
アニメーションを切り替えるプログラムだけ残してそれ以外カットしたいと思います。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月19日(土) 10:15
by softya(ソフト屋)
念の為に書いておきますが、アニメも1つのパターンで良いですよ。1つが解決すれば他も解決するはずです。
後フルスクリーンは。テスト中は起動に時間がかかり面倒なのでウィンドウモードでお願いします。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月19日(土) 14:21
by ptolemy
これでどうですか?
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月19日(土) 14:25
by softya(ソフト屋)
何も表示されません。操作説明をされていませんが何もしなくて良いんですよね?
【補足】
こういうやり取りをしないためにもシンプルにしてほしいとお願いしたわけですが。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月19日(土) 15:08
by ptolemy
すみません。説明不足でした。
今、起きていることと操作を説明します。
本来ならばデバックするとプレイヤーの手が映るんですが、真っ暗のままで何も映りません。
なぜでしょうか?
操作は、
マウス左クリック=うつ
W=移動
1=武器を持っていない状態にする。
2=武器を持つ。
です。
終了するには、ESCです。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月19日(土) 15:16
by softya(ソフト屋)
正常に表示されるものと正常に表示されないものをお願いしたと思いますが、正常に表示されないものだけって事なのでしょうか?
私は現状は、そもそもカメラが何も捉えていない(方向間違い)なのではと思っています。
現状でカメラに何かが写る操作はあるのでしょうか?
【テストの原則】
正常があって比較で異常が有るわけですから、まず正常がないと動作確認とはいえません。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月19日(土) 16:50
by ptolemy
少し前に正常に表示されるものにされないものを上書きしてしまって正常に表示されるものは、なくなってしまいました。
バックアップは、しばらくとってなかったのでありません。
ウィンドウモードにしました。
また、アニメーションを二つにしました。
あと、方向の件ですが、通常は、
A地点をカメラがみる視線で設定してますが、
それをAからカメラを見る設定にしてもモデル自体描画されていませんでした。
カメラの座標は、プレイヤーの手の位置です。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月19日(土) 20:39
by softya(ソフト屋)
正常な表示がないと何処に原因が有るか見極めが難しいんですね。
実際組むときに正常な表示ができる簡素なものに付け足して実験を重ねた上で本物に実装しないとバグが分けがわからなくなります。
手が消えると言うことですが、カメラを引いて手のマトリクスがある場所にカメラを向けてみましたか?
バグの原因を追求すると言うのは、出来るだけ問題を正確に把握することですので、カメラを引いたり信頼できる数値データが無いか探したり、色々と手はあるものです
※ カメラを引くときはSetCameraNearFarの変更を忘れずに。
とりあえず、そういう方針で調べてみましょう。
【現状】
全体が見えるように
camera.Z=player.Z-3394
SetCameraNearFar(0.1f,5000.0f);/;
にしてみましたが、ピクりとも動きませんね。
手がカメラに映らないのはこれが原因では?
バグそのものは、まだ調べてませんがモデルとしての手は存在します。カメラの向いている方向にはないのとアニメーションが反映されていないです。
と言うことで、ptolemyさんがもう少し調べてみてください。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月20日(日) 09:13
by ptolemy
確認をしてもいいですか?
これからやること
・カメラを手のマトリックスに向けて手の存在を確かめる。
・その時SetCameraNearFarを変更する。
ですか?
それともカメラの初期の向いている方向を修正すればいいんですか?
あと、手は、表示されていたんですか?
現状をあまり理解してないので少し説明してもらえませんか?
宜しくお願いします。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月20日(日) 09:48
by softya(ソフト屋)
現状ですか?
camera.Z=player.Z-3394;
SetCameraNearFar(0.1f,5000.0f);
にしてもらえば分かります。手は存在しています。
次にしてもらうのは、アニメーションしない理由を探すことです。
・名前間違いが無いか確認。
・各関数の戻り値を確認。
などなどして、まずアニメーションを動かして下さい。
カメラを直すのはその後です。
【補足】
私はptolemyさんが問題点を把握する方法などをアドバイスしているだけですので、考えるのも直すのも本来はptolemyさんの役割ですよ。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月20日(日) 14:52
by ptolemy
今、僕もそうみたら手を直角に上げた状態で固まってますね。
このポーズは、フリーでダウンロードしたときのポーズなのでアニメーションが適応されてないのがわかりました。
また、確認したところ、向きは、正常でした。
元々は、手を前に出しているような状態でFPSにしていたのが
手を上げたので画面上には、描画されなくなっただけで
向きは、関係ありませんでした。
アニメーションについていろいろ確認してみます。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月20日(日) 15:17
by ptolemy
わかりました!!
アニメーション番号をMV1GetAttachAnim関数で取得していたんですがこの""で囲ってある第二引数を
リファレンスを見間違えていました。
なので、 関数の部分を
HASHA=1
KAMAE=0
ZENSHIN=3
PMMD=4
(変数は、短縮しました。)
のように手動で設定するとアニメーションが適応されました。
しかし、まだ、切り替えがしっかりとできません。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月20日(日) 20:29
by softya(ソフト屋)
出来る場合と出来ない場合の違いを明確にしましょう。
なにか原因が有るはずです。私はデタッチ関係にあると何度も書いてますね。よく調べてみてください。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月21日(月) 20:55
by ptolemy
一つお聞きしたいんですが、普通、アニメーションの切り替えは、
切り替えるごとにデタッチとアタッチの関数を書くものなのですか?
それともテンプレート見たいなものを作ってアニメーション番号を変数として
そのアニメーション番号の入れ換えでやりますか?
一般的というのは、存在しないのかも知れないのですが、多いやり方を教えてください。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月21日(月) 21:04
by softya(ソフト屋)
ブレンド率を変えるのも方法ですが、何しろ全部のアニメを制御していやる必要はあります。
> 一般的というのは、存在しないのかも知れないのですが、多いやり方を教えてください。
それこそ統計など取ったこと無いので、ご自身でやりやすい方法があればそれが一番です。
ただ、こういう面倒なものは私なら処理する関数やクラスで隠蔽します。どう隠蔽するかは個人の趣味の問題です。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月21日(月) 22:38
by ptolemy
そうですよね。そもそも、他の人のやり方を知っている訳がないですね。
これから休みに入るので、やり方を考えていきたいと思います
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月22日(火) 12:49
by ptolemy
僕は、
コード:
#define Atacchi(Index) MMD=MV1AttachAnim(PLAYER,Index,-1,FALSE);
int HASHA_Z=1,ZENSHIN_Z=3,ZENSHIN_N=4;
int main(){
.......
while(...){
Total=MV1GetAttachAnimTotalTime(PLAYER,MMD);
MV1SetAttachAnimTime(PLAYER,MMD,Playtime);
if(Playtime>=Total){
Playtime=0.0f;
}
if(Wキーを押したら){//進む
Playtime+=1.0f;
}
if(player_mode==2&&左クリック){//うつ
MV1DetachAnim(PLAYER,ZENSHIN_N) ;
MV1DetachAnim(PLAYER,ZENSHIN_Z) ;
Atacchi(HASHA_Z);
Playtime+=1.0f;
}else{//たまを撃たないとき
MV1DetachAnim(PLAYER,ZENSHIN_N) ;
MV1DetachAnim(PLAYER,HASHA_Z) ;
Atacchi(ZENSHIN_Z);
}
if(player_mode==1){
MV1DetachAnim(PLAYER,HASHA_Z) ;
MV1DetachAnim(PLAYER,ZENSHIN_Z) ;
Atacchi(ZENSHIN_N);
}
if(player_mode==2&&1を押したら){
player_mode=1;
}
if(player_mode==1&&2を押したら){
player_mode=2;
}
}
}
このプログラムを考えたんですがなぜかアニメーションがおかしくなってしまいます。
おかしいところやプログラム上の使い方が間違っている部分をご指摘お願いします。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月22日(火) 13:05
by softya(ソフト屋)
このコードですが、キーの処理と状態別の処理がごちゃごちゃに処理されているのでバグの温床にはなりそうです。
キー入力と状態の遷移においてのデタッチ・タッチ処理グループと状態別のアニメ・表示処理グループは分けて書きましょう。
あとAtacchiという関数が増えたみたいですが、アタッチしたら自動的に他のはデタッチする関数にしたほうが良いです。MV1DetachAnimが表面に出てこないようにするわけです。
アニメが変に関してはPlaytimeの値が異常がないか確認を。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月22日(火) 20:54
by ptolemy
コード:
void Atattch (int A,int B,int C,int D){
MMD=MV1AttachAnim(PLAYER,A,-1,FALSE);
MV1DetachAnim(PLAYER,B) ;
MV1DetachAnim(PLAYER,C) ;
MV1DetachAnim(PLAYER,D) ;
}
Atattch(最初の引数ガアタッチ,後の3つがデタッチ);
と書いたんですが、アニメーションを読み込んでくれません。
こういう書き方は考え方的には、間違っていますか?
考え方自体が間違っているのか、プログラムのミスか知りたいです。
お願いします。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月22日(火) 21:02
by softya(ソフト屋)
MV1DetachAniの引数が間違っている気がします。AnimIndexではなく、AttachIndexが引数です。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月22日(火) 22:31
by ptolemy
ありがとうございます。
まだテストしてませんが、多分今までのアニメーションの読み込みの失敗は、これだったのかもしれません。
総時間と再生時間は、attachiIndexかどうか確認をしたんですが、
デタッチは、アタッチの逆だと、思い込み、確認をしていませんでした。
ということは、
自作Attachi関数の中にデタッチの分も一度アタッチするということですか?
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月22日(火) 22:34
by softya(ソフト屋)
管理の仕方次第です。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月22日(火) 22:38
by ptolemy
わかりました。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月23日(水) 19:46
by ptolemy
再生時間などいりいろ確認をしたところ、
アタッチ番号がなぜかずっと1,2,3,4.....と勝手に大きくなっていました。
原因がわからないままです。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月23日(水) 20:31
by softya(ソフト屋)
DXライブラリの関数の戻り値のハンドルやAttachIndexの話しであれば、呼び出す度に変化するのは仕様でどんな値が入っているかはこちらで想定してはいけません。
変化する前提でプログラムを組んで下さい。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月23日(水) 23:15
by ptolemy
そういうものなんですね。
アタッチ番号は、番号ということで固定の数値が入るのだと勝手に思ってました。
いまのところ、
player_mode変数、playtime,自作関数のABCDは、おかしな部分は、ありませんでした。
Playtimeは、キーを押せばしっかり値が大きくなり、
さらに押してないときは、0、総再生時間になったら0
というのがしっかりできてました。
もう少し、プログラムのミス等を探して見タイと思います。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月24日(木) 22:41
by ptolemy
コード:
Attach(int Attach Index){
MMD=MV1AttachAnim(PLAYER,Index,-1,FALSE);
if(Index==0){
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号1,-1,FALSE));
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号2,-1,FALSE));
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号3,-1,FALSE));
}
if(Index==1){
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号0,-1,FALSE));
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号2,-1,FALSE));
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号3,-1,FALSE));
}
if(Index==2){
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号0,-1,FALSE));
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号1,-1,FALSE));
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号3,-1,FALSE));
}
if(Index==3){
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号0,-1,FALSE));
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号1,-1,FALSE));
MV1DetachAnim(PLAYER,MV1AttachAnim(PLAYER,アニメーション番号2,-1,FALSE));
}
}
//MMDというAttachIndexを使い総時間と再生時間を取得
//アタッチするとき
Attach(アニメーション番号);
でやるとまたアニメーションがおかしいです。
ミスや間違いを探したんですが変数もおかしな部分もありませんでした。
このプログラムに悪い点がありますか?
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月24日(木) 23:07
by softya(ソフト屋)
アタッチしたものをデタッチされていないのでバグると思います。
MMD=MV1AttachAnim(PLAYER,Index,-1,FALSE);
のMMDが不要時にデタッチされていません。
アタッチ→デタッチのセットを壊さないで下さい。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月25日(金) 08:31
by ptolemy
切り替えをする前からおかしいです。(デバック→ウィンドウが開かれる→アニメーションがバグる)
切り替えキーを押したら一時的にMMD=MV1AttachAnim(PLAYER,Index,-1,FALSE);をデタッチする。
と書いてみたんですが、バグりました。
やはり下線部のような状態だと、MMD=MV1AttachAnim(PLAYER,Index,-1,FALSE);のデタッチは、関係ないんでしょうか?
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月25日(金) 09:00
by ptolemy
また、数値を調べたら、
初期のアニメーションは、キーを押すと123...と増えますが、
切り替え後の他のアニメーションは、総時間などは、取得されていますが、ずっと0のままです。
切り替え後の初期のアニメーションは、正常です。
なので、
初期のアニメーションがバグってるのと、切り替え後の他のモーションが再生されてないのが、問題点です。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月25日(金) 10:00
by softya(ソフト屋)
問題点を明確にするためアタッチしてforループでnコマ再生、それをデタッチして別のアニメをアタッチしてforループでnコマ再生と言うプログラムを書いてみてください。正しい書き方を意識する必要はないです。while(...){は一つだけとかルール無視で。
なんか根本的な間違いが有る気がしてきました。
【補足】4つを切り替える必要もないです。2つの切り替わりが成功したら考えましょう。
Re: 3D多数のモーションをDXライブラリで扱
Posted: 2014年7月25日(金) 18:14
by ptolemy
そうですよね。二つでできたなら四つでもできますよね。
一つ聞きたいんですが、
nコマとは、総再生時間分ですか?
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月25日(金) 19:37
by softya(ソフト屋)
> nコマとは、総再生時間分ですか?
アニメーションを確認するのに必要十分なコマ数/時間ぐらいの意味です。深い意味はありません。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月26日(土) 14:17
by ptolemy
作ってみたんですがモーションが再生されません。
コード:
mode=1;
if(mode==1){
MV1DetachAnim(PLAYER,MMD2);
MMD=MV1AttachAnim(PLAYER,0,-1,FALSE);
while(Playtime1<Totaltime1){
Playtime1+=0.5f;
}
if(Playtime1==Totaltime1){
mode=2;
Playtime1=0.0f;
}
}
if(mode==2){
MV1DetachAnim(PLAYER,MMD);
MMD=MV1AttachAnim(PLAYER,1,-1,FALSE);
while(Playtime2<Totaltime2){
Playtime2+=0.5f;
}
if(Playtime2==Totaltime2){
mode=2;
Playtime2=0.0f;
}
}
Totaltime1=MV1GetAttachAnimTotalTime(PLAYER,MMD);
MV1SetAttachAnimTime(PLAYER,MMD,Playtime1);
Totaltime2=MV1GetAttachAnimTotalTime(PLAYER,MMD2);
MV1SetAttachAnimTime(PLAYER,MMD2,Playtime2);
だと値が、
Playtime1=0.0000..
Playtime2=0.0000..
Totaltime1=29.00..
Totaltime2=-1
になりました。
アニメーションすら再生されないし、Totaltime2がエラーを起こしてるので、ひとまず、
if(Playtime1==Totaltime1){
mode=2;
Playtime1=0.0f;
}の部分を/**/で囲って
modeが2にならないようにしても値に変化は、ありませんでした。
なにか書き方を間違っているんでしょうか?
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月26日(土) 14:19
by softya(ソフト屋)
コード全体を見せてもらえませんか?
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月26日(土) 18:58
by ptolemy
コード:
#include"DXLib.h"
#include"keybord.h"//キーボードのヘッダ
#include<math.h>
static const float ROTATE_SPEED=DX_PI/50;//回転スピード(DX_PI/A)(Aを小さくすると速。大きくすると遅。)
void rotate(float *x,float *y,const float ang,float mx,float my){
const float ox=*x-mx,oy=*y-my;
*x=ox*cos(ang)+oy*sin(ang);
*y=-ox*sin(ang)+oy*cos(ang);
*x+=mx;
*y+=my;
}
struct Player{
float X,Y,Z,flag,angleY,HP,HPMAX,HPflag,HX,HY,ang,speed;
}player={20,0.0f,200,1,0,300,100,0,0,0,0,5};
struct Camera{
float X,Y,Z,High;
}camera={0,0,0,150.0f};
static int GAMESTART=0;
static float cursor_x,cursor_y,cursor_z=150.0f;
static int Mouse_x,Mouse_y,Mouse_HX,Mouse_HY,Mouse_set_x=320,Mouse_set_y=240,cnt=0,Mouse_x2,cnt_tama=0;
static float Totaltime2,Playtime2,Totaltime1,Playtime1;
static int mode=1;
static int MMD,MMD2;
static int STAGE,PLAYER,ENEMY,PTAMA,Light,ETAMA,PGAGE,EGAGE,TAMASAUND,kasoru65;//3Dモデルの読み込み
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK)/*,SetWindowSizeExtendRate(1.0)*/,SetMainWindowText("Ptolemy Game");//1.4がちょうどいい
//マウスの初期位置指定
SetMousePoint(320,240);
SetMouseDispFlag(FALSE);
PLAYER=MV1LoadModel("GAME/高校生.x");//プレイヤー
Light=CreatePointLightHandle(VGet(stage.X,1000.0f,stage.Z),2000.0f,0.0f,0.002f,0.0f);
//カメラの場所設定
camera.X=player.X;
camera.Y=2600;
camera.Z=player.Z-394;
//カメラが見る座標を設定
cursor_x=player.X;
cursor_z=player.Z-568;
cursor_y=2420;
Playtime=0.0f;
while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
if(mode==1){
MV1DetachAnim(PLAYER,MMD2);
MMD=MV1AttachAnim(PLAYER,0,-1,FALSE);
while(Playtime1<Totaltime1){
Playtime1+=0.5f;
}
if(Playtime1==Totaltime1){//ここを消すと、始まった直後に総再生時間になる。
mode=2;
Playtime1=0.0f;
}
}
if(mode==2){
MV1DetachAnim(PLAYER,MMD);
MMD=MV1AttachAnim(PLAYER,1,-1,FALSE);
while(Playtime2<Totaltime2){
Playtime2+=0.5f;
}
if(Playtime2==Totaltime2){
mode=2;
Playtime2=0.0f;
}
}
Totaltime1=MV1GetAttachAnimTotalTime(PLAYER,MMD);
MV1SetAttachAnimTime(PLAYER,MMD,Playtime1);
Totaltime2=MV1GetAttachAnimTotalTime(PLAYER,MMD2);
MV1SetAttachAnimTime(PLAYER,MMD2,Playtime2);
//上の選択がないのでGAMESTART=1;追加
GAMESTART=1;
//カメラの範囲
SetCameraNearFar(0.1f,2000.0f);//奥行き0.1~1000までをカメラの描画範囲とする。
//方向回転
GetMousePoint(&Mouse_x,&Mouse_y);
if(cnt>0){
if(Mouse_x>320){
rotate(&camera.X,&camera.Z,+ROTATE_SPEED,player.X,player.Z);
rotate(&cursor_x,&cursor_z,+ROTATE_SPEED,player.X,player.Z);
rotate(&TAMA_end_x,&TAMA_end_z,+ROTATE_SPEED,player.X,player.Z);
//player.angleY+=ROTATE_SPEED;
}
if(Mouse_x<320){
rotate(&camera.X,&camera.Z,-ROTATE_SPEED,player.X,player.Z);
rotate(&cursor_x,&cursor_z,-ROTATE_SPEED,player.X,player.Z);
rotate(&TAMA_end_x,&TAMA_end_z,-ROTATE_SPEED,player.X,player.Z);
//player.angleY-=ROTATE_SPEED;
}
if(Mouse_y<240){
cursor_y+=15;
//rotate(&cursor_y,&cursor_y,-ROTATE_SPEED,player.Y,player.Z);
}
if(Mouse_y>240){
cursor_y-=15;
// rotate(&cursor_y,&cursor_y,+ROTATE_SPEED,player.Y,player.Z);
}
}
cnt++;
SetMousePoint(320,240);
SetCameraPositionAndTarget_UpVecY(VGet(camera.X,camera.Y,camera.Z),VGet(cursor_x,cursor_y,cursor_z));
MV1SetPosition(PLAYER,VGet(player.X,player.Y,player.Z));//プレイヤーの位置
MV1SetRotationXYZ(PLAYER,VGet(0.0f,player.angleY,0.0f));//プレイヤーの回転
MV1SetScale(PLAYER,VGet(1.0f,1.0f,1.0f));
DrawFormatString(0,40,GetColor(0,255,255),"MMD=%d\n",MMD);
DrawFormatString(0,140,GetColor(0,255,255),"MMD2=%d\n",MMD2);
DrawFormatString(0,200,GetColor(0,255,255),"Playtime1=%f\n",Playtime1);
DrawFormatString(0,220,GetColor(0,255,255),"Playtime2=%f\n",Playtime2);
DrawFormatString(0,240,GetColor(0,255,255),"count1=%f\n",count1);
DrawFormatString(0,260,GetColor(0,255,255),"count2=%f\n",count2);
DrawFormatString(0,280,GetColor(0,255,255),"Totaltime1=%f\n",Totaltime1);
DrawFormatString(0,300,GetColor(0,255,255),"Totaltime2=%f\n",Totaltime2);
}
void Player_Draw(){
//3Dモデルの描画
if(player.flag==1&&GAMESTART==1){
MV1DrawModel(PLAYER);//プレイヤー
}
}
if(keybord_Get(KEY_INPUT_ESCAPE)>0){
break;
}
}
ClearDrawScreen();
DxLib_End();
return 0;
}
先ほどお伝えした、値が間違ってました。
Totaltime1=29.000..
Totaltime2=29.000..
他の値が全て0です。
2番目のアニメーションは、29秒では、ないのに1番目と同じになってます。
なぜかprintfDxでは、値が表示されなかったので他の関数を使用しました。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月26日(土) 19:38
by softya(ソフト屋)
基本的なテストには不要なコードだらけですね。
最低限にしないとバグ発見が困難になると説明したはずなのですが・・・。
こちらで整理してみます。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月26日(土) 20:00
by ptolemy
あえて、アニメーションがどうなっているかをみるためカメラだけは、回転できるようにしてました。
カメラの回転の部分をなくして、カメラの位置自体を変えると不要な部分がほぼなくなると思います。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月26日(土) 20:13
by softya(ソフト屋)
とりあえずシンプルにしてバグをなくしてみました。
問題点は、
1.プログラムの流れがちゃんとできていない。これはコード整理の問題です。アタッチ・デタッチがちゃんと制御されていませんでした。
2.変数名の付け方が不統一なので、自分でも変数の使い方を間違っている。自分でバグりやすい状況を作り出しています。
3.最低限のコードにしてみました(変数などは放置してあります)。
これで動きはあっているはずです。
【補足】
書き忘れです。最大のバグはwhileループで描画せずにPlayTimeを進めていたことです。あとで私が書いたforループ版を投稿しますね。
コード:
#include"DXLib.h"
#include"keybord.h"//キーボードのヘッダ
#include<math.h>
struct Player {
float X, Y, Z, flag, angleY, HP, HPMAX, HPflag, HX, HY, ang, speed;
} player = {20, 0.0f, 200, 1, 0, 300, 100, 0, 0, 0, 0, 5};
struct Camera {
float X, Y, Z, High;
} camera = {0, 0, 0, 150.0f};
static int GAMESTART = 0;
static float cursor_x, cursor_y, cursor_z = 150.0f;
static int Mouse_x, Mouse_y, Mouse_HX, Mouse_HY, Mouse_set_x = 320, Mouse_set_y = 240, cnt = 0, Mouse_x2, cnt_tama = 0;
static float Totaltime2, Playtime, Totaltime1;
static int mode = 1;
static int AttachIndex1 = -1, AttachIndex2 = -1;
static int STAGE, PlayerModelHandle, ENEMY, PTAMA, LightHandle, ETAMA, PGAGE, EGAGE, TAMASAUND, kasoru65; //3Dモデルの読み込み
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) {
ChangeWindowMode( TRUE ), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK )/*,SetWindowSizeExtendRate(1.0)*/, SetMainWindowText( "Ptolemy Game" ); //1.4がちょうどいい
//マウスの初期位置指定
// SetMousePoint( 320, 240 );
// SetMouseDispFlag( FALSE );
PlayerModelHandle = MV1LoadModel( "GAME/高校生.x" ); //プレイヤー
//カメラの場所設定
camera.X = player.X;
camera.Y = 2600;
camera.Z = player.Z - 2394;
//カメラが見る座標を設定
cursor_x = player.X;
cursor_z = player.Z - 568;
cursor_y = 2420;
//カメラの範囲
SetCameraNearFar( 0.1f, 5000.0f ); //奥行き0.1~1000までをカメラの描画範囲とする。
// モデルアニメ初期化
AttachIndex1 = MV1AttachAnim( PlayerModelHandle, 0, -1, FALSE );
AttachIndex2 = MV1AttachAnim( PlayerModelHandle, 1, -1, FALSE );
Totaltime1 = MV1GetAttachAnimTotalTime( PlayerModelHandle, AttachIndex1 );
Totaltime2 = MV1GetAttachAnimTotalTime( PlayerModelHandle, AttachIndex2 );
// 一旦アニメ2をデタッチ
MV1DetachAnim( PlayerModelHandle, AttachIndex2 );
AttachIndex2 = -1;
// メインループ
Playtime = 0.0f;
while( ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 ) {
if( mode == 1 ) {
// アニメ時間オーバー?
if( Playtime >= Totaltime1 ) {
// アニメを切り替える。
mode = 2;
Playtime = 0.0f;
// アニメ1をデタッチ
if( AttachIndex1 != -1 ) {
MV1DetachAnim( PlayerModelHandle, AttachIndex1 );
AttachIndex1 = -1;
}
// アニメ2をアタッチ
AttachIndex2 = MV1AttachAnim( PlayerModelHandle, 1, -1, FALSE );
}
} else if( mode == 2 ) {
// アニメ時間オーバー?
if( Playtime >= Totaltime2 ) {
// アニメを切り替える。
mode = 1;
Playtime = 0.0f;
// アニメ2をデタッチ
if( AttachIndex2 != -1 ) {
MV1DetachAnim( PlayerModelHandle, AttachIndex2 );
AttachIndex2 = -1;
}
// アニメ1をアタッチ
AttachIndex1 = MV1AttachAnim( PlayerModelHandle, 0, -1, FALSE );
}
}
// アニメを設定
if( AttachIndex1 != -1 ) {
MV1SetAttachAnimTime( PlayerModelHandle, AttachIndex1, Playtime );
}
if( AttachIndex2 != -1 ) {
MV1SetAttachAnimTime( PlayerModelHandle, AttachIndex2, Playtime );
}
Playtime += 0.5f;
// カメラの位置
SetCameraPositionAndTarget_UpVecY( VGet( camera.X, camera.Y, camera.Z ), VGet( cursor_x, cursor_y, cursor_z ) );
// モデルの位置と描画
MV1SetPosition( PlayerModelHandle, VGet( player.X, player.Y, player.Z ) ); //プレイヤーの位置
MV1SetRotationXYZ( PlayerModelHandle, VGet( 0.0f, player.angleY, 0.0f ) ); //プレイヤーの回転
MV1SetScale( PlayerModelHandle, VGet( 1.0f, 1.0f, 1.0f ) );
MV1DrawModel( PlayerModelHandle ); //プレイヤ
DrawFormatString( 0, 40, GetColor( 0, 255, 255 ), "AttachIndex1=%d\n", AttachIndex1 );
DrawFormatString( 0, 140, GetColor( 0, 255, 255 ), "AttachIndex2=%d\n", AttachIndex2 );
DrawFormatString( 0, 200, GetColor( 0, 255, 255 ), "Playtime=%f\n", Playtime );
DrawFormatString( 0, 280, GetColor( 0, 255, 255 ), "Totaltime1=%f\n", Totaltime1 );
DrawFormatString( 0, 300, GetColor( 0, 255, 255 ), "Totaltime2=%f\n", Totaltime2 );
}
DxLib_End();
return 0;
}
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月26日(土) 20:32
by softya(ソフト屋)
forループで難しい制御を除いた版です。
問題点を明確にして、制御コードが複雑にならないと動くことを確認するのが目的です。
こういうのを足がかりにして問題点を潰していって欲しかったわけです。
コード:
#include"DXLib.h"
#include"keybord.h"//キーボードのヘッダ
#include<math.h>
struct Player {
float X, Y, Z, flag, angleY, HP, HPMAX, HPflag, HX, HY, ang, speed;
} player = {20, 0.0f, 200, 1, 0, 300, 100, 0, 0, 0, 0, 5};
struct Camera {
float X, Y, Z, High;
} camera = {0, 0, 0, 150.0f};
static int GAMESTART = 0;
static float cursor_x, cursor_y, cursor_z = 150.0f;
static int Mouse_x, Mouse_y, Mouse_HX, Mouse_HY, Mouse_set_x = 320, Mouse_set_y = 240, cnt = 0, Mouse_x2, cnt_tama = 0;
static float Totaltime2, Playtime, Totaltime1;
static int mode = 1;
static int AttachIndex1 = -1, AttachIndex2 = -1;
static int STAGE, PlayerModelHandle, ENEMY, PTAMA, LightHandle, ETAMA, PGAGE, EGAGE, TAMASAUND, kasoru65; //3Dモデルの読み込み
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) {
ChangeWindowMode( TRUE ), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK )/*,SetWindowSizeExtendRate(1.0)*/, SetMainWindowText( "Ptolemy Game" ); //1.4がちょうどいい
//マウスの初期位置指定
// SetMousePoint( 320, 240 );
// SetMouseDispFlag( FALSE );
PlayerModelHandle = MV1LoadModel( "GAME/高校生.x" ); //プレイヤー
//カメラの場所設定
camera.X = player.X;
camera.Y = 2600;
camera.Z = player.Z - 2394;
//カメラが見る座標を設定
cursor_x = player.X;
cursor_z = player.Z - 568;
cursor_y = 2420;
//カメラの範囲
SetCameraNearFar( 0.1f, 5000.0f ); //奥行き0.1~1000までをカメラの描画範囲とする。
// カメラの位置
SetCameraPositionAndTarget_UpVecY( VGet( camera.X, camera.Y, camera.Z ), VGet( cursor_x, cursor_y, cursor_z ) );
// モデルの位置と描画
MV1SetPosition( PlayerModelHandle, VGet( player.X, player.Y, player.Z ) ); //プレイヤーの位置
MV1SetRotationXYZ( PlayerModelHandle, VGet( 0.0f, player.angleY, 0.0f ) ); //プレイヤーの回転
MV1SetScale( PlayerModelHandle, VGet( 1.0f, 1.0f, 1.0f ) );
// メインループ
while( 1 ) {
////////////////////
// アニメ1
////////////////////
// アタッチ
AttachIndex1 = MV1AttachAnim( PlayerModelHandle, 0, -1, FALSE );
Totaltime1 = MV1GetAttachAnimTotalTime( PlayerModelHandle, AttachIndex1 );
// ループ1
for( Playtime=0.0f ; Playtime<Totaltime1 ; Playtime+=0.5f ) {
// 3大要素。ほんとあまりやっちゃダメよ。
if( ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 ) {
// 説明
DrawFormatString( 0, 40, GetColor( 0, 255, 255 ), "アニメ1 AttachIndex1=%d Playtime=%f", AttachIndex1, Playtime );
// 描画
MV1SetAttachAnimTime( PlayerModelHandle, AttachIndex1, Playtime );
MV1DrawModel( PlayerModelHandle ); //プレイヤ
} else {
goto end;
}
}
// デタッチ
MV1DetachAnim( PlayerModelHandle, AttachIndex1 );
AttachIndex1 = -1;
////////////////////
// アニメ2
////////////////////
// アタッチ
AttachIndex2 = MV1AttachAnim( PlayerModelHandle, 1, -1, FALSE );
Totaltime2 = MV1GetAttachAnimTotalTime( PlayerModelHandle, AttachIndex2 );
// ループ2
for( Playtime=0.0f ; Playtime<Totaltime2 ; Playtime+=0.5f ) {
// 3大要素。ほんとあまりやっちゃダメよ。
if( ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 ) {
// 説明
DrawFormatString( 0, 40, GetColor( 0, 255, 255 ), "アニメ2 AttachIndex2=%d Playtime=%f", AttachIndex2, Playtime );
// 描画
MV1SetAttachAnimTime( PlayerModelHandle, AttachIndex2, Playtime );
MV1DrawModel( PlayerModelHandle ); //プレイヤ
} else {
goto end;
}
}
// デタッチ
MV1DetachAnim( PlayerModelHandle, AttachIndex2 );
AttachIndex2 = -1;
}
end:;
DxLib_End();
return 0;
}
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月26日(土) 22:53
by ptolemy
自分のC言語の知識の無さと変数などの名前の適当さがとてもわかりました。
また、改良したものを二つも投稿してくださって本当にありがとうございます。
僕は、modeで管理する方法の方がピンとくるのでこちらを参考にします。
modeの方で出来なかったら、forにしたいと思います。
自分で書いて、どうなるか試したいと思います。
また、変数の名前の適当さについては、前にもご指摘されたのですが直していませんでした。
これからは、変数の名前を適当につけないよう心がけていきたいと思います。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月26日(土) 22:59
by softya(ソフト屋)
forはあくまで実験用ですので本物として使わないでくださいね。この場合forの方が状態遷移を持たないので簡単なはずなんですが?
少なくともptolemyさんのコードでは状態遷移処理が今のところちゃんと書けていないので、状態遷移を必要とするmodeの方が簡単に見えるとしたら誤解だと思います。
【補足】
ちなみにC言語の文法レベルの間違いは特に無いです。
自分で書いたプログラムのフロー(流れ)がちゃんと把握できていないため変数の扱いが不適当なのと(コードのわかり易さの心がけが必要)、状態遷移ロジックの記述が行き当たりばったり(状態遷移と言う動作をちゃんと把握する)などなど、プログラムの組み方の心がけが必要な状況だと思います。
ある程度の規模のプログラムを作るには、ここをちゃんと出来ないとバグのためプログラムが作れない自滅パターンに陥ります。
よくプログラミング言語は道具と言われますが、道具の基礎だけ覚えても何も作れません。これが文法の基礎を終えた状態です。
道具を使ってどうやって組み立てるのか、これが今やるべき事で言語の勉強よりはるかに難しくて時間の掛かるものなのです。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月27日(日) 14:37
by ptolemy
では、forを使って書いてみます。
流れてとしては、
アニメ1[アタッチ]&総時間取得
↓
forループでモデルの描画と、再生時間のセットを
再生時間が総再生時間を過ぎるまでループする。
↓
アニメ1をデタッチ&アタッチ番号を初期化
↓
アニメ2は、同様
なのですが、これを例えば何処かのキーを押したらforループみたいな感じでよろしいと思いますか?
あと、プログラムに関する質問なのですが、
1・while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
の部分を
if( ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 ) {
} else {
goto end;
}
にするのは、どうしてでしょうか?
2・また、goto ~とは、
[リンク:goto文]
http://wisdom.sakura.ne.jp/programming/c/c11.html
こちらでは、使わない方がいいと書いているのですが使ってもいいんでしょうか?
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月27日(日) 14:44
by softya(ソフト屋)
forはあくまで実験用。理解をするために使うものです。その前提を崩さないでくださいね。
> なのですが、これを例えば何処かのキーを押したらforループみたいな感じでよろしいと思いますか?
順次処理に書くことで単純化しているので、それを崩したら意味がなくなります。
> while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
> if( ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 ) {
> } else {
> goto end;
> }
whileを使う以上は状態遷移を使うしかなくなるからです。
つまり、時間処理でforループしているわかり易さが最優先です。
> 2・また、goto ~とは、
なぜ使わないほうが良いのか理解していて、その上であえて使う分には問題ないです。
よくわからないのなら使わない方が良いですよ。
ちなみに今回の場合、gotoを使わないとかえって複雑になるのでわざと使っています。
Re: 3D多数のモーションをDXライブラリで扱
Posted: 2014年7月27日(日) 15:14
by ptolemy
forがアニメの再生について理解するための実験用なら、
本物のゲームとして作る方には、状態遷移の方を使うということですか?
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月27日(日) 15:30
by softya(ソフト屋)
> 本物のゲームとして作る方には、状態遷移の方を使うということですか?
状態遷移を使う事になります。
ただ、今は全くうまく使えてませんので、使う前に状態遷移の練習をしたほうが良いと思います。
Re: 3D多数のモーションをDXライブラリで扱
Posted: 2014年7月27日(日) 20:10
by ptolemy
練習は、ソフト屋さんに作っていただいたサンプルプログラムを理解するだけじゃ不十分ですか?
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月27日(日) 20:13
by softya(ソフト屋)
最終的に十分かどうかはご本人が判断すべきことかと思います。
応用して、うまく作れない → 不十分
うまく応用ができた → たぶん、十分
と言うことだと思いますよね。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月27日(日) 22:39
by ptolemy
4つのモーションを切りかえれるようにがんばります。
まずは、2つから..
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月31日(木) 20:04
by ptolemy
コード:
#include"DXLib.h"
#include"keybord.h"//キーボードのヘッダ
#include<math.h>
struct Player {
float X, Y, Z, flag, angleY, HP, HPMAX, HPflag, HX, HY, ang, speed;
} player = {20, 0.0f, 200, 1, 0, 300, 100, 0, 0, 0, 0, 5};
struct Camera {
float X, Y, Z, High;
} camera = {0, 0, 0, 150.0f};
static int GAMESTART = 0;
static float Totaltime2, Playtime, Totaltime1;
static int mode = 1;
static int AttachIndex1 = -1, AttachIndex2 = -1;
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) {
ChangeWindowMode( TRUE ), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ), SetMainWindowText( "Ptolemy Game" );
PlayerModelHandle = MV1LoadModel( "GAME/高校生.x" ); //プレイヤー
//カメラの場所設定
camera.X = player.X;
camera.Y = 2600;
camera.Z = player.Z - 2394;
//カメラが見る座標を設定
cursor_x = player.X;
cursor_z = player.Z - 568;
cursor_y = 2420;
//カメラの範囲
SetCameraNearFar( 0.1f, 5000.0f ); //奥行き0.1~1000までをカメラの描画範囲とする。
// モデルアニメ初期化
AttachIndex1 = MV1AttachAnim( PlayerModelHandle, 0, -1, FALSE );
AttachIndex2 = MV1AttachAnim( PlayerModelHandle, 1, -1, FALSE );
Totaltime1 = MV1GetAttachAnimTotalTime( PlayerModelHandle, AttachIndex1 );
Totaltime2 = MV1GetAttachAnimTotalTime( PlayerModelHandle, AttachIndex2 );
// 一旦アニメ2をデタッチ
MV1DetachAnim( PlayerModelHandle, AttachIndex2 );
AttachIndex2 = -1;
Playtime = 0.0f;
while( ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 ) {
//移動
if(keybord_Get(KEY_INPUT_W)>0&&GAMESTART==1){
Playtime+=1.0f;
}else{
Playtime=0.0f;
}
if(Player_mode==2){
if(keybord_Get(KEY_INPUT_1)>0){
Player_mode=1;
Playtime=0.0f;
if(AttachIndex2!=-1){
MV1DetachAnim(PLAYER,AttachIndex2);
AttachIndex2=-1;
}
}
if(Playtime>=Totaltime2){
Playtime=0.0f;
}
AttachIndex2=MV1AttachAnim(PLAYER,3,-1,FALSE);
}
if(Player_mode==1){
if(keybord_Get(KEY_INPUT_2)>0){
Player_mode=2;
Playtime=0.0f;
if(AttachIndex1!=-1){
MV1DetachAnim(PLAYER,AttachIndex1);
AttachIndex1=-1;
}
}
if(Playtime>=Totaltime1){
Playtime=0.0f;
}
AttachIndex1=MV1AttachAnim(PLAYER,4,-1,FALSE);
}
if(AttachIndex1!=-1){
MV1SetAttachAnimTime(PLAYER,AttachIndex1,Playtime);
}
if(AttachIndex2!=-1){
MV1SetAttachAnimTime(PLAYER,AttachIndex2,Playtime);
SetCameraPositionAndTarget_UpVecY( VGet( camera.X, camera.Y, camera.Z ), VGet( cursor_x, cursor_y, cursor_z ) );
// モデルの位置と描画
MV1SetPosition( PlayerModelHandle, VGet( player.X, player.Y, player.Z ) ); //プレイヤーの位置
MV1SetRotationXYZ( PlayerModelHandle, VGet( 0.0f, player.angleY, 0.0f ) ); //プレイヤーの回転
MV1SetScale( PlayerModelHandle, VGet( 1.0f, 1.0f, 1.0f ) );
MV1DrawModel( PlayerModelHandle ); //プレイヤ
DrawFormatString( 0, 40, GetColor( 0, 255, 255 ), "AttachIndex1=%d\n", AttachIndex1 );
DrawFormatString( 0, 140, GetColor( 0, 255, 255 ), "AttachIndex2=%d\n", AttachIndex2 );
DrawFormatString( 0, 200, GetColor( 0, 255, 255 ), "Playtime=%f\n", Playtime );
DrawFormatString( 0, 280, GetColor( 0, 255, 255 ), "Totaltime1=%f\n", Totaltime1 );
DrawFormatString( 0, 300, GetColor( 0, 255, 255 ), "Totaltime2=%f\n", Totaltime2 );
}
DxLib_End();
return 0;
}
まずは、今あるサンプルと自分の力で書いてみたんですが、アニメーションがバグります。
おかしいところは、ありますか?
また、使い方がまだ理解していないような部分は、ありますか?
ちなみに、
アニメ番号は、
0=武器を持ちかえるアニメ
1=銃を持っている状態での発砲
2=銃のリロード
3=銃を持ったままの前進
4=武器をもってないバニラでの前進
です。
今回は、3と4でWを押したときアニメを進め、切り替えをキーボードの1と2で切り替えてみました。(テンキーの1,2では、ありません。)
こんな感じです。
ちなみにHPとか敵とか出てますがこれは、気にしないでください。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月31日(木) 20:27
by softya(ソフト屋)
このコードだとうまく動くはずが無いです。
インデントを整えてみてください。インデントの乱れがバグを呼んでいる気がしました。
あと3,4のアニメをしているのに変数名は1,2なのですが、これもバグを呼ぶ原因では? それ関連での間違いがあります。
変数やインデントをちゃんとしないと自分で自分のコードを誤解しててバグ生まれますよ。
間違えやすい人が間違えやすい状況を自分で作ってはダメです。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年7月31日(木) 22:53
by ptolemy
出来ました!!!
変数名をしっかり整理しました。
そして、最大の原因が毎フレームアタッチしていたことでした。
if(mode==1){
if(AttachIndex4==-1){
アタッチ4
}
}
というようにアタッチされていない場合のみアタッチとしたら成功しました。
まだ、4つのアニメを切り替えるのができてないのでそれができたら解決です。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年8月02日(土) 19:33
by ptolemy
すみません。
4つのモーションを扱うようにしたらなぜかうまくいきせん。
プログラムを作って失敗するたび何回もプログラムを載せて間違いを質問して申し訳ないです。
こちらがプログラムです。
コード:
#include"DXLib.h"
#include"keybord.h"
#include"GAME.h"
#include<math.h>
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
PLAYER=MV1LoadModel("GAME/高校生.x");//プレイヤー
Light=CreatePointLightHandle(VGet(stage.X,1000.0f,stage.Z),2000.0f,0.0f,0.002f,0.0f);
camera.X = player.X;
camera.Y = 2600;
camera.Z = player.Z - 2394;
cursor_x = player.X;
cursor_z = player.Z - 568;
cursor_y = 2420;
//カメラの範囲
SetCameraNearFar( 0.1f, 5000.0f );
// モデルアニメ初期化
AttachIndex0=MV1AttachAnim(PLAYER,0,-1,FALSE);
AttachIndex1=MV1AttachAnim(PLAYER,1,-1,FALSE);
AttachIndex3=MV1AttachAnim(PLAYER,3,-1,FALSE);
AttachIndex4=MV1AttachAnim(PLAYER,4,-1,FALSE);
Totaltime0=MV1GetAttachAnimTotalTime(PLAYER,AttachIndex0);
Totaltime1=MV1GetAttachAnimTotalTime(PLAYER,AttachIndex1);
Totaltime3=MV1GetAttachAnimTotalTime(PLAYER,AttachIndex3);
Totaltime4=MV1GetAttachAnimTotalTime(PLAYER,AttachIndex4);
// 使わないアニメをデタッチ
MV1DetachAnim(PLAYER,AttachIndex0);
AttachIndex0=-1;
MV1DetachAnim(PLAYER,AttachIndex1);
AttachIndex1=-1;
MV1DetachAnim(PLAYER,AttachIndex3);
AttachIndex3=-1;
MV1DetachAnim(PLAYER,AttachIndex4);
AttachIndex4=-1;
Playtime=0.0f;
while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
//前進
if(keybord_Get(KEY_INPUT_W)>0){
Playtime+=1.0f;
}else{
Playtime=0.0f;
}
//弾を撃つ
if(Player_mode==3){
int Mouse=GetMouseInput();
if(Mouse&MOUSE_INPUT_LEFT){
Playtime+=1.0f;
}else{
Playtime=0.0f;
}
/////////////////////////////////
/////////モード3////////////////
///////////////////////////////
if(Player_mode==3){
int Mouse=GetMouseInput();
if(Mouse&MOUSE_INPUT_LEFT){//左クリック
if(AttachIndex3!=-1){//AttachIndex3をデタッチ
MV1DetachAnim(PLAYER,AttachIndex3);
AttachIndex3=-1;
}
if(AttachIndex1==-1){//AttachIndex1をアタッチ
AttachIndex1=MV1AttachAnim(PLAYER,1,-1,FALSE);
}
}else{
if(AttachIndex1!=-1){//AttachIndex1をデタッチ
MV1DetachAnim(PLAYER,AttachIndex1);
AttachIndex1=-1;
}
if(AttachIndex3==-1){//AttachIndex3をアタッチ
AttachIndex3=MV1AttachAnim(PLAYER,3,-1,FALSE);
}
}
if(keybord_Get(KEY_INPUT_1)>0){
Player_mode=4;
Playtime=0.0f;
if(AttachIndex3!=-1){
MV1DetachAnim(PLAYER,AttachIndex3);
AttachIndex3=-1;
}
if(AttachIndex1!=-1){
MV1DetachAnim(PLAYER,AttachIndex1);
AttachIndex1=-1;
}
}
if(Playtime>=Totaltime3){
Playtime=0.0f;
}
}
/////////////////////////////////
/////////モード4////////////////
///////////////////////////////
if(Player_mode==4){
if(AttachIndex4==-1){
AttachIndex4=MV1AttachAnim(PLAYER,4,-1,FALSE);
}
if(keybord_Get(KEY_INPUT_2)>0){
Player_mode=0;
Playtime=0.0f;
if(AttachIndex4!=-1){
MV1DetachAnim(PLAYER,AttachIndex4);
AttachIndex4=-1;
}
}
if(Playtime>=Totaltime4){
Playtime=0.0f;
}
}
/////////////////////////////////
/////////モード0////////////////
///////////////////////////////
if(Player_mode==0){
if(AttachIndex0==-1){
AttachIndex0=MV1AttachAnim(PLAYER,0,-1,FALSE);
}
Playtime+=1.0f;
if(Playtime>=Totaltime0){
if(AttachIndex0!=-1){
MV1DetachAnim(PLAYER,AttachIndex0);
AttachIndex0=-1;
}
Player_mode=3;
Playtime=0.0f;
}
}
//再生時間セット
if(AttachIndex4!=-1){
MV1SetAttachAnimTime(PLAYER,AttachIndex4,Playtime);
}
if(AttachIndex3!=-1){
MV1SetAttachAnimTime(PLAYER,AttachIndex3,Playtime);
}
if(AttachIndex0!=-1){
MV1SetAttachAnimTime(PLAYER,AttachIndex0,Playtime);
}
if(AttachIndex1!=-1){
MV1SetAttachAnimTime(PLAYER,AttachIndex1,Playtime);
}
SetCameraPositionAndTarget_UpVecY(VGet(camera.X,camera.Y,camera.Z),VGet(cursor_x,cursor_y,cursor_z));
MV1SetPosition(PLAYER,VGet(player.X,player.Y,player.Z));//プレイヤーの位置
MV1SetRotationXYZ(PLAYER,VGet(0.0f,player.angleY,0.0f));//プレイヤーの回転
SetLightPositionHandle(Light,VGet(stage.X,1000.0f,stage.Z));
MV1DrawModel(PLAYER);//プレイヤー
}
ClearDrawScreen();
DxLib_End();
return 0;
}
変数は、載せていません。
うまくいかないところとわからない場所は、
1つめ
モード0のPlaytimeが自動再生されなく、Wなど、他の再生キーを押しつづけないと再生されない。
2つめ
銃を持った状態での撃つモーションと歩くモーションの切り替え方がよくわからず、デタッチとアタッチの数が、等しくない。
なので、ヒントでいいので教えてほしいです。
ちなみにこの視点から見ると、銃を持っているときの手が体に埋まっていますが手から見ると問題ないです。
よろしくお願いします。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年8月02日(土) 19:53
by softya(ソフト屋)
インデントが変なのでソースを見るのが辛いですね。
あと共通関数化すべきだと思います。
1つめ。アニメのデタッチと別件なので問題を分離すべきですね。別質問で別コードを制作して質問をお願いします。
状態遷移の話なので場合によっては長くなります。
2つめ。同時に2つアタッチは出来ます。上に書いたようにアタッチを管理する関数を作るべきかと思います。
3つめ。ちなみにこの視点から見ると、銃を持っているときの手が体に埋まっていますが手から見ると問題ないです。
SetCameraNearFar()をちゃんと理解しないとこうなります。Zバッファの精度問題だと思います。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年8月06日(水) 23:09
by ptolemy
いつも関数化が上手くいかないので、関数化して整理するのは、関数がうまく使えるようになってからにします。
一応、関数を呼び出して管理するというのをすこし回りくどいですがフラグで管理してみました。
質問のWキーを押さないと再生されないというバグ以外は、解決しました。
この件に関しては、再度質問いたします。
完成したソースです。
コード:
#include"DXLib.h"
#include"keybord.h"//キーボードのヘッダ
#include"GAME.h"
#include<math.h>
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);
PLAYER=MV1LoadModel("GAME/高校生.x");//プレイヤーのモデルを読み込み
Light=CreatePointLightHandle(VGet(stage.X,1000.0f,stage.Z),2000.0f,0.0f,0.002f,0.0f);//ライトの設定
//カメラの位置設定
camera.X = player.X;
camera.Y = 2600;
camera.Z = player.Z - 2394;
//カメラがみる位置設定
cursor_x = player.X;
cursor_z = player.Z - 568;
cursor_y = 2420;
//カメラの範囲
SetCameraNearFar( 0.1f, 5000.0f );
//モデルアニメ初期化
AttachIndex0=MV1AttachAnim(PLAYER,0,-1,FALSE);
AttachIndex1=MV1AttachAnim(PLAYER,1,-1,FALSE);
AttachIndex3=MV1AttachAnim(PLAYER,3,-1,FALSE);
AttachIndex4=MV1AttachAnim(PLAYER,4,-1,FALSE);
//総再生時間取得
Totaltime0=MV1GetAttachAnimTotalTime(PLAYER,AttachIndex0);
Totaltime1=MV1GetAttachAnimTotalTime(PLAYER,AttachIndex1);
Totaltime3=MV1GetAttachAnimTotalTime(PLAYER,AttachIndex3);
Totaltime4=MV1GetAttachAnimTotalTime(PLAYER,AttachIndex4);
//アニメを一旦デタッチ
MV1DetachAnim(PLAYER,AttachIndex0);
AttachIndex0=-1;
MV1DetachAnim(PLAYER,AttachIndex1);
AttachIndex1=-1;
MV1DetachAnim(PLAYER,AttachIndex3);
AttachIndex3=-1;
MV1DetachAnim(PLAYER,AttachIndex4);
AttachIndex4=-1;
Playtime=0.0f;
//メインループ
while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
//前進
if(keybord_Get(KEY_INPUT_W)>0){
Playtime+=1.0f;
}else{
Playtime=0.0f;
}
//弾を撃つ
if(Player_mode==3){
int Mouse=GetMouseInput();
if(Mouse&MOUSE_INPUT_LEFT){
Playtime+=1.0f;
}else{
Playtime=0.0f;
}
/////////////////////////////////
/////////モード3////////////////
///////////////////////////////
if(Player_mode==3){
int Mouse=GetMouseInput();
if(Mouse&MOUSE_INPUT_LEFT){
Attachflag_1_3=1;
}else{
Attachflag_1_3=0;
}
////////////////
///フラグOFF///
//////////////
if(Attachflag_1_3==0){
if(AttachIndex1!=-1){
MV1DetachAnim(PLAYER,AttachIndex1);
AttachIndex1=-1;
}
if(AttachIndex3==-1){
AttachIndex3=MV1AttachAnim(PLAYER,3,-1,FALSE);
}
}
////////////////
///フラグON////
//////////////
if(Attachflag_1_3==1){
if(AttachIndex3!=-1){
MV1DetachAnim(PLAYER,AttachIndex3);
AttachIndex3=-1;
}
if(AttachIndex1==-1){
AttachIndex1=MV1AttachAnim(PLAYER,1,-1,FALSE);
}
}
if(keybord_Get(KEY_INPUT_1)>0){
Player_mode=4;
Playtime=0.0f;
if(AttachIndex3!=-1){
MV1DetachAnim(PLAYER,AttachIndex3);
AttachIndex3=-1;
}
if(AttachIndex1!=-1){
MV1DetachAnim(PLAYER,AttachIndex1);
AttachIndex1=-1;
}
}
if(Playtime>=Totaltime3){
Playtime=0.0f;
}
}
/////////////////////////////////
/////////モード4////////////////
///////////////////////////////
if(Player_mode==4){
if(AttachIndex4==-1){
AttachIndex4=MV1AttachAnim(PLAYER,4,-1,FALSE);
}
if(keybord_Get(KEY_INPUT_2)>0){
Player_mode=0;
Playtime=0.0f;
if(AttachIndex4!=-1){
MV1DetachAnim(PLAYER,AttachIndex4);
AttachIndex4=-1;
}
}
if(Playtime>=Totaltime4){
Playtime=0.0f;
}
}
/////////////////////////////////
/////////モード0////////////////
///////////////////////////////
if(Player_mode==0){
if(AttachIndex0==-1){
AttachIndex0=MV1AttachAnim(PLAYER,0,-1,FALSE);
}
Playtime+=1.0f;
if(Playtime>=Totaltime0){
if(AttachIndex0!=-1){
MV1DetachAnim(PLAYER,AttachIndex0);
AttachIndex0=-1;
}
Player_mode=3;
Playtime=0.0f;
}
}
//再生時間セット
if(AttachIndex4!=-1){
MV1SetAttachAnimTime(PLAYER,AttachIndex4,Playtime);
}
if(AttachIndex3!=-1){
MV1SetAttachAnimTime(PLAYER,AttachIndex3,Playtime);
}
if(AttachIndex0!=-1){
MV1SetAttachAnimTime(PLAYER,AttachIndex0,Playtime);
}
if(AttachIndex1!=-1){
MV1SetAttachAnimTime(PLAYER,AttachIndex1,Playtime);
}
SetCameraPositionAndTarget_UpVecY(VGet(camera.X,camera.Y,camera.Z),VGet(cursor_x,cursor_y,cursor_z));
MV1SetPosition(PLAYER,VGet(player.X,player.Y,player.Z));//プレイヤーの位置
MV1SetRotationXYZ(PLAYER,VGet(0.0f,player.angleY,0.0f));//プレイヤーの回転
SetLightPositionHandle(Light,VGet(stage.X,1000.0f,stage.Z));
MV1DrawModel(PLAYER);//プレイヤー
}
ClearDrawScreen();
DxLib_End();
return 0;
}
また、インデントがおかしかったらすみません。
いままで長らくとアドバイスを下さり本当にありがとうございました。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年8月07日(木) 00:09
by へにっくす
No.66のコードでコンパイルできるとは思えないのですが。
コンパイルできないものをあげてもらったところで本当に解決したのか疑問に感じます。
・全角のスペースでインデントしないでください。タブか半角スペースを使って普通インデントします。softyaさんが掲示してくれたソースに、全角スペースはありましたか?なかったはずですよ。
オフトピック
最近のコンパイラって全角のスペースがあってもコンパイルできるんかいな?
・170行目と174行目の閉じかっこが全角です。
・59行目と69行目が同じif (Player_mode==3)となってますが、何か意味が違うのでしょうか。
・59行目から65行目でif( Player_mode == 3 ) {}のブロックのつもりなのだとしたら、かっこが足りないと普通気づきそうなものですが。
コード:
//弾を撃つ
if(Player_mode==3){
int Mouse=GetMouseInput();
if(Mouse&MOUSE_INPUT_LEFT){
Playtime+=1.0f;
}else{
Playtime=0.0f;
}
ただしくはこうならないとおかしいですよね?
コード:
//弾を撃つ
if(Player_mode==3){
int Mouse=GetMouseInput();
if(Mouse&MOUSE_INPUT_LEFT){
Playtime+=1.0f;
}else{
Playtime=0.0f;
} // <=ここが足りない!!
}
とにかくまず言えることは、
ちゃんと
インデントをそろえなさい。
そろえていないから、しなくてもいいことが増えるのですよ。
Re: 3D多数のモーションをDXライブラリで扱
Posted: 2014年8月07日(木) 00:39
by ptolemy
すみませんでした。
PCがネットワーク関係の事情により、他の端末で投稿させていただきました。
PCでは、TABでスペースを開けていて、
PC→メールでフリーメールに送信→他の端末でフリーメールのメールコピペ
としてるんですが、なぜか改行などがおかしくなったので、
その端末でコピペ時にその場で修正しました。
また、そのとき、誤って消してしまった部分があり、そこなどを修正もしました。
しかし、コピペ前は、正常に動作しています。
今回は、まず、PCで投稿しなかったため、他の端末を使うことになったということと、
全角でスペースを開けていたというミスです。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年8月07日(木) 11:11
by softya(ソフト屋)
スマホで投稿する場合は、ブラウザ選びを気をつけないと化けると思います。
zipのままPCからメール転送して添付するって手もあります。
Re: 3D多数のモーションをDXライブラリで扱う方法
Posted: 2014年8月07日(木) 14:29
by ptolemy
はい。これからは、PCからスマホにzipで送って、
スマホのファイラーで解凍してコピペまたは、添付するようにします。
ご迷惑おかけしました。