вращение изображения в touchesMoved при повторной очистке с помощью CGAffineTransformMakeRotation вдвое снижает частоту кадров в секунду

#ios #user-interface #3d #cgaffinetransform #frame-rate

#iOS #пользовательский интерфейс #3D #cgaffinetransform #частота кадров

Вопрос:

в 3D-игре, после оптимизации я достиг 60 кадров в секунду на iPad2, основной цикл выполнения находится во вторичном потоке, а пользовательский интерфейс, созданный разработчиком интерфейса, встроен в основной поток (этот вопрос касается пользовательского интерфейса основного потока)

у меня есть два контроллера, регулятор скорости и стик для поворота в пользовательском интерфейсе, который использует сенсорное взаимодействие, вы можете увидеть стик на этом изображении ниже.

как вы можете себе представить по этому изображению, вращение составляет 180 градусов

введите описание изображения здесь

если я запускаю игру, а затем провожу большим пальцем по этой палочке взад-вперед (резко поворачиваясь от 0 градусов до -180 градусов), частота кадров в секунду падает до 33 кадров в секунду вместо 60 кадров в секунду..

простое комментирование этой строки из приведенного ниже списка кода возвращает частоту кадров в секунду обратно к 60 кадрам в секунду (я протираю большим пальцем, и игра запускается, но изображение этого джойстика, конечно, не перемещается), так что можно играть в игру с полной частотой кадров в секунду без обновления изображения этого джойстика (показывая, что это только эта процедура) это обновление и преобразование изображения с помощью этого метода значительно влияет на мой fps. смотрите этот код ниже, как вы думаете, есть ли способ обойти это снижение производительности? (в противном случае мне придется создать некоторую общую круглую область с одним кругом, представляющим область касания, чтобы дать представление о броске, который вы видите в некоторых играх, таких как, я думаю, infinity blade .. но я бы предпочел, чтобы это интерактивное изображение показывало истинное назначение. вы видите что-нибудь, чего мне не хватает? нужно изменить? было бы лучше?

   joypadCap.transform = CGAffineTransformMakeRotation(touchAngle); //rotation in radians
  

вот соответствующий код из настроенного ViewController, «джойстик» — это изображение, которое вы видите выше, дроссельная заслонка — это другое изображение, и оно влияет на частоту кадров, но не в той степени, в какой этот единственный вызов выше, потому что дроссельная заслонка просто перемещает изображение в нужное место, а не использует эту CGAffineTransformMakeRotation. но эта операция действительно снижает частоту кадров в секунду примерно на 8 кадров в секунду.

 @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) amp;amp; (dy > 0.0f)) touchAngle = -1.570796;
            else if ((dx > 0.0f) amp;amp; (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;
        }
    }
}