Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как двигать и вращать UIImage одновременно, двигать и вращать UIImage одновременно 
:(
    Опции темы
SlavaMinsk
  Дата 2.4.2014, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 29.3.2014

Репутация: нет
Всего: нет



Помогите разобраться.


Есть персонаж. После нажатия на StartGame координатам объекта присваиваются начальные значения (X = Object.center.x;  Y = Object.center.y) и запускается таймер, который каждые 0.05 сек. выполняет метод Object.Moving. 

В нём вычисляются координаты объекта X и Y;

И таким образом задаётся движение персонажа:   Object.center = CGPointMake ((int)X , (int)Y);

Потом обращение к методу [self Object.Rotate];


В Object.Rotate:

Object.center = CGPointMake (Object.center.x, Object.center.y);

Object.transform = CGAffineTransformMakeRotation(angle);        // угол снимается со слайдера на экране


Если закомментировать Object.Rotate - движение персонажа происходит отлично. А с ним вращение (через слайдер на экране) происходит не относительно текущей точки центра объекта, а относительно начальной точки. То есть Объект уже в другом месте, но если дернуть слайдер - он появляетсяна стартовой позиции и вращается. Отпустишь слайдер - появляется там, где должен быть.

Как сделать чтобы вращение происходило относительно текущего центра объекта (UIImage)?


Заранее спасибо, жду ваших ответов.






Это сообщение отредактировал(а) SlavaMinsk - 2.4.2014, 17:16
PM MAIL   Вверх
Bitter
Дата 2.4.2014, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

Репутация: 10
Всего: 27



Object.center = CGPointMake (Object.center.x, Object.center.y);
это вообще гениально )

Это сообщение отредактировал(а) Bitter - 2.4.2014, 13:57
PM MAIL ICQ Skype   Вверх
SlavaMinsk
  Дата 2.4.2014, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 29.3.2014

Репутация: нет
Всего: нет



Цитата(Bitter @ 2.4.2014,  13:57)
Object.center = CGPointMake (Object.center.x, Object.center.y);
это вообще гениально )

Спасибо, я знаю)

Так подсказать можете как это сделать?
PM MAIL   Вверх
Bitter
Дата 2.4.2014, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

Репутация: 10
Всего: 27



Если б мог, подсказал бы, а так кто его знает, что у вас там написано...
Ну попробуйте поменять местами вызовы Moving и Rotate
PM MAIL ICQ Skype   Вверх
SlavaMinsk
  Дата 2.4.2014, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 29.3.2014

Репутация: нет
Всего: нет



Вот код для наглядности, подскажите где я ошибся.

.h

@interface Game : UIViewController{
    
    IBOutlet UIImageView *Tank;
    IBOutlet UIButton *StartGame;
    IBOutlet UISlider *Rotation;
    IBOutlet UIButton *Accelerate;
    
    NSTimer *TankMovement;
    
    
}

-(IBAction)StartGame:(id)sender;
-(IBAction)Accelerate:(id)sender;
-(IBAction)OffAccelerate:(id)sender;
-(void)TankMoving;
-(void)TankRotate;


.m

@implementation Game

-(IBAction)StartGame:(id)sender{
    
    StartGame.hidden = YES;
    AccPressed = FALSE;
    dTime = 0.5;
    X = Tank.center.x;
    Y = Tank.center.y;
    SpeedX = 0;
    SpeedY = 0;
    HorsePower = 3;
    
    TankMovement = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(TankRotate) userInfo:nil repeats:YES];
    
}

-(IBAction)Accelerate:(id)sender{
    
    AccPressed = TRUE;
  
}

-(IBAction)OffAccelerate:(id)sender{
    
    AccPressed = FALSE;

}

-(void)TankRotate{
    
    Tank.transform = CGAffineTransformMakeRotation(angle);
    
    [self TankMoving];

}

-(void)TankMoving{

    SpeedY = SpeedY + dTime;
    
    angle = Rotation.value*0.03925;
    
    if (AccPressed){
        
        // Код расчета скорости при нажатой кнопке газа
        
    }
    
        X = X + dTime * SpeedX;
        Y = Y + dTime * SpeedY;
    
    Tank.center = CGPointMake((int)X, (int)Y);
    
}

Проблема: при нажатии на слайдер объект исчезает, появляется в начальной точке и вращается. Когда слайдер отпускаю - он (повернутый как надо) появляется там, куда до этого приехал.

То есть при нажатии на слайдер координаты центра UIImage скидываются на изначальные. Почему?


