具体的には天井に衝突すると天井をすり抜けるということとジャンプ無しで落下すると高速で落下するということです。
Collision.h
#pragma once
class CCollision {
float OffsetL, OffsetU, OffsetR, OffsetD;
POINT mPt[8];
int ColType;
public:
CCollision(POINT pt[], float offset_l, float offset_u, float offset_r, float offset_d, int col_type);
void Init();
void GetMove(float* myx, float* myy, float* addx, float* addy, int* jcount, bool* gflag);
POINT CheckMap(int x, int y);
void GetXPosition(float* myx, float* myy, float* addx, float* addy);
void GetYPosition(float* myx, float* myy, float* addx, float* addy, int* jcount, bool* gflag);
};
#include "Main.h"
#include "Mapping.h"
#include "Collision.h"
CCollision::CCollision(POINT pt[], float offset_l, float offset_u, float offset_r, float offset_d, int col_type)
: OffsetL(offset_l), OffsetU(offset_u), OffsetR(offset_r), OffsetD(offset_d), ColType(col_type){
Init();
for (int i = 0; i < 8; i++)
{
mPt[i].x = pt[i].x;
mPt[i].y = pt[i].y;
}
}
void CCollision::Init(){
ZeroMemory(mPt, sizeof(mPt));
}
POINT CCollision::CheckMap(int x, int y){
POINT pt[] ={
{ x + mPt[0].x, y + mPt[0].y },//左上
{ x + mPt[1].x, y + mPt[1].y },//上真ん中
{ x + mPt[2].x, y + mPt[2].y },//右上
{ x + mPt[3].x, y + mPt[3].y },//左真ん中
{ x + mPt[4].x, y + mPt[4].y },//右真ん中
{ x + mPt[5].x, y + mPt[5].y },//左下
{ x + mPt[6].x, y + mPt[6].y },//下真ん中
{ x + mPt[7].x, y + mPt[7].y },//右下
};
POINT res = { x, y };
DWORD cwidth = MapObj.GetChipWidth();
DWORD cheight = MapObj.GetChipHeight();
//マップエディターの特性上、マップチップを0にしないと当たり判定を認識してくれないようです。
for (int i = 0; i < 8; i++){
//当たり判定のレイヤを読み込む。
int index = MapObj.GetValue(1, pt[i].x / MAP_CELL, pt[i].y / MAP_CELL);
int src_x = (index % BitCount) * cwidth;
int src_y = (index / BitCount) * cheight;
if (src_x == 0 && src_y == 0){
res.x = pt[i].x / MAP_CELL;//壁の座標を代入
res.y = pt[i].y / MAP_CELL;
return res;//壁の座標を返す
}
}
res.x = -1;//ここまで来たら当たっていないということ
res.y = -1;
return res;
}
void CCollision::GetXPosition(float* myx, float* myy, float* addx, float* addy) {
float newx;
float tempx = *myx;
float tempaddx = *addx;
newx = tempx + tempaddx;
POINT block = CheckMap((int)newx, (int)*myy);
if (block.x == -1) {
*myx = newx;
}
else {
if (tempaddx > 0) {
*myx = (float)((block.x - 1) * 16 + 8 + OffsetR - 0.1f);
}
else {
*myx = (float)((block.x + 1) * 16 + 8 + OffsetL + 0.1f);
}
*addx = 0;//当たっているので移動させない。
}
}
void CCollision::GetYPosition(float* myx, float* myy, float* addx, float* addy, int* jcount, bool* gflag) {
float newy = *myy + *addy;
POINT block = CheckMap((int)*myx, (int)newy);
if (block.y == -1) {
*myy = newy;
gflag = false;
}
else {
if (addy < 0) {
//何故か、天井をすり抜けてしまう。
*myy = (float)((block.y + 1) * 16 + 8 - OffsetU);
}
else {
*myy = (float)((block.y - 1) * 16 + 8 + OffsetD - 0.1f);
*jcount = 0;
*gflag = true;
}
}
}
void CCollision::GetMove(float* myx, float* myy, float* addx, float* addy, int* jcount, bool* gflag) {
GetXPosition(myx, myy, addx, addy);
if (*addy > GRAVMAX)
{
*addy = GRAVMAX;
}
else
{
*addy += GRAV;
}
GetYPosition(myx, myy, addx, addy, jcount, gflag);
}