ブロック侵入不可の処理
Posted: 2015年8月12日(水) 16:27
プログラムの全文です
http://dixq.net/g/
上記のサイトを参考にDxlibとC言語を使ってテラリアみたいな横スクロールゲームを目指しています
ブロックに侵入したときにVxVyに応じて外に押し出すようにしているのですが、上下を先に押し出すか左右を先に押し出すかで挙動が不自然になる時があります
これを解決すべく色々追記したのですが右上角、右下角が未だに挙動不審です
左上角、左下角はこんな感じで解決したのですが
右上角、右下角にあたる
が何故か機能していません
具体的に言いますと右上右下において無条件に上下への押し出しが優先されているのですが、old_player_x基準で一つ右のブロックに侵入した場合のみ左への押し出しを優先させたいです
今となってはもっと別のアプローチがあったと思いますがせっかくここまできたのでこのまま使用したいです
対処法?ご教授願います
意味のない条件文はひたすらコピペした際のものです
初心者につき読みづらい文ご容赦ください
#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;
}
上記のサイトを参考に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基準で一つ右のブロックに侵入した場合のみ左への押し出しを優先させたいです
今となってはもっと別のアプローチがあったと思いますがせっかくここまできたのでこのまま使用したいです
対処法?ご教授願います
意味のない条件文はひたすらコピペした際のものです
初心者につき読みづらい文ご容赦ください