ページ 11

ブロック侵入不可の処理

Posted: 2015年8月12日(水) 16:27
by 夏休み製作者
プログラムの全文です

コード:


#include <stdio.h>
#include <stdlib.h>
#include "DxLib.h"

int Key[256]; // キーが押されているフレーム数を格納する

			  // キーの入力状態を更新する
int gpUpdateKey() {
	char tmpKey[256]; // 現在のキーの入力状態を格納する
	GetHitKeyStateAll(tmpKey); // 全てのキーの入力状態を得る
	for (int i = 0; i<256; i++) {
		if (tmpKey[i] != 0) { // i番のキーコードに対応するキーが押されていたら
			Key[i]++;     // 加算
		}
		else {              // 押されていなければ
			Key[i] = 0;   // 0にする
		}
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更と初期化と裏画面設定

	int aHandle[13];
	aHandle[0] = LoadGraph("揺髪下128.png");
	aHandle[1] = LoadGraph("揺髪中128.png");
	aHandle[2] = LoadGraph("足上32.png");
	aHandle[3] = LoadGraph("足下32.png");
	aHandle[4] = LoadGraph("足上32.png");
	aHandle[5] = LoadGraph("足下32.png");
	aHandle[6] = LoadGraph("腰64.png");
	aHandle[7] = LoadGraph("左腕32.png");
	aHandle[8] = LoadGraph("右腕上32.png");
	aHandle[9] = LoadGraph("胴64.png");	
	aHandle[10] = LoadGraph("右腕下32.png");
	aHandle[11] = LoadGraph("顔128.png");
	aHandle[12] = LoadGraph("揺髪前128.png");
	int Handle = LoadGraph("block1.png");

	
	int p = 0;
	int q = 0;
	int r = 0;
	int s = 0;
	int Vx = 0;
	int Vy = 0;
	int count_save = 0;
	int count_load = 0;

	
	int RLflag = 0;
	int player_x = 150;
	int player_y = 200;
	int old_player_x = 150;
	int old_player_y = 200;
	int movepos_x [13] = { 64,64,35,35,44,44,41,31,59,41,60,64,64 };
	int movepos_y [13] = { 67,67,90,90,90,90,70,77,79,68,83,67,67 };

	
	int x = 0;
	int y = 0;
	int num = 0;

	
	int block[100][100];
	for (int j = 0; 100 > j; j++) {
		for (int i = 0; 100 > i; i++) {
			block[i][j] = 0;
		}
	}
	for (int i = 0; 100 > i; i++) {
		block[i][3] = 1;
		block[i][12] = 1;
		block[i][13] = 1;
		block[1][i] = 1;
		block[18][i] = 1;
	}

	block[6][4] = 1;
	block[6][11] = 1;
	block[10][10] = 1;
	block[3][10] = 1;
	block[3][11] = 1;
	

	
	typedef struct {
		int move_x ;
		int move_y ;
		float move_r;
	} motion_t;
	motion_t mot[10][10][13];
	for (int k = 0; k < 10; k++) {
		for (int j=0; j < 10; j++) {
			for (int i=0; i < 13; i++) {
				mot[k][j][i] = { movepos_x[i] ,movepos_y[i],0 };
			}
		}
	}

	//セーブデータの読み込み
	FILE *fp;
	errno_t error;
	if (error = fopen_s(&fp, "dst.dat", "rb") != 0) {
		printf("ファイルオープンエラー\n");
		exit(EXIT_FAILURE);
	}
	fread(mot, sizeof(motion_t), 10 * 10 * 13, fp);
	fclose(fp);




	// while(裏画面を表画面に反映, メッセージ処理, 画面クリア, キーの更新)
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && gpUpdateKey() == 0) {

		r++;
		s = r % 4;
		if(s==0){
			p++;
		}
		q = p % 10;

		
		if (Key[KEY_INPUT_RIGHT] >= 1) {
			Vx = 2;
		}
		if (Key[KEY_INPUT_LEFT] >= 1) {
			Vx = -2;
		}
		if (Key[KEY_INPUT_SPACE] == 1) {
			Vy = -20;
		}
		if (Key[KEY_INPUT_DOWN] == 1) {
			player_y++;
		}

		
		old_player_x = player_x;
		old_player_y = player_y;
		player_x += Vx;
		player_y += Vy / 2;

		
		Vx = Vx / 2;
		Vy += 1;

		
		if (Vx > 32){
			Vx = 32;
		}
		if (Vx < -32) {
			Vx = -32;
		}
		if (Vy > 32) {
			Vy = 32;
		}
		if (Vy < -32) {
			Vy = -32;
		}





		if (Vy <0) {
			if (Vx >= 0) {
				if (block[(old_player_x + 48) / 32][(old_player_y - 12) / 32] != 0) {
					if (player_x > (old_player_x+48)-(old_player_x+48)%32-16 &&block[(old_player_x+80)/32][(old_player_y +20)/32] !=0) {
						if (Vx >= 0) {
							if (block[(player_x + 48) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
								Vx = 0;
								player_x -= (player_x + 48) % 32;
							}
						}
						else if (Vy < 0) {
							if (block[(player_x + 28) / 32][(player_y + 20) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
								Vy = 0;
								player_y += 32 - (player_y + 20) % 32;
							}
						}
					}
					if (Vy < 0) {
						if (block[(player_x + 28) / 32][(player_y + 20) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
							Vy = 0;
							player_y += 32 - (player_y + 20) % 32;
						}
					}else if (Vx >= 0) {
						if (block[(player_x + 48) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
							Vx = 0;
							player_x -= (player_x + 48) % 32;
						}
					}
				}else{
					if (Vx >= 0) {
						if (block[(player_x + 48) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
							Vx = 0;
							player_x -= (player_x + 48) % 32;
						}
					}else if (Vy < 0) {
						if (block[(player_x + 28) / 32][(player_y + 20) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
							Vy = 0;
							player_y += 32 - (player_y + 20) % 32;
						}
					}
				}
			}
	
			else if(Vx < 0) {
				if (block[(old_player_x + 28) / 32][(old_player_y - 12) / 32] != 0) {
					if (player_x < (old_player_x+28) - (old_player_x+28)%32-28 && block[(old_player_x - 4) / 32][(old_player_y + 20) / 32] != 0) {
						if (Vx < 0) {
							if (block[(player_x + 28) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 20) / 32] != 0) {
								Vx = 0;
								player_x += 32 - (player_x + 28) % 32;
							}
						}
						else if (Vy < 0) {
							if (block[(player_x + 28) / 32][(player_y + 20) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
								Vy = 0;
								player_y += 32 - (player_y + 20) % 32;
							}
						}
					}
					if (Vy < 0) {
						if (block[(player_x + 28) / 32][(player_y + 20) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
							Vy = 0;
							player_y += 32 - (player_y + 20) % 32;
						}
					}else if (Vx < 0) {
						if (block[(player_x + 28) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 20) / 32] != 0) {
							Vx = 0;
							player_x += 32 - (player_x + 28) % 32;
						}
					}
				}else {
					if (Vx < 0) {
						if (block[(player_x + 28) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 20) / 32] != 0) {
							Vx = 0;
							player_x += 32 - (player_x + 28) % 32;
						}
					}else if (Vy < 0) {
						if (block[(player_x + 28) / 32][(player_y + 20) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
							Vy = 0;
							player_y += 32 - (player_y + 20) % 32;
						}
					}
				}
			}
		}






		if (Vy > 0) {
			if (Vx >= 0) {
				if (block[(old_player_x + 48) / 32][(old_player_y + 134) / 32] != 0) {
					if (player_x > (old_player_x+48)-(old_player_x+48)%32-16 && block[(old_player_x + 80) / 32][(old_player_y + 102) / 32] != 0) {
						if (Vx >= 0) {
							if (block[(player_x + 48) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
								Vx = 0;
								player_x -= (player_x + 48) % 32;
							}
						}
						else if (Vy >= 0) {
							if (block[(player_x + 28) / 32][(player_y + 102) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 102) / 32] != 0) {
								Vy = 0;
								player_y -= (player_y + 102) % 32;
							}
						}
					}
					if (Vy >= 0) {
						if (block[(player_x + 28) / 32][(player_y + 102) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 102) / 32] != 0) {
							Vy = 0;
							player_y -= (player_y + 102) % 32;
						}
					}else if (Vx >= 0) {
						if (block[(player_x + 48) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
							Vx = 0;
							player_x -= (player_x + 48) % 32;
						}
					}
				}else {
					if (Vx >= 0) {
						if (block[(player_x + 48) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
							Vx = 0;
							player_x -= (player_x + 48) % 32;
						}
					}else if (Vy >= 0) {
						if (block[(player_x + 28) / 32][(player_y + 102) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 102) / 32] != 0) {
							Vy = 0;
							player_y -= (player_y + 102) % 32;
						}
					}
				}
			}
			else if (Vx < 0) {
				if (block[(old_player_x + 28) / 32][(old_player_y + 134) / 32] != 0) {
					if (player_x<(old_player_x+28)-(old_player_x+28)%32-28 && block[(old_player_x - 4) / 32][(old_player_y + 102) / 32] != 0) {
						if (Vx < 0) {
							if (block[(player_x + 28) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 20) / 32] != 0) {
								Vx = 0;
								player_x += 32 - (player_x + 28) % 32;
							}
						}
						else if (Vy >= 0) {
							if (block[(player_x + 28) / 32][(player_y + 102) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 102) / 32] != 0) {
								Vy = 0;
								player_y -= (player_y + 102) % 32;
							}
						}
					}
					if (Vy >= 0) {
						if (block[(player_x + 28) / 32][(player_y + 102) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 102) / 32] != 0) {
							Vy = 0;
							player_y -= (player_y + 102) % 32;
						}
					}else if (Vx < 0) {
						if (block[(player_x + 28) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 20) / 32] != 0) {
							Vx = 0;
							player_x += 32 - (player_x + 28) % 32;
						}
					}
				}else {
					if (Vx < 0) {
						if (block[(player_x + 28) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 20) / 32] != 0) {
							Vx = 0;
							player_x += 32 - (player_x + 28) % 32;
						}
					}else if (Vy >= 0) {
						if (block[(player_x + 28) / 32][(player_y + 102) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 102) / 32] != 0) {
							Vy = 0;
							player_y -= (player_y + 102) % 32;
						}
					}
				}
			}
		}




		//block判定
		if (Vx >= 0) {
			if (block[(player_x + 48) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
				Vx = 0;
				player_x -= (player_x + 50) % 32;
			}
		}
		if (Vx < 0) {
			if (block[(player_x + 28) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 20) / 32] != 0) {
				Vx = 0;
				player_x += 32 - (player_x + 28) % 32;
			}
		}
		if (Vy >= 0) {
			if (block[(player_x + 28) / 32][(player_y + 102) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 102) / 32] != 0) {
				Vy = 0;
				player_y -= (player_y + 102) % 32;
			}
		}
		if (Vy < 0) {
			if (block[(player_x + 28) / 32][(player_y + 20) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
				Vy = 0;
				player_y += 32 - (player_y + 20) % 32;
			}
		}

		//ブロック描画
		for (int j = 0; 100 > j; j++) {
			for (int i = 0; 100 > i; i++) {
				if (block[i][j] != 0) {
					DrawRotaGraph(32 * i+16, 32 * j+16, 1.0, 0, Handle, TRUE);
				}
			}
		}

		//描画
		if(Key[KEY_INPUT_LEFT] >= 1){
			for (int i = 0; i < 13; i++){
				DrawRotaGraph(mot[1][q][i].move_x + player_x, mot[1][q][i].move_y + player_y, 1.0, mot[1][q][i].move_r, aHandle[i], TRUE);
				RLflag = 0;
			}
		}else if(Key[KEY_INPUT_RIGHT] >= 1){
			for (int i = 0; i < 13; i++) {
				DrawRotaGraph(80-mot[1][q][i].move_x + player_x, mot[1][q][i].move_y + player_y, 1.0, -mot[1][q][i].move_r, aHandle[i], TRUE, TRUE);
				RLflag = 1;
			}
		}else if(RLflag == 0){
			for (int i = 0; i < 13; i++) {
				DrawRotaGraph(mot[0][q][i].move_x + player_x, mot[0][q][i].move_y + player_y, 1.0, mot[0][q][i].move_r, aHandle[i], TRUE);
			}
		}else if (RLflag == 1) {
			for (int i = 0; i < 13; i++) {
				DrawRotaGraph(80 - mot[0][q][i].move_x + player_x, mot[0][q][i].move_y + player_y, 1.0, -mot[0][q][i].move_r, aHandle[i], TRUE, TRUE);
			}
		}


		
		if (Key[KEY_INPUT_0] && Key[KEY_INPUT_LSHIFT]) {
			num = 0;
		}
		if (Key[KEY_INPUT_1] && Key[KEY_INPUT_LSHIFT]) {
			num = 1;
		}
		if (Key[KEY_INPUT_2] && Key[KEY_INPUT_LSHIFT]) {
			num = 2;
		}
		if (Key[KEY_INPUT_3] && Key[KEY_INPUT_LSHIFT]) {
			num = 3;
		}
		if (Key[KEY_INPUT_4] && Key[KEY_INPUT_LSHIFT]) {
			num = 4;
		}
		if (Key[KEY_INPUT_5] && Key[KEY_INPUT_LSHIFT]) {
			num = 5;
		}
		if (Key[KEY_INPUT_6] && Key[KEY_INPUT_LSHIFT]) {
			num = 6;
		}
		if (Key[KEY_INPUT_7] && Key[KEY_INPUT_LSHIFT]) {
			num = 7;
		}
		if (Key[KEY_INPUT_8] && Key[KEY_INPUT_LSHIFT]) {
			num = 8;
		}
		if (Key[KEY_INPUT_9] && Key[KEY_INPUT_LSHIFT]) {
			num = 9;
		}
		if (Key[KEY_INPUT_0]) {
			x = 0;
		}
		if (Key[KEY_INPUT_1]) {
			x = 1;
		}
		if (Key[KEY_INPUT_2]) {
			x = 2;
		}
		if (Key[KEY_INPUT_3]) {
			x = 3;
		}
		if (Key[KEY_INPUT_4]) {
			x = 4;
		}
		if (Key[KEY_INPUT_5]) {
			x = 5;
		}
		if (Key[KEY_INPUT_6]) {
			x = 6;
		}
		if (Key[KEY_INPUT_7]) {
			x = 7;
		}
		if (Key[KEY_INPUT_8]) {
			x = 8;
		}
		if (Key[KEY_INPUT_9]) {
			x = 9;
		}
		if (Key[KEY_INPUT_Y]) {
			y = 0;
		}
		if (Key[KEY_INPUT_U]) {
			y = 1;
		}
		if (Key[KEY_INPUT_I]) {
			y = 2;
		}
		if (Key[KEY_INPUT_O]) {
			y = 3;
		}
		if (Key[KEY_INPUT_P]) {
			y = 4;
		}
		if (Key[KEY_INPUT_H]) {
			y = 5;
		}
		if (Key[KEY_INPUT_J]) {
			y = 6;
		}
		if (Key[KEY_INPUT_K]) {
			y = 7;
		}
		if (Key[KEY_INPUT_L]) {
			y = 8;
		}
		if (Key[KEY_INPUT_N]) {
			y = 9;
		}
		if (Key[KEY_INPUT_M]) {
			y = 10;
		}
		if (Key[KEY_INPUT_COMMA]) {
			y = 11;
		}
		if (Key[KEY_INPUT_PERIOD]) {
			y = 12;
		}

		
		if (Key[KEY_INPUT_W] == 1) {
			mot[num][x][y].move_y--;
		}
		if (Key[KEY_INPUT_S] == 1) {
			mot[num][x][y].move_y++;
		}
		if (Key[KEY_INPUT_A] == 1) {
			mot[num][x][y].move_x--;
		}
		if (Key[KEY_INPUT_D] == 1) {
			mot[num][x][y].move_x++;
		}
		if (Key[KEY_INPUT_Q] == 1) {
			mot[num][x][y].move_r -=0.05F;
		}
		if (Key[KEY_INPUT_E] == 1) {
			mot[num][x][y].move_r +=0.05F;
		}

		
		for (int i = 0; i < 13; i++) {
			DrawRotaGraph(mot[num][x][i].move_x, mot[num][x][i].move_y, 1.0, mot[num][x][i].move_r, aHandle[i], TRUE);
		}		
		for (int i = 0; i < 13; i++) {
			DrawRotaGraph(mot[num][q][i].move_x + 100, mot[num][q][i].move_y, 1.0, mot[num][q][i].move_r, aHandle[i], TRUE);
		}

		//セーブ関連 
		if (count_save > 0) {
			char name[32] = "セーブしました";
			DrawFormatString(50, 200, GetColor(255, 255, 255), name);
			count_save--;
		}
		if (Key[KEY_INPUT_F1] == 1) {
			count_save = 60;
			FILE *fp;
			errno_t error;
			if (error = fopen_s(&fp, "dst.dat", "wb") != 0) {
				printf("ファイルオープンエラー\n");
				exit(EXIT_FAILURE);
			}
			fwrite(mot, sizeof(motion_t),10*10*13, fp);
			fclose(fp);
		}
		if (count_load > 0) {
			char name[32] = "ロードしました";
			DrawFormatString(50, 200, GetColor(255, 255, 255), name);
			count_load--;
		}
		if (Key[KEY_INPUT_F2] == 1) {
			count_load = 60;
			FILE *fp;
			errno_t error;
			if (error = fopen_s(&fp, "dst.dat", "rb") != 0) {
				printf("ファイルオープンエラー\n");
				exit(EXIT_FAILURE);
			}
			fread(mot, sizeof(motion_t), 10 * 10 * 13, fp);
			fclose(fp);
		}

		//取り消し関連 
		if (Key[KEY_INPUT_F12] == 1) {
			player_x = 150;
			player_y = 200;
		}
		if (Key[KEY_INPUT_F11] == 1) {
			for (int i = 0; i < 13; i++) {
				mot[num][x][i] = { movepos_x[i] ,movepos_y[i],0 };
			}
		}

		//exit
		if (Key[KEY_INPUT_ESCAPE] == 1) {
			printf("終了します");
			exit(EXIT_FAILURE);

		}
	}

	DxLib_End(); // DXライブラリ終了処理
	return 0;
}

