Я следую N обучающему руководству по обработке обнаружения столкновений для одной из моих игр, одна вещь, которая неясна в этом подходе, это то, что они говорили о теореме об отдельной оси на этой странице, но если вы видите в реализации (Учебное пособие A), не гдеЯ мог видеть, что отдельная ось была обработана.Из приведенного ниже URL-адреса в разделе --= round shapes =--
рассказывается, как обрабатывать столкновения между AABB и выпуклыми / вогнутыми формами.http://www.metanetsoftware.com/technique/tutorialA.html#section2
У меня есть базовая идея реализации векторов и отдельных осей, но не этот подход, я понял из этого урока, что весь мир N игр состоит из 5 - 8 различных форм (плиток) каждой плиткив свою очередь вращается горизонтально / вертикально, что дает 4 комбинации, обращенные влево, вправо, сверху и снизу.Эта информация о облицовке хранится в каждой ячейке, обозначенной знаком, у.
obj - это игрок (прямоугольник) t - плитка x, y - проекция ограничивающей рамки
Реализация: Кто-нибудь может объяснить, что именно делает этот код?
function ProjAABB_Concave(x,y,obj,t)
{
//if distance from "innermost" corner of AABB is further than tile radius,
//collision is occuring and we need to project
var signx = t.signx;
var signy = t.signy;
var ox = (t.pos.x + (signx*t.xw)) - (obj.pos.x - (signx*obj.xw));//(ox,oy) is the vector form the innermost AABB corner to the
var oy = (t.pos.y + (signy*t.yw))- (obj.pos.y - (signy*obj.yw));//circle's center
var twid = t.xw*2;
var rad = Math.sqrt(twid*twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile;
//note that this should be precomputed at compile-time since it's constant
var len = Math.sqrt(ox*ox + oy*oy);
var pen = len - rad;
if(0 < pen)
{
//collision; we need to either project along the axes, or project along corner->circlecenter vector
var lenP = Math.sqrt(x*x + y*y);
if(lenP < pen)
{
//it's shorter to move along axis directions
obj.ReportCollisionVsWorld(x,y,x/lenP, y/lenP, t);
return COL_AXIS;
}
else
{
//project along corner->circle vector
ox /= len;//len should never be 0, since if it IS 0, rad should be > than len
oy /= len;//and we should never reach here
obj.ReportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t);
return COL_OTHER;
}
}
return COL_NONE;
}