×
Namespaces

Variants
Actions

碰撞检测

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

文章
hoolee 在 10 Jul 2008 创建
最后由 hamishwillee 在 15 Dec 2011 编辑

CS000865


  • 开发伙伴平台:

S60 3rd Edition, MR

S60 3rd Edition, FP1

S60 3rd Edition, FP2 Beta


  • 详细描述

下列代码演示了如何完成基本的碰撞检测逻辑。例如在一个简单的游戏里,5个方块在屏幕上移动。对墙体以及各自之间都会产生碰撞的检测。移动使用CPeriodic来处理。


在这个代码片段中,我们在一个名为CAppView的空间中完成,它从CCoeControl派生


头文件

const TInt KBlocks = 5;
const TInt KBlockWidth = 10;
const TInt KBlockHeight = 10;
const TInt KBlockMaxSpeed = 3;
 
const TInt KDelay = 10000;
const TInt KInterval = 10000;/**
* Static callback function for timer, called periodically.
* @param aPtr pointer to this class
* @return one of S60 error codes
*/
static TInt TimerCallBack(TAny* aPtr);
 
/**
* Timer function called from TimerCallBack.
* Takes care of moving the blocks.
* @return one of S60 error codes
*/
TInt DoTimer();
 
// Data
 
TPoint iPosition[KBlocks]; // positions for blocks
TPoint iSpeed[KBlocks]; // speeds for blocks
TRgb iColor[KBlocks]; // colors for blocks
 
CPeriodic* iTimer;

源文件

#include <e32math.h>void CAppView::ConstructL(const TRect& aRect)
{
// Create a window for this application view
CreateWindowL();
 
// Create a periodic timer to move the blocks
iTimer = CPeriodic::NewL(EPriorityNormal);
 
// Initialize the blocks
TInt i;
for (i = 0; i < KBlocks; i++)
{
iSpeed[i] = TPoint(
Math::Random() % (2 * KBlockMaxSpeed + 1) - KBlockMaxSpeed,
Math::Random() % (2 * KBlockMaxSpeed + 1) - KBlockMaxSpeed);
iPosition[i] = TPoint(
Math::Random() % aRect.Width(),
Math::Random() % aRect.Height());
iColor[i] = TRgb(
Math::Random() % 256,
Math::Random() % 256,
Math::Random() % 256);
}
 
// Start the timer
iTimer->Start(KDelay, KInterval, TCallBack(TimerCallBack, this));
 
// Set the window size
SetRect(aRect);
 
// Activate the window, which makes it ready to be drawn
ActivateL();
}TInt CAppView::TimerCallBack(TAny* aPtr)
{
return ((CAppView*)aPtr)->DoTimer();
}TInt CAppView::DoTimer()
{
// Get gc to draw with
CWindowGc& gc = SystemGc();
 
gc.Activate(Window());
gc.Clear();
gc.SetPenStyle(CGraphicsContext::ENullPen);
gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
 
// Handle each block in turn
for (TInt i = 0; i < KBlocks; i++)
{
gc.SetBrushColor(iColor[i]);
TPoint& position = iPosition[i];
TPoint& speed = iSpeed[i];
 
// Move blocks
position = position + speed;
 
TRect rect = Rect();
 
// Detect block colliding against walls
if ((position.iX + KBlockWidth >= rect.iBr.iX) ||
(position.iX <= rect.iTl.iX))
{
speed.iX = -speed.iX;
position = position + speed;
}
 
if ((position.iY + KBlockHeight >= rect.iBr.iY) ||
(position.iY <= rect.iTl.iY))
{
speed.iY = -speed.iY;
position = position + speed;
}
 
// Detect blocks colliding against each other
TRect boxRect(position, TSize(KBlockWidth, KBlockHeight));
for (TInt j = 0; j < KBlocks; j++)
{
TRect boxRect2(iPosition[j], TSize(KBlockWidth, KBlockHeight));
if ((i != j) && (boxRect.Intersects(boxRect2)))
{
speed.iY = -speed.iY;
speed.iX = -speed.iX;
}
}
 
// Draw current block
gc.DrawRect(boxRect);
}
gc.Deactivate();
 
return KErrNone;
}
This page was last modified on 15 December 2011, at 08:50.
44 page views in the last 30 days.
×