はじめて質問させていただきます。
Wlibというライブラリを使いながらC言語でvisual studio 2005,または2008で作成しているのですが、
プレイヤーと壁との当たり判定が上手くいきません。
Wlibを使っているのは先頭にW.が入っているもの、これではプレイヤーと配列で並べた壁の描画、ならびにパッドの入力を得るのに使われています。
壁との当たり判定をプレイヤーの向いている方向とプレイヤーの座標より16ずらしたところ壁があるのかどうかで判定しています。
しかしプレイヤーの左と上方向を入力したときの当たり判定がおかしく壁にぶつかる前に止まってしまいます。
ソースを乗せるので何か気付いた方は意見などもらえるとうれしいです。
//ヘッダーの読み込み
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "WlibDL/wlib_dl.h"
#include "WlibDL/wlib_link.h"
#include "WlibDL/wlibDL_macro.h"
#define GAME_START 1
//全体の大きさ
#define MAX_X 640
#define MAX_Y 480
#define MIN_X 0
#define MIN_Y 0
//壁の最大量
#define MAP_X 40
#define MAP_Y 30
//壁の大きさ
#define WALL_X 16
#define WALL_Y 16
//壁のある、なし、ゴール
#define WALL_ON 1
#define WALL_OFF 0
#define WALL_GOAL 2
//プレイヤーの向き
#define PL_NOT 0
#define PL_UP 1
#define PL_LEFT 2
#define PL_DOWN 3
#define PL_RIGHT 4
//歩くフラグのON,OFF
#define WALK_ON 1
#define WALK_OFF 0
//主にプレイヤーの構造体
typedef struct{
int x,y;
int sw;
int spd;
int direction;
int walking_flug;
}CONTROL;
//X:40
//Y:30
//マップの配列データ入力
int wall[ MAP_Y ][ MAP_X ] = {
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 },
{ 0,1,0,1,0,0,1,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,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,0,0,0,0,0,1,0 },
{ 0,1,0,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,1,1,0,1,0,1,0,0,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,0,0,0,1,0,1,0,1,0,0,1,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,1,1,0,1,0,1,1,1,1,0,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,0,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,1,0,0,1,0,1,1,1,1,1,0,1,1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,1,1,0 },
{ 0,1,0,1,0,1,0,1,1,0,1,1,0,1,0,0,0,0,1,0,1,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,0,0,0,0,0,1,1,1,1,0,1,1,0,1,0,1,1,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0 },
{ 0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 },
{ 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },
};
//壁に突き当たったか判定して止める関数////////////////////////////////////////////////////////////////////////////////
int IsAbleToGo( CONTROL player ){ //
//上向きの方向キーが入力された時 //
//壁が進行方向にある場合歩くフラグを0にする //
if( player.direction == PL_UP ){ //
if( wall[ ( player.y / WALL_Y ) - 1 ][ player.x / WALL_X ] == WALL_ON ) //
return 1; //
} //
//左向きの方向キーが入力された時 //
//壁が進行方向にある場合歩くフラグを0にする //
else if( player.direction == PL_LEFT ){ //
if( wall[ player.y / WALL_Y ][ ( player.x / WALL_X ) - 1] == WALL_ON ) //
return 1; //
} //
//下向きの方向キーが入力された時 //
//壁が進行方向にある場合歩くフラグを0にする //
else if( player.direction == PL_DOWN ){ //
if( wall[ ( player.y / WALL_Y ) + 1 ][ player.x / WALL_X ] == WALL_ON ) //
return 1; //
} //
//右向きの方向キーが入力された時 //
//壁が進行方向にある場合歩くフラグを0にする //
else if( player.direction == PL_RIGHT ){ //
if( wall[ player.y / WALL_Y ][ ( player.x / WALL_X ) + 1] == WALL_ON ) //
return 1; //
} //
return 0; //
} //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////
//ここからスタート
int main(void)
{
//変数の宣言//////////////////
int i , j; //
PAD pad; //
CONTROL player; //
int count = 0; //
//////////////////////////////
//プレイヤーデータ初期化
//・プレイヤーのXY座標
//・プレイヤーの方向キーは入力なし(0)
//・プレイヤーの歩くフラグはOFF
//////////////////////////////////////////
//プレイヤー座標は16×16の左上 //
player.x = MIN_X + 64; //
player.y = MAX_Y - 16; //
player.direction = PL_NOT; //
player.spd = 4; //
player.sw = 0; //
player.walking_flug = WALK_OFF; //
//////////////////////////////////////
///////////////////////////////////////////本ループ開始/////////////////////////////////////////////////////////////////////
while( GAME_START ){
//PADデータを取得/////////////
pad = W.GetPadData( 0 ); //
//////////////////////////////
//壁がある部分に描画//////////////////////////////////////////////////////////////////////////////////////////////////////
for( i = 0; i < MAP_Y ; i++){ //
for( j = 0; j < MAP_X ; j++){ //
//壁が存在するときの処理 //
if( wall[ i ][ j ] == WALL_ON){ //
//壁描画 //
W.DrawLine( j * WALL_X , i * WALL_Y ,( j + 1 ) * WALL_X,( i + 1 ) * WALL_Y, RGBto( 255,255,255 ), DW_FILL );//
} //
//ゴールポイントを描画 //
if( wall[ i ][ j ] == 2){ //
W.DrawLine( j * WALL_X , i * WALL_Y ,( j + 1 ) * WALL_X,( i + 1 ) * WALL_Y, RGBto( 255,0,0 ), DW_FILL ); //
} //
} //
} //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//進む方向入力////////////////////////////////////////////////////
//プレイヤーの座標と壁の大きさを割った余りがないとき //
if( !( player.x % WALL_X ) && !( player.y % WALL_Y ) ) //
{ //
//歩くフラグを立てる //
player.walking_flug = WALK_ON; //
//上の方向キーが入力された時 //
if( pad.press & PAD_UP ) //
//上向きフラグを立てる //
player.direction = PL_UP; //
//左の方向キーが入力された時 //
if( pad.press & PAD_LEFT ) //
//左向きフラグを立てる //
player.direction = PL_LEFT; //
//下の方向キーが入力された時 //
if( pad.press & PAD_DOWN ) //
//下向きフラグを立てる //
player.direction = PL_DOWN; //
//右の方向キーが入力された時 //
if( pad.press & PAD_RIGHT ) //
//右向きフラグを立てる //
player.direction = PL_RIGHT; //
} //
//////////////////////////////////////////////////////////////////
//壁に当たっているか判定//////////////////////
if( player.walking_flug == WALK_ON ){ //
if( IsAbleToGo( player ) ) //
player.walking_flug = WALK_OFF; //
} //
//////////////////////////////////////////////
//それぞれの方向のスピード調整////////////////////////////////////////////////////////////////
//プレイヤーの歩くフラグが立っている時 //
if( player.walking_flug == WALK_ON){ //
//上へ移動 //
if( player.direction == PL_UP && !( player.y == MIN_Y )){ //
player.y -= player.spd; //
} //
//左へ移動 //
if( player.direction == PL_LEFT && !( player.x == MIN_X )){ //
player.x -= player.spd; //
} //
//下へ移動 //
if( player.direction == PL_DOWN && !( player.y + 16 == MAX_Y )){ //
player.y += player.spd; //
} //
//右へ移動 //
if( player.direction == PL_RIGHT && !(player.x + 16 == MAX_X)){ //
player.x += player.spd; //
} //
} //
// else //
// player.walking_flug = WALK_OFF; //
//////////////////////////////////////////////////////////////////////////////////////////////
//プレイヤーを描く //
W.DrawLine( player.x,player.y, player.x + 16, player.y + 16, RGBto( 0,255,255), DW_FILL ); //
W.RefreshScreen(0);
W.Clear(0);
DebPutHex( player.x , 420 , 240 ) ;
DebPutHex( player.walking_flug , 400 , 250 ) ;
count++;
}
return 0;
}