部屋と同じ用途で家具にも当たり判定用の座標を設定して
(家具 = CPUキャラクターにすると同じ構造体が使えて更にforで処理を一括できるので便利)
プレイヤーが移動する関数を作る,
当たり判定用の関数はforでキャラクター構造体を全て当たり判定させて、結果を返すと良いです。
言語は指定されて無いのでCのみ書きます。
※デバッグはしてないけどたぶん動くと思います
// キャラクター最大数
#define CHARA_MAX 512
/// <summary>
/// キャラクターオブジェクトの種類マクロ
/// </summary>
enum Type{
Chara_Player, // 自分
Chara_Cpu, // 自分以外の誰か
Chara_Object, // 家具などの置物
Chara_Wall, // 部屋の壁
}
/// <summary>
/// キャラクターオブジェクト構造体
/// </summary>
struct Chara {
// X座標現在地
int x;
// Y座標現在地
int y;
// 当たり判定座標左X
int cx1;
// 当たり判定座標上Y
int cy1;
// 当たり判定座標右X
int cx2;
// 当たり判定座標下Y
int cy2;
// 種類(ここで家具やら自分やらを判別するといい)
Type type;
// グラフィックハンドルとか
int Handle;
// ...
};
/// <summary>
/// 全てのキャラクターオブジェクト(ここにCPUキャラや家具などのオブジェクトを全て設定する)
/// </summary>
Chara Chara_s[CHARA_MAX];
/// <summary>
/// キャラクターを移動する
/// </summary>
/// <param name="x">移動する距離X</param>
/// <param name="y">移動する距離Y</param>
/// <param name="chara">移動するキャラorオブジェクトのポインタ(int Indexでもできるけど)</param>
void CharaMove(int x,int y, Chara* chara){
// x座標を当たり判定をしつつ移動する
for(int i = 0; i < abs(x); i++){
他のキャラクターorオブジェクトにx座標が当たっていたらforから脱出
if(CollisionDetection(chara) == 1)break;
// X座標を1pxだけ移動 (絶対値で割るとどちらの方向に1移動するかがわかる)
chara.x += (x / abs(x));
}
// y座標を当たり判定をしつつ移動する
for(int i = 0; i < abs(y); i++){
他のキャラクターorオブジェクトにy座標が当たっていたらforから脱出
if(CollisionDetection(chara) == 1)break;
// Y座標を1pxだけ移動 (絶対値で割るとどちらの方向に1移動するかがわかる)
chara.y += (y / abs(y));
}
}
/// <summary>
/// キャラクター同士の当たり判定
/// </summary>
/// <param name="chara">判定対象のキャラクターポインタ</param>
/// <returns>結果(当たった:1 当たらなかった:0)</returns>
int CollisionDetection(Chara* chara){
// 全キャラクターを判定 (CHARA_MAXでもOK)
for(int i = 0; i < (sizeof(Chara_s) / sizeof(Chara)); i++){
// 自分はスキップ
if(&Chara_s[i] == chara) continue;
// 当たり判定座標 + 現在地
const int ax1 = chara->cx1 + chara->x;
const int ay1 = chara->cy1 + chara->y;
const int ax2 = chara->cx2 + chara->x;
const int ay2 = chara->cy2 + chara->y;
const int bx1 = Chara_s[i].cx1 + Chara_s[i].x;
const int by1 = Chara_s[i].cy1 + Chara_s[i].y;
const int bx2 = Chara_s[i].cx2 + Chara_s[i].x;
const int by2 = Chara_s[i].cy2 + Chara_s[i].y;
// 判定
if((ax1 < bx2) && (bx1 < ax2) && (ay1 < by2) && (by1 < ay2)){
return 1;
}
}
return 0;
}