在 3D 游戏中,经过优化后,我在 iPad2 上达到了 60fps,主运行循环在辅助线程中,界面构建器在主线程上构建 UI,(这个问题是关于主线程的 UI)
我在使用触摸交互的 UI 中有两个控制器、一个油门加速器和一个用于滚动的摇杆,您可以在下图中看到摇杆。
正如您可以从这张图片中想象的那样,它具有 180 度的旋转运动
如果我运行游戏,然后用我的拇指在这根棍子上来回擦洗,(从 0 度到 -180 度疯狂滚动)fps 下降到 33fps 而不是 60fps ..
只需从下面的代码清单中注释掉下面的这一行,就可以将 fps 恢复到 60fps,(我用拇指擦洗,游戏确实在滚动,但是这根棍子的图像当然不会移动)所以可以玩在不更新此棒的图像的情况下以全 fps 进行游戏,(表明仅此例程)使用此方法对图像的更新和转换极大地影响了我的 fps。看看下面的这段代码,你认为有办法解决这个性能问题吗?(否则我将不得不有一些通用的圆形区域,只有一个圆圈代表触摸区域,以给出你在一些游戏中看到的滚动的概念,比如我认为无限刀片......但我更希望有这个交互式图像显示真正的目的。你看到我遗漏了什么吗?需要改变吗?会更好吗?
joypadCap.transform = CGAffineTransformMakeRotation(touchAngle); //rotation in radians
这是设置的 viewController 中的相关代码,“joypad”是您在上面看到的图像,油门是不同的图像,它会影响 fps,但不会影响到上面的单个调用,因为油门是只是将图像移动到正确的位置,而不是使用这个 CGAffineTransformMakeRotation。但该操作确实将 fps 降低了约 8fps。
@interface stickController : UIViewController
{
IBOutlet UIImageView *throttleStickCap;
IBOutlet UIImageView *joypadCap;
etc......
@implementation stickController
@synthesize frontViewButton, backViewButton, leftViewButton, rightViewButton, upViewButton, gunSight;
//------------------------------------------------------------------------------------
- (void)viewDidLoad
{
NSLog(@"viewDidLoad");
[super viewDidLoad];
throttleStick = throttleStickCap.frame;
throttleStickCenterx = throttleStickCap.center.x;
throttleStickCentery = throttleStickCap.center.y;
throttleStickMax = 72.0f;
throttleStickMin = -7.0f;
joypad = joypadCap.frame;
joypadCenterx = joypadCap.center.x;
joypadCentery = joypadCap.center.y;
joypadMax = 50.0f;
joypadMin = -50.0f;
theStickController = self;
}
//------------------------------------------------------------------------------------
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
NSSet *allTouches = [event allTouches];
for (UITouch *touch in allTouches)
{
CGPoint touchLocation = [touch locationInView:self.view];
if (CGRectContainsPoint(throttleStick, touchLocation))
{
throttleStickTouchHash = [touch hash];
}
if (CGRectContainsPoint(joypad, touchLocation))
{
joypadTouchHash = [touch hash];
CGPoint touchLocation = [touch locationInView:self.view];
float dx = touchLocation.x - (float)joypadCenterx;
float dy = touchLocation.y - (float)joypadCentery;
distance = sqrtf(powf(dx, 2.0f) + powf(dy, 2.0f));
if (distance > joypadMax)
{
enoughDistance = shootDistance;
createBulletSet();
}
}
}
}
//------------------------------------------------------------------------------------
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
NSSet *allTouches = [event allTouches];
for (UITouch *touch in allTouches)
{
if ([touch hash] == throttleStickTouchHash)
{
CGPoint touchLocation = [touch locationInView:self.view];
distance = throttleStickCentery - touchLocation.y;
if (distance > throttleStickMax)
{
throttleStickCap.center = CGPointMake(throttleStickCenterx, throttleStickCentery - throttleStickMax);
throttle = throttleStickMax;
}
else if (distance < throttleStickMin)
{
throttleStickCap.center = CGPointMake(throttleStickCenterx, throttleStickCentery - throttleStickMin);
throttle = throttleStickMin;
}
else
{
throttleStickCap.center = CGPointMake(throttleStickCap.center.x, touchLocation.y);
throttle = distance;
}
throttle *= .10;
throttleStick = throttleStickCap.frame;
}
if ([touch hash] == joypadTouchHash)
{
CGPoint touchLocation = [touch locationInView:self.view];
float dx = touchLocation.x - (float)joypadCenterx;
float dy = touchLocation.y - (float)joypadCentery;
distance = sqrtf(powf(dx, 2.0f) + powf(dy, 2.0f));
if (distance > joypadMax) createBulletSet();
else enoughDistance = shootDistance;
if (dx > joypadMax) roll = joypadMax;
else if (dx < joypadMin) roll = joypadMin;
else roll = dx;
joypad = joypadCap.frame;
touchAngle = atan2(dy, dx) + 1.570796;
if ((dx < 0.0f) && (dy > 0.0f)) touchAngle = -1.570796;
else if ((dx > 0.0f) && (dy > 0.0f)) touchAngle = 1.570796;
// joypadCap.transform = CGAffineTransformMakeRotation(touchAngle); //rotation in radians
}
}
}
//------------------------------------------------------------------------------------
- (void)forceTouchesEnd
{
throttleStickMoving = NO;
throttleStickTouchHash = 0;
throttle = 0.0f;
throttleStickCap.center = CGPointMake(throttleStickCenterx, throttleStickCentery);
throttleStick = throttleStickCap.frame;
joypadMoving = NO;
joypadTouchHash = 0;
roll = 0.0f;
joypadCap.transform = CGAffineTransformMakeRotation(0.0f); //rotation in radians
joypad = joypadCap.frame;
}
//------------------------------------------------------------------------------------
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
for (UITouch *touch in touches)
{
if ([touch hash] == throttleStickTouchHash)
{
throttleStickTouchHash = 0;
}
if ([touch hash] == joypadTouchHash)
{
joypadTouchHash = 0;
roll = 0.0f;
joypad = joypadCap.frame;
return;
}
}
}