ページ 11

【DXLib】弾の連射について

Posted: 2015年8月15日(土) 21:48
by recomm
はじめまして、DXライブラリを勉強し始めてから間もない者です

マップを生成し、そのマップ上でキャラクターを戦わせる一種のTPSのようなものを作っております
そこでさまざまなサイトを参考にして組んだのですが、現在の私の弾発射のコードは単発でここから連射できるようにしたいです
SPACEキーを押すことで弾を発射します
コードです

コード:

#include "DxLib.h"

int player[12], chip[2], shot;
int px = 1, py = 1;
int sx, sy;
bool sf = false;
int num = 1;

int map[15][20] = {
	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
	{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 },
	{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1 },
	{ 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1 },
	{ 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
	{ 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
	{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
	{ 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1 },
	{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
	{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
	{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
	{ 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1 },
	{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
	{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
	{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
};

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	ChangeWindowMode(TRUE);
	DxLib_Init();
	SetDrawScreen(DX_SCREEN_BACK);

	LoadDivGraph("../player.png", 12, 3, 4, 32, 32, player);
	LoadDivGraph("../mapchip.png", 2, 2, 1, 32, 32, chip);
	shot = LoadGraph("../shot.png");

	while (!ProcessMessage()) {
		ClearDrawScreen();

		int kx = px, ky = py;
		if (CheckHitKey(KEY_INPUT_LEFT)) {
			kx--;
			num = 4;
		}
		if (CheckHitKey(KEY_INPUT_RIGHT)) {
			kx++;
			num = 7;
		}
		if (CheckHitKey(KEY_INPUT_UP)) {
			ky--;
			num = 10;
		}
		if (CheckHitKey(KEY_INPUT_DOWN)) {
			ky++;
			num = 1;
		}
		if (map[ky][kx] != 1) {
			px = kx;
			py = ky;
		}

		if (CheckHitKey(KEY_INPUT_SPACE)) {
			if (!sf) {
				sf = true;
				sx = px * 32;
				sy = py * 32;
			}
		}
		if (sf) {
			switch (num)
			{
			case 4:
				sx -= 31;
				break;
			case 7:
				sx += 31;
				break;
			case 10:
				sy -= 31;
				break;
			case 1:
				sy += 31;
				break;
			}
			if (sy < 0) sf = false;

 			if (map[sy/32][sx/32] == 1) {
				sf = false;
			}
		} 

		for (int y = 0; y < 15; y++) {
			for (int x = 0; x < 20; x++) {
				DrawGraph(x * 32, y * 32, chip[map[y][x]], FALSE);
			}
		}

		if (sf) DrawGraph(sx, sy, shot, TRUE);
		DrawGraph(px * 32, py * 32, player[num], TRUE);
		ScreenFlip();
		WaitTimer(40);
	}

	DxLib_End();
	return 0;
}
お願いします

Re: 【DXLib】弾の連射について

Posted: 2015年8月15日(土) 22:16
by みけCAT
recomm さんが書きました:はじめまして、DXライブラリを勉強し始めてから間もない者です

マップを生成し、そのマップ上でキャラクターを戦わせる一種のTPSのようなものを作っております
そこでさまざまなサイトを参考にして組んだのですが、現在の私の弾発射のコードは単発でここから連射できるようにしたいです
頑張ってください。
もしわからないことがあれば、質問をしてみるのもいいかもしれません。

Re: 【DXLib】弾の連射について

Posted: 2015年8月15日(土) 22:20
by recomm
あ、申し訳ございません
肝心の質問が抜けていました
現在の単発のコードから連射を可能にするにはどう書き換えればよいのでしょうか

Re: 【DXLib】弾の連射について

Posted: 2015年8月15日(土) 22:25
by みけCAT
recomm さんが書きました:現在の単発のコードから連射を可能にするにはどう書き換えればよいのでしょうか
  • 弾の情報を配列を用い、複数管理できるようにする
  • SPACEキーが押されている間毎フレーム弾を撃とうとするのではなく、適当な間隔で弾を撃つ処理を実行するようにする
基本的にはこの2点だと思います。

Re: 【DXLib】弾の連射について

Posted: 2015年8月16日(日) 22:14
by recomm
がんばってプログラムを組んでみました
ちゃんと連射自体はできたのですがバグが起きました
私が参考にしていたサイトはどこも上向きオンリーのシューティングだったのでもちろん下を向いたりすることなど想定外です。
そのため私のプログラムでは方向転換時に発射した全ての弾が同時に向いた方向へ流れてしまいます
numで向いている方向を取得し、そのnumの値によって弾の座標を動かすもので、原因はそこにあるとわかっているのですが…
弾一つ一つを独立させることはできないのでしょうか

コード:

while (!ProcessMessage() && gpUpdateKey() == 0) {
		ClearDrawScreen();

		if (Key[KEY_INPUT_Z] && shotcount % 5 == 1){
			flag = true;
		}
		if (Key[KEY_INPUT_Z] == 0)
		{
			shotcount = 0;
		}
		if (flag){
			for (int j = 0; j < 30; j++){
				if (sh[j].use_flag[j] == 0){
					sh[j].x[j] = px * 32;
					sh[j].y[j] = py * 32;
					sh[j].use_flag[j] = 1;
					j = 30;
				}
			}
			bullet = 1;
			flag = false;
		}
		if (bullet == 1){
			for (int j = 0; j < 30; j++){
				if (sh[j].use_flag[j] == 1 && sh[j].y[j] < 480){
					switch (num)
					{
					case 4:
						sh[j].x[j] -= 4;
						break;
					case 7:
						sh[j].x[j] += 4;
						break;
					case 10:
						sh[j].y[j] -= 4;
						break;
					case 1:
						sh[j].y[j] += 4;
						break;
					}
				}
				else{
					sh[j].use_flag[j] = 0;
				}
				if (map[sh[j].y[j] / 32][sh[j].x[j] / 32] == 1) {
					sh[j].use_flag[j] = 0;
				}
			}
		}


		int kx = px, ky = py;
		if (CheckHitKey(KEY_INPUT_LEFT)) {
			kx--;
			num = 4;
		}
		if (CheckHitKey(KEY_INPUT_RIGHT)) {
			kx++;
			num = 7;
		}
		if (CheckHitKey(KEY_INPUT_UP)) {
			ky--;
			num = 10;
		}
		if (CheckHitKey(KEY_INPUT_DOWN)) {
			ky++;
			num = 1;
		}
		if (map[ky][kx] != 1) {
			px = kx;
			py = ky;
		}

		if (CheckHitKey(KEY_INPUT_SPACE)) {
			if (!sf) {
				sf = true;
				sx = px * 32;
				sy = py * 32;
			}
		}
		if (sf) {
			switch (num)
			{
			case 4:
				sx -= 31;
				break;
			case 7:
				sx += 31;
				break;
			case 10:
				sy -= 31;
				break;
			case 1:
				sy += 31;
				break;
			}
			if (sy < 0) sf = false;

 			if (map[sy/32][sx/32] == 1) {
				sf = false;
			}
		} 

		for (int y = 0; y < 15; y++) {
			for (int x = 0; x < 20; x++) {
				DrawGraph(x * 32, y * 32, chip[map[y][x]], FALSE);
			}
		}

		if (bullet == 1){
			for (int j = 0; j < 30; j++){
				if (sh[j].use_flag[j] == 1){
					sh[j].draw_x[j] = sh[j].x[j];
					sh[j].draw_y[j] = sh[j].y[j];
				}
			}
		}
		if (bullet == 1){
			for (int j = 0; j < 30; j++){
				if (sh[j].use_flag[j] == 1){
					DrawGraph(sh[j].draw_x[j], sh[j].draw_y[j], shot, TRUE);
				}
			}
		}


		if (sf) DrawGraph(sx, sy, shot, TRUE);
		DrawGraph(px * 32, py * 32, player[num], TRUE);
		ScreenFlip();
		WaitTimer(40);

		shotcount++;
	}

Re: 【DXLib】弾の連射について

Posted: 2015年8月16日(日) 22:24
by みけCAT
recomm さんが書きました:numで向いている方向を取得し、そのnumの値によって弾の座標を動かすもので、原因はそこにあるとわかっているのですが…
弾一つ一つを独立させることはできないのでしょうか
できます。
numまたは弾の速度を弾のデータを管理する構造体に保存しましょう。
オフトピック
recomm さんが書きました:

コード:

		if (bullet == 1){
			for (int j = 0; j < 30; j++){
				if (sh[j].use_flag[j] == 1){
					sh[j].draw_x[j] = sh[j].x[j];
					sh[j].draw_y[j] = sh[j].y[j];
				}
			}
		}
		if (bullet == 1){
			for (int j = 0; j < 30; j++){
				if (sh[j].use_flag[j] == 1){
					DrawGraph(sh[j].draw_x[j], sh[j].draw_y[j], shot, TRUE);
				}
			}
		}
なんで弾の構造体配列の要素のメンバと推測されるものに添字っぽいものが付いているんだ…?怪しいなあ…?
shの型がわからないから断定はできないけど、まさかメモリを本来必要な量の約2乗 (2倍ではない) も確保するようなバカな真似はしていないよな…?

Re: 【DXLib】弾の連射について

Posted: 2015年8月16日(日) 22:55
by recomm
みけCAT さんが書きました: できます。
numまたは弾の速度を弾のデータを管理する構造体に保存しましょう。
numを保存する場合のコードはどうすればよいのでしょうか
私も似たようなことを試してみましたが、numは方向キーを押すたびに変わるので別の変数を経由しても結局上書きされてしまいます。

みけCAT さんが書きました:なんで弾の構造体配列の要素のメンバと推測されるものに添字っぽいものが付いているんだ…?怪しいなあ…?
shの型がわからないから断定はできないけど、まさかメモリを本来必要な量の約2乗 (2倍ではない) も確保するようなバカな真似はしていないよな…?
ご指摘ありがとうございます、修正しました
参考サイトを見てみましたが当たり前にこのようなミスはありませんでした
なぜ私はつけてしまったんでしょうか…

Re: 【DXLib】弾の連射について

Posted: 2015年8月16日(日) 23:06
by みけCAT
recomm さんが書きました:numを保存する場合のコードはどうすればよいのでしょうか
例えば、shの型を適切に修正した後、
16行目と17行目の間に

コード:

					sh[j].num = num;
を追加し、26行目を

コード:

					switch (sh[j].num)
に変更するといいと思います。(テストしていません)

Re: 【DXLib】弾の連射について

Posted: 2015年8月17日(月) 00:31
by recomm
おお!!できました!
なるほど、保存と利用の仕組みがよくわかりました
ありがとうございました