Это сообщение отредактировал(а) SlavaMinsk - 2.4.2014, 22:38
PM MAIL   Вверх
likalilika
Дата 2.4.2014, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 1.4.2014
Где: Кавказ

Репутация: 1
Всего: 1



В сценах крутить текстурой большого ума не нужно:) Чет не поняла для чего так много лишнего написано?
PM MAIL WWW ICQ Skype   Вверх
SlavaMinsk
Дата 2.4.2014, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 29.3.2014

Репутация: нет
Всего: нет



Цитата(likalilika @ 2.4.2014,  21:33)
В сценах крутить текстурой большого ума не нужно:) Чет не поняла для чего так много лишнего написано?

Информативнее пожалуйста. Что лишнее. Как вращать и двигать UIImage одновременно? Напишите как надо если знаете.

PM MAIL   Вверх
Bitter
Дата 2.4.2014, 23:05 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

Репутация: 10
Всего: 27



На самом деле вопрос не такой уж и простой, вы пытаетесь работать с аффинными преобразованиями, которые во-первых требуют понимания принципов этих преобразований, а во-вторых они довольно капризны. Аффинные преобразования оперируют матрицами. То есть для описания объекта в пространстве используется матрица, в которую заносятся данные о повороте по осям, масштабе и перемещении. Перемножая матрицы друг на друга, получаете комбинации преобразований поворот-перенос-масштаб.
В вашем случае свойство transform и есть та матрица. Комбинируйте матрицы поворота и переноса, чтобы добиться того чего хотите. Как их комбинировать легко найдете в инете.

Вот кстати тут похожая тема и ответ помечен решенным, так что может вам поможет
http://stackoverflow.com/questions/1983751...iimage-and-move

Это сообщение отредактировал(а) Bitter - 2.4.2014, 23:17
PM MAIL ICQ Skype   Вверх
SlavaMinsk
Дата 3.4.2014, 00:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 29.3.2014

Репутация: нет
Всего: нет



Цитата(Bitter @ 2.4.2014,  23:05)
В вашем случае свойство transform и есть та матрица. Комбинируйте матрицы поворота и переноса, чтобы добиться того чего хотите. Как их комбинировать легко найдете в инете.

Спасибо за подсказку - очень помогла. Проблема решилась именно так:

Tank.transform = CGAffineTransformConcat(CGAffineTransformMakeRotation(angle),
                                                               CGAffineTransformMakeTranslation(X,Y));

Но появился новый косяк - картинка вращается не относительно центра - при повороте против часовой (слайдер влево) - относительно левого края, по часовой - относительно правого. C чем это может быть связано?

Это сообщение отредактировал(а) SlavaMinsk - 3.4.2014, 10:57
PM MAIL   Вверх
Shklyar
Дата 3.4.2014, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 211
Регистрация: 28.11.2007
Где: Kyiv

Репутация: нет
Всего: 3



Посмотрите не Tank.transform = CGAffineTransformMakeRotation(angle). Так тоже вращение относительно края?

Цитата(SlavaMinsk @  3.4.2014,  00:19 Найти цитируемый пост)
C чем это может быть связано?


Цитата(SlavaMinsk @  3.4.2014,  00:19 Найти цитируемый пост)
CGAffineTransformConcat(CGAffineTransformMakeRotation(angle),
                                                               CGAffineTransformMakeTranslation(X,Y));

Вот блин, вы то зачем делаете CGAffineTransformMakeTranslation(X,Y)?

Это сообщение отредактировал(а) Shklyar - 3.4.2014, 16:51
--------------------
https://www.youtube.com/watch?v=JZN8Xaebs_U
PM WWW   Вверх
SlavaMinsk
Дата 3.4.2014, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 29.3.2014

Репутация: нет
Всего: нет



Цитата(Shklyar @ 3.4.2014,  16:48)
Посмотрите не Tank.transform = CGAffineTransformMakeRotation(angle). Так тоже вращение относительно края?

Цитата(SlavaMinsk @  3.4.2014,  00:19 Найти цитируемый пост)
CGAffineTransformConcat(CGAffineTransformMakeRotation(angle),                        CGAffineTransformMakeTranslation(X,Y));


Вот блин, вы то зачем делаете CGAffineTransformMakeTranslation(X,Y)?

CGAffineTransformMakeRotation(angle) я и так использую,

CGAffineTransformMakeTranslation(X,Y) - чтобы обрабатывать перемещение объекта,

CGAffineTransformConcat - чтобы объединить вращение и перемещение (по сути перемножение матриц вращения и перемещения как я понял).

