** STILL NOT WORKING **
我使用下面的公式来移动球,其中 accelX
和 accelY
是来自加速度计的值,它工作正常。
但是这段代码中的问题是mRadius
(我将其值固定为50),我需要根据加速度计值更改mRadius
,并且当我需要弹跳效果时它触及轨道。目前,我正在假设棋盘上只有一个球来开发代码。
float degrees = -atan2(accelX, accelY);
int x = cCentrePoint.x + mRadius * cos(degrees);
int y = cCentrePoint.y + mRadius * sin(degrees);
这是我想要开发的游戏的快照:
Balls Game http://iphront.com/wp-content/uploads/2009/12/bdece528ea334033.jpg.jpg
更新:我正在发送更新的代码...
mRadius = 5;
mRange = NSMakeRange(0,60);
-(void) updateBall: (UIAccelerationValue) accelX
withY:(UIAccelerationValue)accelY
{
float degrees = -atan2(accelX, accelY);
int x = cCentrePoint.x + mRadius * cos(degrees);
int y = cCentrePoint.y + mRadius * sin(degrees);
//self.targetRect is rect of ball Object
self.targetRect = CGRectMake(newX, newY, 8, 9);
self.currentRect = self.targetRect;
static NSDate *lastDrawTime;
if(lastDrawTime!=nil)
{
NSTimeInterval secondsSinceLastDraw =
-([lastDrawTime timeIntervalSinceNow]);
ballXVelocity = ballXVelocity + (accelX * secondsSinceLastDraw)
* [self isTouchedTrack:mRadius andRange:mRange];
ballYVelocity = ballYVelocity + -(accelY * secondsSinceLastDraw)
* [self isTouchedTrack:mRadius andRange:mRange];
distXTravelled = distXTravelled + secondsSinceLastDraw
* ballXVelocity * 50;
distYTravelled = distYTravelled + secondsSinceLastDraw
* ballYVelocity * 50;
//Updating the ball rect
CGRect temp = self.targetRect;
temp.origin.x += distXTravelled;
temp.origin.y += distYTravelled;
//calculating new radius after updating ball position
int radius = (temp.origin.x - cCentrePoint.x) /
cos(degreesToRadians(degrees));
if( !NSLocationInRange(abs(radius),mRange))
{
//Colided with the tracks...Need a better logic here
ballXVelocity = -ballXVelocity;
}
else
{
// Need a better logic here
self.targetRect = temp;
}
}
[lastDrawTime release];
lastDrawTime = [ [NSDate alloc] init];
}
在上面的代码中,我已将 mRadius 和 mRange(指示轨迹)初始化为某个常量以进行测试,但我没有按照我的预期获得球相对于加速度计的移动(与轨迹碰撞时的弹跳效果)。帮助我识别哪里出错了,或者发送一些执行类似工作的代码片段或链接。
我正在寻找比我的代码更好的逻辑,如果您发现与我分享。
最佳答案
如果我正确理解你的代码,那么球的位置直接由 iPhone 的方向(倾斜)控制。因此,向右倾斜 iPhone 会将球放置在轨道的右侧(3 点钟方向)。我相信您可能希望控制球的加速度(或者至少是其速度)。然后,您将加速度与速度以及放置速度相结合,同时考虑约束(轨道墙)。
按照现在的设置方式,我不知道你如何控制多个球(根据你发布的图片)。
然后,对于弹跳效果:如果您的意思是通过轨道壁弹跳,那么这将是 mRadius 的一个小调制。如果您指的是其他球的弹跳,那么您需要调制两个球的角位置(通过角速度)来反射(reflect) react 。
编辑:为了将加速度积分到速度,然后积分到位置,为了这个游戏的目的,您可以使用一阶矩形积分。而且,使加速度与倾斜角度成正比会更现实。给定 iPhone 本身的加速度值,您可以在球加速度和设备读数之间分配 1:1 的关系。所以,你想要这样的东西:
BallAccX = AccelX * Am_I_NOT_touching_a_wall_in_X_direction() * Ka
BallVelX = BallVelX + BallAccX * dT * Kv
BallPosX = BallPosX + BallVelX * dT * Kp
注意:上述速度和位置公式是一阶近似,但对于本游戏的目的来说应该足够了。
Ka、Kv、Kp 是一些比例系数。选择它们可以使感测到的加速度与球运动之间的关系随心所欲。 dT 是球状态更新之间的时间差。如果球可以自由水平移动(沿倾斜方向),则函数 Am_I_NOT_touching_a_wall_in_X_direction() 返回 1,否则返回 0。
Y 方向移动的计算是对称的。
关于iphone - 当球撞击轨道时如何获得碰撞效果或弹力,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2505616/