追尾オプションのアレンジ
-
LIFE
追尾オプションのアレンジ
はじめまして、LIFEと申します。よろしくお願いします。
龍神録プログラミングの館を参考にDXライブラリでSTGを製作しております。
今回、当たり判定のあるオプション(オプションで敵の弾を消せる)について質問がしたく、恐れ多くも書き込ませていただきました。
まず、グラディウスのようなオプションを作りたくてこちら↓
http://dixq.net/forum/viewtopic.php?f=3 ... %B3#p30253
の質問を参考に自機を追尾するオプションを製作したのですが、通常の移動時はごく普通に追尾して、低速移動時には、例えば自分の前方を覆うようにオプションを配置したら、オプションが通常時のように追尾するのではなくその自分を覆う形のままついてくる様なアレンジを加えたい(風神録の魔理沙の高威力装備のような感じです)と思ったのですが、どうしても上手くいきません。
自分は、龍神録のプログラムを参考に数ヶ月前からプログラミングをやり始めた初心者です。学校の専門も全然違います。
殆どのプログラムは全て龍神録プログラミングの館のものを使わせて頂いております。
龍神録プログラミングの館を参考にDXライブラリでSTGを製作しております。
今回、当たり判定のあるオプション(オプションで敵の弾を消せる)について質問がしたく、恐れ多くも書き込ませていただきました。
まず、グラディウスのようなオプションを作りたくてこちら↓
http://dixq.net/forum/viewtopic.php?f=3 ... %B3#p30253
の質問を参考に自機を追尾するオプションを製作したのですが、通常の移動時はごく普通に追尾して、低速移動時には、例えば自分の前方を覆うようにオプションを配置したら、オプションが通常時のように追尾するのではなくその自分を覆う形のままついてくる様なアレンジを加えたい(風神録の魔理沙の高威力装備のような感じです)と思ったのですが、どうしても上手くいきません。
自分は、龍神録のプログラムを参考に数ヶ月前からプログラミングをやり始めた初心者です。学校の専門も全然違います。
殆どのプログラムは全て龍神録プログラミングの館のものを使わせて頂いております。
Re: 追尾オプションのアレンジ
どう上手くいかないのでしょう。具体的に書いてください。
「自分を覆う形のままついてくる」だけならできるのでしょうか?
「自分を覆う形のままついてくる」だけならできるのでしょうか?
-
LIFE
Re: 追尾オプションのアレンジ
ISLeさん、返信ありがとうございます。そして言葉足らずで申し訳ありませんでした。
「自分を覆う形のままついてくる」なら出来ました。けれどそのように固定させるプログラムだと、画面端に行き着いてその画面端に向かって方向キーを入れていると、その方向にオプションが行ってしまいます。例えば、右端にキャラが辿り着き、それ以上移動できなくなったにもかかわらず、オプションだけが右に移動し続け画面の外に行ってしまいます。
「自分を覆う形のままついてくる」なら出来ました。けれどそのように固定させるプログラムだと、画面端に行き着いてその画面端に向かって方向キーを入れていると、その方向にオプションが行ってしまいます。例えば、右端にキャラが辿り着き、それ以上移動できなくなったにもかかわらず、オプションだけが右に移動し続け画面の外に行ってしまいます。
Re: 追尾オプションのアレンジ
キャラが端で止まるような処理が実装できているのなら、
オプションも端で止まるような処理も同様に作ることはできないのでしょうか?
オプションも端で止まるような処理も同様に作ることはできないのでしょうか?
-
LIFE
Re: 追尾オプションのアレンジ
何度もすみません。
やっぱり自分ではどのようにやっても例の不具合が発生します。
不具合を解消できるかもしれないやり方でやっても、今度はその場に固定されてしまって、固定された状態でプレイヤーの動きに合わせて動いてはくれません。
やっぱり自分ではどのようにやっても例の不具合が発生します。
不具合を解消できるかもしれないやり方でやっても、今度はその場に固定されてしまって、固定された状態でプレイヤーの動きに合わせて動いてはくれません。
Re: 追尾オプションのアレンジ
「自分を覆う形のままついてくる」オプションは、少し遅れて動くふうなのでしょうか。
仮にそうだとしても、オプションそれぞれが自分のいるべき座標を追いかけるようにしてやれば良いと思います。
ついでに言うと、自機を追尾するオプションの場合にも同じことが言えますので、自機を覆う座標と自機を追尾する座標のどちらを参照するかの切り替えができさえすれば移動処理は共有できます。
仮にそうだとしても、オプションそれぞれが自分のいるべき座標を追いかけるようにしてやれば良いと思います。
ついでに言うと、自機を追尾するオプションの場合にも同じことが言えますので、自機を覆う座標と自機を追尾する座標のどちらを参照するかの切り替えができさえすれば移動処理は共有できます。
-
LIFE
Re: 追尾オプションのアレンジ
>> ISLeさん
すみません、まだ言葉足らずだったかもしれません。
「自分を覆う形のままついてくる」というのはあくまで陣形の例えであって、高速移動時にプレイヤーがグラディウス風の追尾オプションで陣形を作り、低速移動に切り替えたらその陣形のままオプションがついてくる、という形にしたいのです。本当にご迷惑をおかけして申しわけありません。
すみません、まだ言葉足らずだったかもしれません。
「自分を覆う形のままついてくる」というのはあくまで陣形の例えであって、高速移動時にプレイヤーがグラディウス風の追尾オプションで陣形を作り、低速移動に切り替えたらその陣形のままオプションがついてくる、という形にしたいのです。本当にご迷惑をおかけして申しわけありません。
Re: 追尾オプションのアレンジ
先に書いたとおり、陣形がどうであれ、オプションのいるべき座標をどう取り出すかが重要なのです。
サンプルプログラムを作ってみました。
参考になるでしょうか。
サンプルプログラムを作ってみました。
参考になるでしょうか。
#include "DxLib.h"
#define OPTION_NUM 5
#define TRACE_PITCH 20
#define HISTORY_NUM ((OPTION_NUM+1)*TRACE_PITCH)
// プレイヤー座標
int PlayerX, PlayerY;
// オプション座標
int OptionX[OPTION_NUM];
int OptionY[OPTION_NUM];
// プレイヤー座標履歴
int HistoryX[HISTORY_NUM];
int HistoryY[HISTORY_NUM];
int history_index;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int i;
ChangeWindowMode(TRUE);
if (DxLib_Init() == -1) {
return 0;
}
SetDrawScreen(DX_SCREEN_BACK);
while (ProcessMessage() == 0) {
/*
* 1. プレイヤーを移動する
*/
if (CheckHitKey(KEY_INPUT_UP)) PlayerY -= 2;
if (CheckHitKey(KEY_INPUT_DOWN)) PlayerY += 2;
if (CheckHitKey(KEY_INPUT_LEFT)) PlayerX -= 2;
if (CheckHitKey(KEY_INPUT_RIGHT)) PlayerX += 2;
/*
* 2. プレイヤー座標履歴を更新する
*/
if (PlayerX != HistoryX[history_index] || PlayerY != HistoryY[history_index]) {
// プレイヤーが移動した
if (CheckHitKey(KEY_INPUT_LSHIFT)) {
// 固定モード
int oldX = HistoryX[history_index];
int oldY = HistoryY[history_index];
// 履歴をプレイヤーの移動分ずらす
for (i=0; i<HISTORY_NUM; i++) {
HistoryX[i] += PlayerX - oldX;
HistoryY[i] += PlayerY - oldY;
}
}
else {
// 通常モード
// 最新履歴にプレイヤー座標を記録する
history_index++;
history_index%=HISTORY_NUM;
HistoryX[history_index] = PlayerX;
HistoryY[history_index] = PlayerY;
}
}
/*
* 3. プレイヤー座標履歴からオプション座標を取得する
*/
for (i=0; i<OPTION_NUM; i++) {
OptionX[i] = HistoryX[(history_index+(i+1)*TRACE_PITCH)%HISTORY_NUM];
OptionY[i] = HistoryY[(history_index+(i+1)*TRACE_PITCH)%HISTORY_NUM];
}
/*
* 4. 画面描画
*/
ClearDrawScreen() ;
for (i=OPTION_NUM-1; i>=0; i--) {
DrawBox(OptionX[i], OptionY[i], OptionX[i]+16, OptionY[i]+16, GetColor(0,0,255), TRUE);
}
DrawBox(PlayerX, PlayerY, PlayerX+16, PlayerY+16, GetColor(255,0,0), TRUE);
ScreenFlip();
}
DxLib_End();
return 0;
}
-
LIFE
Re: 追尾オプションのアレンジ
>> ISLeさん
ありがとうございます。このようなやり方もあったんですね!
ですが、やっぱりこのコードを参考にしても画面端に辿り着いたらオプションが勝手に行ってしまいます……。
あと、恐縮ですが、自分のソースだとこのコードの場合オプションの初期位置がどうやっても左上に設置されるのと、オプションの間隔が最初にキャラを動かし始めた時がとても広く、しばらく動かしているとヨーヨーのように一気にオプションが動いて間隔が狭まり、連なる形になります。
オプションの初期位置の変更と、この間隔の変動を解消するにはどうしたらいいでしょうか。
ありがとうございます。このようなやり方もあったんですね!
ですが、やっぱりこのコードを参考にしても画面端に辿り着いたらオプションが勝手に行ってしまいます……。
あと、恐縮ですが、自分のソースだとこのコードの場合オプションの初期位置がどうやっても左上に設置されるのと、オプションの間隔が最初にキャラを動かし始めた時がとても広く、しばらく動かしているとヨーヨーのように一気にオプションが動いて間隔が狭まり、連なる形になります。
オプションの初期位置の変更と、この間隔の変動を解消するにはどうしたらいいでしょうか。
-
LIFE
Re: 追尾オプションのアレンジ
初期位置も設定できました。ありがとうございます。
けれど、やっぱりヨーヨーのようにしばらく移動していると(斜めに移動すると?)オプションの間隔が変わってしまいます。
けれど、やっぱりヨーヨーのようにしばらく移動していると(斜めに移動すると?)オプションの間隔が変わってしまいます。
Re: 追尾オプションのアレンジ
サンプルプログラムのLIFE さんが書きました:けれど、やっぱりヨーヨーのようにしばらく移動していると(斜めに移動すると?)オプションの間隔が変わってしまいます。
// 最新履歴にプレイヤー座標を記録する
history_index++;
history_index%=HISTORY_NUM;
HistoryX[history_index] = PlayerX;
HistoryY[history_index] = PlayerY;
// 最新履歴にプレイヤー座標を記録する
HistoryX[history_index] = PlayerX;
HistoryY[history_index] = PlayerY;
history_index++;
history_index%=HISTORY_NUM;
これは、インデックス値が最新の履歴を差さなくなるので、プレイヤーが常に動いていると判定されてしまうためです。
移動判定に履歴を使わず、移動前の座標を別の変数に覚えておいても良いのですが。
オプションだけ画面外に進んでしまうのもプレイヤーが移動していると誤判定しているのでしょう。
もしかして座標値を浮動小数点数で比較していて誤差で等しくならないとか。
-
LIFE
Re: 追尾オプションのアレンジ
本当に何度もすみません、ちょっと違います。誤作動の状況を記号で表すと
自機→■
オプション→○
だとするとゲーム起動直後に
■ ○ ○ ○ ○
のような状況になっているのに斜めに移動した途端に
■○○○○
という風になり、自機が撃墜されるまで斜め以外の上下左右移動でも
■○○○○
の状態のままオプションがついてきてしまいます。
画面端まで行ってもオプションが移動してしまう誤作動も、オプションの初期位置も解決できたのですが、コレがどうしても全然分かりません。
自機→■
オプション→○
だとするとゲーム起動直後に
■ ○ ○ ○ ○
のような状況になっているのに斜めに移動した途端に
■○○○○
という風になり、自機が撃墜されるまで斜め以外の上下左右移動でも
■○○○○
の状態のままオプションがついてきてしまいます。
画面端まで行ってもオプションが移動してしまう誤作動も、オプションの初期位置も解決できたのですが、コレがどうしても全然分かりません。