📄 e_collision.c
字号:
/******************************************************************************
*
* The information contained herein is the exclusive property of
* Sunplus Technology Co. And shall not be distributed, reproduced,
* or disclosed in whole in part without prior written permission.
*
* (C) COPYRIGHT 2005 SUNPLUS TECHNOLOGY CO.
* ALL RIGHTS RESERVED
*
* The entire notice above must be reproduced on all authorized copies.
*
*****************************************************************************/
/******************************************************************************
* Filename: E_Collision.c
* Author: Robin.xjliu (eMail: xjliu@sunplus.com)
* Tel: 00885-028-87848688-5884
* Date: 2005-11-28
* Description: basic collision function
* Reference:
* Version history:
*-----------------------------------------------------------------------------
* Version YYYY-MM-DD-INDEX Modified By Description
* 1.0.0 2005-11-28 xjliu Create
*
*****************************************************************************/
#include "Include/E_Collision.h"
#ifdef ARG_CHK_EN
extern MOTION MOTION_TABLE[];
#endif
//static inline
bool __BBoxHit(S16 ax, S16 ay, S16 aX, S16 aY,S16 bx, S16 by, S16 bX, S16 bY)
{
/*
* (ax,ay) (bx,by)
* +-------------+ +-----------------+
* | | | |
* | | | |
* | | | |
* | | | |
* +-------------+ | |
* (aX,aY) +-----------------+
* (bX,bY)
*/
return (!((ax > bX) || (aX < bx) || (ay > bY) || (aY < by)));
}
/**
* _BBoxHit - check bounding box hit.
* @a: bounding box a to be checked.
* @b: bounding box b to be checked.
* @bxoa: bounding box b's x-offset to a.
* @byoa: bounding box b's y-offset to a.
* @RETURN: true if hit,otherwise return false.
*/
//static inline
bool _BBoxHit(const FRAME_BLOCK *a, const FRAME_BLOCK *b, S16 bxoa, S16 byoa)
{
/*
* (xa,ya) (xb,yb)
* +-------------+ +-----------------+
* | | | |
* | | | |
* | | | |
* | | | |
* +-------------+ | |
* (Xa,Ya) +-----------------+
* (Xb,Yb)
*/
return __BBoxHit(a->Left,a->Top,a->Right,a->Bottom,
(S16)(b->Left+bxoa),(S16)(b->Top+byoa),(S16)(b->Right+bxoa),(S16)(b->Bottom+byoa));
}
/**
* _BBoxesHit - check two group bounding box hit.
* @xa, @ya: position of the bounding box group a.
* @a: the bounding box group a.
* @na: the bounding box number of group a.
* @xb, @yb: position of the bounding box group b.
* @b: the bounding box group b.
* @nb: the bounding box number of group b.
* @RETURN: false if none of the bounding box from the two group is hit.
* true if any pare of the bounding box from the two group is hit.
*/
//static inline
bool _BBoxesHit(S16 xa, S16 ya, const FRAME_BLOCK *a, U16 na,
S16 xb, S16 yb, const FRAME_BLOCK *b, U16 nb)
{
S16 offx,offy;
const FRAME_BLOCK *ea, *eb; /* End pointer */
ea = a + na;
eb = b + nb;
offx = xb - xa;
offy = yb - ya;
if (na <= nb)
{
for (; a < ea; a++)
{
for (; b < eb; b++)
{
if (_BBoxHit(a, b, offx, offy))
{
return true;
}
}
}
}
else
{
for (; b < eb; b++)
{
for (; a < ea; a++)
{
if (_BBoxHit(a, b, offx, offy))
{
return true;
}
}
}
}
return false;
}
/**
* E_DetectCollision - check whether collision happened between two sprite
* @spa: pointer to the one sprite to be checked
* @spb: pointer to the other sprite to be checked
* @RETURN: true - collision detected; false - no collision
*/
//bool E_DetectCollision(const SPRITE * spa, const SPRITE * spb)
//{
// const FRAME *fa, *fb;
// S16 ax,ay; /* Sprite position of spa */
// S16 bx,by; /* Sprite position of spb */
//
// /* Image boundary box for pre-detecting */
// S16 iaX, iaY, ibX, ibY;
//
// /* get sprite position */
// ax = spa->stPos.x;
// ay = spa->stPos.y;
// bx = spb->stPos.x;
// by = spb->stPos.y;
//
// /* get current frame */
// fa = spa->pFrame;
// fb = spb->pFrame;
//
// iaX = ax + fa->stSize.width;
// iaY = ay + fa->stSize.height;
// ibX = bx + fb->stSize.width;
// ibY = by + fb->stSize.height;
//
// if (__BBoxHit(ax, ay, iaX, iaY, bx, by, ibX, ibY))
// {
// return _BBoxesHit(ax,ay,fa->pFrameBlockTbl,fa->nBlockNum, bx,by,fb->pFrameBlockTbl, fb->nBlockNum);
// }
// else
// {
// return false;
// }
//}
/**
* E_DetectBlock2Sp - check whether collision happened between two sprite
* @spa: pointer to the one sprite to be checked
* @spb: pointer to the other sprite to be checked
* @pblock: pointer to only one block of spb
* @RETURN: true - collision detected; false - no collision
*/
bool E_DetectBlock2Sp(SPRITE * spa, SPRITE * spb, S16 iLeft, S16 iTop, S16 iRight, S16 iBottom)
{
FRAME_BLOCK pBlock;
S16 ax,ay; /* Sprite position of spa */
S16 bx,by; /* Sprite position of spb */
pBlock.Left = iLeft;
pBlock.Top = iTop;
pBlock.Right = iRight;
pBlock.Bottom = iBottom;
/* get sprite position */
ax = spa->stPos.x;
ay = spa->stPos.y;
bx = spb->stPos.x;
by = spb->stPos.y;
if (__BBoxHit(ax, ay,
ax + spa->pFrame->stSize.width, ay + spa->pFrame->stSize.height,
bx, by,
bx + spb->pFrame->stSize.width, by + spb->pFrame->stSize.height))
{
return _BBoxesHit(ax,ay,spa->pFrame->pFrameBlockTbl,spa->pFrame->nBlockNum, bx,by, &pBlock, 1);
}
else
{
return false;
}
}
/**
* E_DetectCollision - check whether collision happened between two motion
* @pMotion1: pointer to the one Motion to be checked
* @pMOtion2: pointer to the other Motion to be checked
* @RETURN: true - collision detected; false - no collision
*/
/*bool E_DetectCollision(MOTION *pMotion1, MOTION *pMotion2)
{
const FRAME_BLOCK *pBlock1,*pBlock2;
const FRAME *pFrame1,*pFrame2;
SPRITE *pSprite1,*pSprite2;
S16 nLeft, nTop, nRight, nBottom;
S16 xOffset, yOffset;
#ifdef ARG_CHK_EN
if (pMotion1 < &MOTION_TABLE[0]
|| pMotion1 >= &MOTION_TABLE[MOTION_NUM_MAX]
|| pMotion2 < &MOTION_TABLE[0]
|| pMotion2 >= &MOTION_TABLE[MOTION_NUM_MAX])
{
return false;
}
#endif
pSprite1 = pMotion1->pSprite;
pSprite2 = pMotion2->pSprite;
pFrame1 = pSprite1->pFrame;
pFrame2 = pSprite2->pFrame;
//relative coordinate
xOffset = pSprite1->stPos.x - pSprite2->stPos.x;
yOffset = pSprite1->stPos.y - pSprite2->stPos.y;
for (pBlock1 = (pFrame1->pFrameBlockTbl); pBlock1 < ((pFrame1->pFrameBlockTbl) + pFrame1->nBlockNum); pBlock1++)
{
nBottom = yOffset + pBlock1->Bottom;
nTop = yOffset + pBlock1->Top;
nRight = xOffset + pBlock1->Right;
nLeft = xOffset + pBlock1->Left;
for (pBlock2 = (pFrame2->pFrameBlockTbl); pBlock2 < ((pFrame2->pFrameBlockTbl) + pFrame2->nBlockNum); pBlock2++)
{
if (CHECK_OVERLAP(nLeft,nTop,nRight,nBottom,
pBlock2->Left, pBlock2->Top,
pBlock2->Right, pBlock2->Bottom))
{
return true;
}
}
}
return false;
}
*/
/*
bool E_PreDetect(MOTION *pMotion1, MOTION *pMotion2, U8 nRange)
{
S16 nCenterX1, nCenterY1;
S16 nCenterX2, nCenterY2;
#ifdef ARG_CHK_EN
if (pMotion1 < &MOTION_TABLE[0]
|| pMotion1 >= &MOTION_TABLE[MOTION_NUM_MAX]
|| pMotion2 < &MOTION_TABLE[0]
|| pMotion2 >= &MOTION_TABLE[MOTION_NUM_MAX])
{
return false;
}
#endif
//center1 coordinate
nCenterX1 = pMotion1->pSprite->stPos.x + (pMotion1->pSprite->pFrame->stSize.width / 2);
nCenterY1 = pMotion1->pSprite->stPos.y + (pMotion1->pSprite->pFrame->stSize.height / 2);
//center2 coordinate
nCenterX2 = pMotion2->pSprite->stPos.x + (pMotion2->pSprite->pFrame->stSize.width / 2);
nCenterY2 = pMotion2->pSprite->stPos.y + (pMotion2->pSprite->pFrame->stSize.height / 2);
if ( abs(nCenterX1 - nCenterX2) < nRange && abs(nCenterY1 - nCenterY2) < nRange )
{
return true;
}
return false;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -