image rotation in touchesMoved scrubbing back and forth using CGAffineTransformMakeRotation is dropping the fps by half
in a 3D game, after optimization i have hit 60fps on an iPad2, the main runloop is in a secondary thread, with the interface builder built UI on the main thread, (this question is about the UI of the main thread)
i have two controllers, a throttle up, and a stick for roll in the UI that uses touch interaction, you can see the stick in this image below.
it has a rotation movement of 180 degrees as you can imagine from this image
if i run the game, and then scrub back and forth with my thumb on this stick, (rolling wildly from 0 degrees to -180 degrees) the fps drops to 33fps instead of 60fps..
simply commenting out this line below from the code listing below, brings the fps back to 60fps, (i scrub with my thumb and the game does it's rolling, but the image of this stick of course does not move) so it is possible to play the game at full fps without updating the image of this stick, (showing that it is this routine alone) this updating and transforming of the image with this method is greatly effecting my fps. see this code below, do you think there is a way around this performance hit? (otherwise i'm going to have to have some generic round area with just a circle representing the touch area to give an idea of roll that you see in some games like i think infinity blade.. but i would much rather have this interactive image showing the true purpose. do you see anything that i am missing? need to change? would be better?
joypadCap.transform = CGAffineTransformMakeRotation(touchAngle); //rotation in radians
here is the relevant code from the viewController that is set up, the "joypad" is the image you see above, the throttle is a different image and it is effecting the fps but not to the extent of this single call above because the throttle is just moving the image to the correct place, and not using this CGAffineTransformMakeRotation. but that operation does drop the fps by about 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))
{
开发者_如何学Go 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;
}
}
}
精彩评论