CGAffineTransform может применять к объекту только одну матрицу - поэтому чтобы применить их надо перемнодить и получить одну с помощью CGAffineTransformConcat.


Остаётся вопрос - почему он вращает объект не относительно его центра, а относительно краёв, да ещё разных.



Это сообщение отредактировал(а) SlavaMinsk - 3.4.2014, 17:53
PM MAIL   Вверх
Bitter
Дата 3.4.2014, 18:53 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

Репутация: 10
Всего: 27



Если я правильно понимаю, поворот в данном случае происходит не относительно какой-то точки. Вьюха поворачивается, и как бы прилипает к верхнему краю, либо углом либо ребром (попробуйте проверить это поворачивая квадрат).

Добавлено через 4 минуты и 14 секунд
Если быть точнее, то она выравнивается по левому верхнему углу после поворота
PM MAIL ICQ Skype   Вверх
SlavaMinsk
Дата 3.4.2014, 20:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 29.3.2014

Репутация: нет
Всего: нет



Цитата(Bitter @ 3.4.2014,  18:53)
Если я правильно понимаю, поворот в данном случае происходит не относительно какой-то точки. Вьюха поворачивается, и как бы прилипает к верхнему краю, либо углом либо ребром (попробуйте проверить это поворачивая квадрат).

Добавлено @ 18:57
Если быть точнее, то она выравнивается по левому верхнему углу после поворота

Да, именно так. Вы знаете как это исправить?
PM MAIL   Вверх
Bitter
Дата 4.4.2014, 00:04 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

Репутация: 10
Всего: 27



нет, не знаю. Если бы знал, то уже написал бы.
Могу только предположить, что при вращении нужно отнимать от Х и Y какое-то значение, на которое смещается центр картинки относительно верхнего левого угла.
Если это квадрат, то возможно что эта величина может быть рассчитана как-то через синус, то есть delta = sin(angle) * radius. где радиус это половина ширины квадрата. Кроме того надо отбрасывать отрицательные величины, то есть delta = ABS(sin(angle) * radius). ну и напоследок угол для синуса скорее всего тоже надо увеличивать быстрее чем для поворота, например в два раза.
То есть финальная дельта delta = ABS(sin(angle * 2) * radius)

В итоге вы должны писать 
Код

double delta = ABS(sin(angle * 2) * radius);
CGAffineTransformMakeTranslation(X - delta, Y - delta);


Но это только теория, возможно что к практике оно не имеет никакого отношения

Это сообщение отредактировал(а) Bitter - 4.4.2014, 00:11
PM MAIL ICQ Skype   Вверх
SlavaMinsk
Дата 4.4.2014, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 29.3.2014

Репутация: нет
Всего: нет



Спасибо, я примерно так и сделал. Правда всё равно получилось не идеально.  При сдвиге слайдера влево и вправо (положительный и отрицательный угол) вращение происходит относительно разных точек.

Но это уже не так принципиально.

Появился ещё один серьезный вопрос: как получить событие столкновения. Если бы вьюшка не подвергалась трансформациям - всё было бы просто:


if (CGRectIntersectRect(Tank.frame, Wall.frame))

                 [self bounce];

Но после трансформаций свойство frame использовать не получится:

http://www.iphones.ru/forum/index.php?showtopic=37301


Здесь предлагается использовать  "bounds" - границы. Кто-нибудь знает как их использовать чтобы получить событие столкновения?

Это сообщение отредактировал(а) SlavaMinsk - 4.4.2014, 13:16
PM MAIL   Вверх
Bitter
Дата 4.4.2014, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

Репутация: 10
Всего: 27



Разные вопросы надо задавать в разных темах
PM MAIL ICQ Skype   Вверх
Bitter
Дата 4.4.2014, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

Репутация: 10
Всего: 27



А вы с какой целью задаете все эти вопросы? Если вы хотите делать игры, то вы пошли по ложному пути, игры так не делаются. Если вы просто изучаете iOS то вы тоже пошли не туда, то что вы делаете в бизнес приложениях я не встречал. Если вам просто нечем заняться, то это не лучшее чем можно убить время )
PM MAIL ICQ Skype   Вверх
p1usiq
Дата 7.4.2015, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 7.4.2015

Репутация: нет
Всего: нет



Есть туториал по этому поводу на русскоязычном сайте про Swift
http://iphonecoder.ru/written-tutorials/us...gnizer-in-swift
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | iOS | Следующая тема »


 




[ Время генерации скрипта: 0.0818 ]   [ Использовано запросов: 20 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.