http://dixq.net/g/
上記のサイトを参考にDxlibとC言語を使ってテラリアみたいな横スクロールゲームを目指しています
ブロックに侵入したときにVxVyに応じて外に押し出すようにしているのですが、上下を先に押し出すか左右を先に押し出すかで挙動が不自然になる時があります
これを解決すべく色々追記したのですが右上角、右下角が未だに挙動不審です
左上角、左下角はこんな感じで解決したのですが

コード:

					if (player_x < (old_player_x+28) - (old_player_x+28)%32-28) {
						if (Vx < 0) {
							if (block[(player_x + 28) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 28) / 32][(player_y + 20) / 32] != 0) {
								Vx = 0;
								player_x += 32 - (player_x + 28) % 32;
							}
						}
						else if (Vy < 0) {
							if (block[(player_x + 28) / 32][(player_y + 20) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
								Vy = 0;
								player_y += 32 - (player_y + 20) % 32;
							}
						}
					}

右上角、右下角にあたる

コード:


					if (player_x > (old_player_x+48)-(old_player_x+48)%32-16) {
						if (Vx >= 0) {
							if (block[(player_x + 48) / 32][(player_y + 83) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 51) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
								Vx = 0;
								player_x -= (player_x + 48) % 32;
							}
						}
						else if (Vy < 0) {
							if (block[(player_x + 28) / 32][(player_y + 20) / 32] != 0 || block[(player_x + 48) / 32][(player_y + 20) / 32] != 0) {
								Vy = 0;
								player_y += 32 - (player_y + 20) % 32;
							}
						}
					}

が何故か機能していません
具体的に言いますと右上右下において無条件に上下への押し出しが優先されているのですが、old_player_x基準で一つ右のブロックに侵入した場合のみ左への押し出しを優先させたいです
今となってはもっと別のアプローチがあったと思いますがせっかくここまできたのでこのまま使用したいです
対処法?ご教授願います
意味のない条件文はひたすらコピペした際のものです
初心者につき読みづらい文ご容赦ください

Re: ブロック侵入不可の処理

Posted: 2015年8月12日(水) 17:34
by 夏休み製作者
自己解決しました
左に押し出してもまだブロック内だったようで引っかかっていたところの%32を%32+1に変えるとうまくいきました
お騒がせしましたm(__)m