int StaticCircleToStaticRectangle(Vector2D *pCenter, float Radius, Vector2D *pRect, float Width, float Height) { Vector2D point = *pCenter; if (pCenter->x > pRect->x + Width / 2.0f) { point.x = pRect->x + Width / 2.0f; } else if (pCenter->x < pRect->x - Width / 2.0f) { point.x = pRect->x - Width / 2.0f; } if (pCenter->y > pRect->y + Width / 2.0f) { point.y = pRect->y + Width / 2.0f; } else if (pCenter->y < pRect->y - Width / 2.0f) { point.y = pRect->y - Width / 2.0f; } if (StaticPointToStaticCircle(&point, pCenter, Radius)) { return 1; } else return 0; }
bool PointCollisionCheck(Vector2 point, BB* a, Vector2 posA) { BB_Circle* circ; BB_Rectangle* rect; switch(a->type) { case(Circle): circ = static_cast<BB_Circle*>(a); return StaticPointToStaticCircle(&point, &posA, circ->radius) > 0; break; case(Rect): rect = static_cast<BB_Rectangle*>(a); return StaticPointToStaticRect(&point, &posA, rect->extents.x, rect->extents.y) > 0; break; } return false; }
int StaticCircleToStaticRectangle(Vector2D *pCenter, float Radius, Vector2D *pRect, float Width, float Height) { Vector2D snapped = { 0 }; if (pCenter->x > pRect->x - Width /2) snapped.x = pRect->x - Width / 2; else if (pCenter->x < pRect->x + Width / 2) snapped.x = pRect->x + Width / 2; if (pCenter->y > pRect->y + Height / 2) snapped.y = pRect->y + Height / 2; else if (pCenter->y > pRect->y - Height / 2) snapped.y = pRect->y - Height / 2; return StaticPointToStaticCircle(&snapped, pCenter, Radius); }
int main() { Vector2D v1, v2, v3, result; float scale; Matrix2D id, m0, m1; Vector2D u; float d, x, y; long n; long i, j; float radius; v1.x = v1.y = 7.0f; Vector2DZero(&v1); result.x = result.y = 0.0f; printf("Vector2DZero: %s\n", (CompareVector2D(&result, &v1) < EPSILON) ? "Pass" : "Fail"); Vector2DSet(&v1, 1.0f, 2.0f); result.x = 1.0f; result.y = 2.0f; printf("Vector2DSet: %s\n", (CompareVector2D(&result, &v1) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = -4.0f; Vector2DNeg(&v2, &v1); result.x = -2.0f; result.y = 4.0f; printf("Vector2DNeg: %s\n", (CompareVector2D(&result, &v2) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = -4.0f; v2.x = 1.0f; v2.y = 7.0f; Vector2DAdd(&v3, &v1, &v2); result.x = result.y = 3.0f; printf("Vector2DAdd: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = -4.0f; v2.x = 1.0f; v2.y = 7.0f; Vector2DSub(&v3, &v1, &v2); result.x = 1.0f; result.y = -11.0f; printf("Vector2DSub: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail"); v1.x = 3.0f; v1.y = 4.0f; Vector2DNormalize(&v2, &v1); result.x = 0.6f; result.y = 0.8f; printf("Vector2DNormalize: %s\n", (CompareVector2D(&result, &v2) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = -5.0f; Vector2DScale(&v2, &v1, 3.0f); result.x = 6.0f; result.y = -15.0f; printf("Vector2DScale: %s\n", (CompareVector2D(&result, &v2) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = -5.0f; v2.x = 6.0f; v2.y = 2.0f; scale = 3.0f; Vector2DScaleAdd(&v3, &v1, &v2, scale); result.x = 12.0f; result.y = -13.0f; printf("Vector2DScaleAdd: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail"); Vector2DScaleSub(&v3, &v1, &v2, scale); result.x = 0.f; result.y = -17.f; printf("Vector2DScaleSub: %s\n", (CompareVector2D(&result, &v3) < EPSILON) ? "Pass" : "Fail"); v1.x = 3.0f; v1.y = -4.0f; printf("Vector2DLength: %s\n", (fabs(Vector2DLength(&v1) - 5.0f) < EPSILON) ? "Pass" : "Fail"); v1.x = 3.0f; v1.y = -4.0f; printf("Vector2DSquareLength: %s\n", (fabs(Vector2DSquareLength(&v1) - 25.0f) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = 3.0f; v2.x = 4.0f; v2.y = -1.0f; printf("Vector2DDistance: %s\n", (fabs(Vector2DDistance(&v1, &v2) - 4.472136) < EPSILON) ? "Pass" : "Fail"); v1.x = 2.0f; v1.y = 3.0f; v2.x = 4.0f; v2.y = -1.0f; printf("Vector2DSquareDistance: %s\n", (fabs(Vector2DSquareDistance(&v1, &v2) - 20.0f) < EPSILON) ? "Pass" : "Fail"); v1.x = 3.0f; v1.y = 2.0f; v2.x = 4.0f; v2.y = -6.0f; printf("Vector2DDotProduct: %s\n", (fabs(Vector2DDotProduct(&v1, &v2)) < EPSILON) ? "Pass" : "Fail"); printf("\n------Testing StaticPointToStaticCircle------\n\n"); v1.x = 10.f; v1.y = 10.f; v2.x = 11.4f; v2.y = 11.4f; radius = 2.f; printf("StaticPointToStaticCircle Collision: %s\n", (StaticPointToStaticCircle(&v2, &v1, radius)) ? "Pass" : "Fail" ); v2.x = 12.f; v2.y = 12.f; printf("StaticPointToStaticCircle Non Collision: %s\n", (!StaticPointToStaticCircle(&v2, &v1, radius)) ? "Pass" : "Fail" ); printf("\n------Running Matrix Tests------\n\n"); // create an id matrix for reference for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) id.m[j][i] = (i == j) ? 1.0f : 0.0f; // ==================== // test Matrix2DIdentity // ==================== Matrix2DIdentity(&m0); d = CompareMatrix2D(&id, &m0); printf("Matrix2DIdentity : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // ==================== // test Matrix2DTrans // ==================== // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; Matrix2DTranslate(&m0, x, y); m0.m[0][2] -= x; m0.m[1][2] -= y; printf("Matrix2DTranslate: %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // ==================== // test Matrix2DScale // ==================== // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; Matrix2DScale(&m0, x, y); m0.m[0][0] /= x; m0.m[1][1] /= y; printf("Matrix2DScale : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // ==================== // test Matrix2DConcat // ==================== // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; Matrix2DTranslate (&m0, x, y); Matrix2DScale (&m1, x, y); Matrix2DConcat(&m0, &m0, &m1); m0.m[0][2] -= x; m0.m[1][2] -= y; m0.m[0][0] /= x; m0.m[1][1] /= y; printf("Matrix2DConcat 1 : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; Matrix2DTranslate (&m0, x, y); Matrix2DScale (&m1, x, y); Matrix2DConcat(&m0, &m1, &m0); m0.m[0][2] -= x * x; m0.m[1][2] -= y * y; m0.m[0][0] /= x; m0.m[1][1] /= y; printf("Matrix2DConcat 2 : %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // ==================== // test Matrix2DRotRad // ==================== n = (rand() % 16) + 15; Matrix2DIdentity(&m0); Matrix2DRotRad (&m1, 2.0f * PI / n); for (i = 0; i < n; i++) Matrix2DConcat(&m0, &m1, &m0); printf("Matrix2DRotRad : %s (%d)\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail", n); // ==================== // test Matrix2DRotDeg // ==================== n = (rand() % 16) + 15; Matrix2DIdentity(&m0); Matrix2DRotDeg (&m1, 360.0f / n); for (i = 0; i < n; i++) Matrix2DConcat(&m0, &m1, &m0); printf("Matrix2DRotDeg : %s (%d)\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail", n); // ==================== // test Matrix2DTranspose // ==================== Matrix2DRotRad (&m0, rand() / (float)(RAND_MAX) * 2.0f * PI); Matrix2DTranspose(&m1, &m0); Matrix2DConcat (&m0, &m1, &m0); printf("Matrix2DTranspose: %s\n", (CompareMatrix2D(&id, &m0) < EPSILON) ? "Pass" : "Fail"); // ==================== // test Matrix2DMultVec // ==================== // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; n = (rand() % 16) + 15; Vector2DSet (&u, x, y); Matrix2DRotRad (&m0, 2.0f * PI / n); for (i = 0; i < n; i++) Matrix2DMultVec(&u, &m0, &u); printf("Matrix2DMultVec : %s\n", ((fabs(u.x - x) + fabs(u.y - y)) < EPSILON) ? "Pass" : "Fail"); // generate 2 random numbers x = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; y = 2.0f * rand() / (float)(RAND_MAX) - 1.0f; n = (rand() % 16) + 15; Vector2DSet (&u, x, y); Matrix2DTranslate (&m0, x, y); for (i = 1; i < n; i++) Matrix2DMultVec(&u, &m0, &u); printf("Matrix2DMultVec : %s\n", ((fabs(u.x - x * n) + fabs(u.y - y * n)) < EPSILON) ? "Pass" : "Fail"); printf("\n------Testing New Collision Functions------\n\n"); //StaticPointToStaticRect Vector2DSet(&v1, 1.f, 1.f); //point Vector2DSet(&v2, 0.f, 0.f); //rect printf("StaticPointToStaticRect Collision: %s\n", (StaticPointToStaticRect(&v1, &v2, 2.f, 2.f) ? "Pass" : "Fail")); printf("StaticPointToStaticRect Non Collision: %s\n\n", (!StaticPointToStaticRect(&v1, &v2, 1.f, 1.f) ? "Pass" : "Fail")); //StaticCircleToStaticCircle Vector2DSet(&v1, 2.f, 0.f); printf("StaticCircleToStaticCircle Collision Touch: %s\n", (StaticCircleToStaticCircle(&v1, 1.f, &v2, 1.f) ? "Pass" : "Fail")); printf("StaticCircleToStaticCircle Collision: %s\n", (StaticCircleToStaticCircle(&v1, 2.f, &v2, 1.f) ? "Pass" : "Fail")); printf("StaticCircleToStaticCircle Non Collision: %s\n\n", (!StaticCircleToStaticCircle(&v1, 0.5f, &v2, 1.f) ? "Pass" : "Fail")); //StaticRectToStaticRect Vector2DSet(&v1, 2.f, 2.f); printf("StaticRectToStaticRect Non Collision: %s\n", (!StaticRectToStaticRect(&v1, 1.f, 1.f, &v2, 1.f, 1.f) ? "Pass" : "Fail")); printf("StaticRectToStaticRect Collision Touch: %s\n", (StaticRectToStaticRect(&v1, 2.f, 2.f, &v2, 2.f, 2.f) ? "Pass" : "Fail")); printf("StaticRectToStaticRect Collision Intersect: %s\n", (StaticRectToStaticRect(&v1, 3.f, 3.f, &v2, 3.f, 3.f) ? "Pass" : "Fail")); return 1; }
void Update2(void) { //unsigned long i; float winMaxX, winMaxY, winMinX, winMinY; double frameTime; // ========================================================================================== // 获取窗口四条边的坐标,当窗口发生移动或缩放,以下值会发生变化 // ========================================================================================== winMaxX = AEGfxGetWinMaxX(); winMaxY = AEGfxGetWinMaxY(); winMinX = AEGfxGetWinMinX(); winMinY = AEGfxGetWinMinY(); // ====================== // 帧时间:相当于zero中的dt // ====================== frameTime = AEFrameRateControllerGetFrameTime(); // ========================= // 游戏逻辑响应输入 // ========================= // 状态切换 if (KeyPressed[KeyR]) Next = GS_Restart; if (KeyPressed[KeyESC]) Next = GS_Quit; if (KeyPressed[Key1]) Next = GS_L1; if (KeyPressed[KeyMenu]) Next = GS_MENU; // 主角的移动 if (KeyPressed[KeyUp]) { obj1Y += 20.0f; } else if (KeyPressed[KeyDown]) { obj1Y -= 20.0f; } if (KeyPressed[KeyLeft]) { obj1X -= 20.0f; } else if (KeyPressed[KeyRight]) { obj1X += 20.0f; } //鼠标左键控制石头生成 if ((KeyPressed[KeyLeftBottom]) && (Burglar->flag& FLAG_ACTIVE))//&& (StoneCount>0)) { pStone = gameObjCreate(TYPE_STONE, 3.0f, 0, 0, 0.0f);; AE_ASSERT(pStone); // 实例化 // 初始化: 坐标位置 朝向和尺寸大小 //在主角位置产生,射向鼠标位置 pStone->posCurr.x = Burglar->posCurr.x; pStone->posCurr.y = Burglar->posCurr.y; //石头减一 StoneCount -= 1; } //随机产生水果,每隔3秒产生一个,一个界面最多产生10个水果 TimeTot++; if (TimeTot == 180 && Fruit_NUM<10) { Fruit_NUM++; int Xx, Yy; Xx = rand(); Yy = rand(); //控制水果在界面内产生 while (Xx > 800.0f) //控制水果在界面宽度内产生 { Xx = (int)rand(); } while (Yy > 600.0f)//控制水果在界面高度度内产生 { Yy = (int)rand(); } Xx = Xx - 400; Yy = Yy - 300; TimeTot = 0; GameObj* pFruit = gameObjCreate(TYPE_WATERMELON, 3.0f, 0, 0, 0.0f);; AE_ASSERT(pFruit); // 实例化 // 初始化: 坐标位置 朝向和尺寸大小 pFruit->posCurr.x = Xx; pFruit->posCurr.y = Yy; pFruit->scale = 5.0f; } else if (TimeTot == 200) TimeTot = 0; //遍历所有对象以决定操作 for (int i = 1; i < GAME_OBJ_NUM_MAX; i++) { GameObj* pObj = sGameObjList + i; //石头的发射 if (pObj->flag && pObj->pObject->type == TYPE_STONE) { //石头朝着鼠标位置运动 pStone->velCurr.x = (posX - Burglar->posCurr.x) / 10.0f; pStone->velCurr.y = (posY - Burglar->posCurr.y) / 10.0f; pObj->posCurr.x += pObj->velCurr.x; pObj->posCurr.y += pObj->velCurr.y; //碰撞到狗或者boss for (int j = 1; j < GAME_OBJ_NUM_MAX; j++) { GameObj* pObj0 = sGameObjList + j; if (pObj0->flag && (pObj0->pObject->type == TYPE_DOG || pObj0->pObject->type == TYPE_BOSS)) { if (StaticPointToStaticCircle(&pObj->posCurr, &pObj0->posCurr, 10.0)) { gameObjDestroy(pObj0); gameObjDestroy(pObj); } } } } //捡石头 if (pObj->flag&&pObj->pObject->type == TYPE_STONE_STATIC) { if (StaticRectToStaticRect(&Burglar->posCurr, 33, 30, &pObj->posCurr, 15, 15)) { gameObjDestroy(pObj); StoneCount += 1; } } //离陷阱距离近时 if (pObj->flag && pObj->pObject->type == TYPE_TRAP_IN) { if (Burglar->flag&FLAG_ACTIVE) { if (((pObj->posCurr.x - Burglar->posCurr.x)*(pObj->posCurr.x - Burglar->posCurr.x) + (pObj->posCurr.y - Burglar->posCurr.y) *(pObj->posCurr.y - Burglar->posCurr.y)) < 4000) { pTrap = gameObjCreate(TYPE_TRAP_OUT, 10.0f, 0, 0, 0.0f); pTrap->posCurr.x = pObj->posCurr.x; pTrap->posCurr.y = pObj->posCurr.y; pTrap->scale = 10.0; if (StaticRectToStaticRect(&Burglar->posCurr, 30, 30, &pObj->posCurr, 40, 40) && pObj->flag) { Burglar->scale -= 0.5; } if (Burglar->scale < 1.0f) { gameObjDestroy(Burglar);//碰撞了,减少scale,并销毁对象 } } } } //远离陷阱时 if (pObj->flag && pObj->pObject->type == TYPE_TRAP_OUT) { if (((pObj->posCurr.x - Burglar->posCurr.x)*(pObj->posCurr.x - Burglar->posCurr.x) + (pObj->posCurr.y - Burglar->posCurr.y) *(pObj->posCurr.y - Burglar->posCurr.y))>40000) gameObjDestroy(pObj); } //Boss 的运动跟碰撞 if (pObj->flag && pObj->pObject->type == TYPE_BOSS) { //发生碰撞,主角死亡 if (StaticRectToStaticRect(&Burglar->posCurr, 15.0f, 15.0f, &pObj->posCurr, 15.0f, 15.0f)) { gameObjDestroy(Burglar); } } //狗的边界控制 if (pObj->flag&&pObj->pObject->type == TYPE_DOG) { if (pObj->posCurr.x >= winMaxX || pObj->posCurr.x <= winMinX) { pObj->posCurr.x = -pObj->posCurr.x; } if (pObj->posCurr.y <= winMinY || pObj->posCurr.y >= winMaxY) { pObj->posCurr.y = -pObj->posCurr.y; } //是否与狗发生碰撞 if (StaticRectToStaticRect(&Burglar->posCurr, 30, 30, &pObj->posCurr, 30, 30) && pObj->flag) { Burglar->scale -= 0.5; } if (Burglar->scale < 1.0f) { gameObjDestroy(Burglar);//碰撞了,减少scale,并销毁对象 } } //捡西瓜 if (pObj->flag&&pObj->pObject->type == TYPE_WATERMELON) { if (StaticPointToStaticCircle(&Burglar->posCurr, &pObj->posCurr, 10.0)) { gameObjDestroy(pObj); Fruit_NUM -= 1; sScore += 10; } } if (pObj->flag && pObj->pObject->type == TYPE_BURGLARBLOOD) { //更新血量位置 pObj->posCurr.x = Burglar->posCurr.x; pObj->posCurr.y = Burglar->posCurr.y + 35.0f; if (!Burglar->flag&FLAG_ACTIVE) { gameObjDestroy(pObj); //销毁主角的同时,销毁主角的血量 } } }//for //狗运动 for (int a = 0; a < 5; a++) { srand(time()); int PosDogX = (pDog[a]->posCurr.x + 400) / 40; int PosDogY = (pDog[a]->posCurr.y + 300) / 15; if (mapinfo[PosDogX - 1][PosDogY]) { pDog[a]->posCurr.x += 1; } else if (mapinfo[PosDogX + 1][PosDogY]) { pDog[a]->posCurr.x -= 1; } else if (mapinfo[PosDogX][PosDogY + 1]) { pDog[a]->posCurr.y -= 1; } else if (mapinfo[PosDogX][PosDogY - 1]) { pDog[a]->posCurr.y += 1; } //else //{ // pDog[a]->posCurr.x += 2; //} } //狗的运动 TimeTot1++; int x; if (TimeTot1 < 300) { pDog[0]->posCurr.x += 1; pDog[1]->posCurr.x -= 1; pDog[2]->posCurr.y += 1; pDog[3]->posCurr.y -= 1; pDog[4]->posCurr.x += 1; } if (TimeTot1 >= 300 && TimeTot1 < 600) { pDog[0]->posCurr.x -= 1; pDog[1]->posCurr.x += 1; pDog[2]->posCurr.y -= 1; pDog[3]->posCurr.y += 1; pDog[4]->posCurr.y -= 1; } if (TimeTot1 >= 600 && TimeTot1 < 900) { pDog[0]->posCurr.y += 1; pDog[1]->posCurr.y -= 1; pDog[2]->posCurr.x += 1; pDog[3]->posCurr.x -= 1; pDog[4]->posCurr.y += 1; } if (TimeTot1 >= 900 && TimeTot1 < 1200) { pDog[0]->posCurr.y -= 1; pDog[1]->posCurr.y += 1; pDog[2]->posCurr.x -= 1; pDog[3]->posCurr.x += 1; pDog[4]->posCurr.y -= 1; } if (TimeTot1 == 1200) { TimeTot1 = 0; } //按空格键 if (KeyPressed[KeySpace]) { } // 输入重置 Input_Initialize(); // 签到 fprintf(fp, "Level2:Update\n"); }
int StaticCircleToStaticCircle(Vector2D *pCenter0, float Radius0, Vector2D *pCenter1, float Radius1) { return StaticPointToStaticCircle(pCenter0, pCenter1, Radius0 + Radius0); }