![]() |
|
![]() ![]() ![]() |
|
SlavaMinsk |
|
|||
Новичок Профиль Группа: Участник Сообщений: 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 |
|||
|
||||
Bitter |
|
|||
![]() Опытный лентяй ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1209 Регистрация: 15.8.2004 Где: Харьков, Ukraine Репутация: 10 Всего: 27 |
Object.center = CGPointMake (Object.center.x, Object.center.y);
это вообще гениально ) Это сообщение отредактировал(а) Bitter - 2.4.2014, 13:57 |
|||
|
||||
SlavaMinsk |
|
|||
Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 29.3.2014 Репутация: нет Всего: нет |
Спасибо, я знаю) Так подсказать можете как это сделать? |
|||
|
||||
Bitter |
|
|||
![]() Опытный лентяй ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1209 Регистрация: 15.8.2004 Где: Харьков, Ukraine Репутация: 10 Всего: 27 |
Если б мог, подсказал бы, а так кто его знает, что у вас там написано...
Ну попробуйте поменять местами вызовы Moving и Rotate |
|||
|
||||
SlavaMinsk |
|
|||
Новичок Профиль Группа: Участник Сообщений: 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 |
|||
|
||||
likalilika |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 3 Регистрация: 1.4.2014 Где: Кавказ Репутация: 1 Всего: 1 |
В сценах крутить текстурой большого ума не нужно:) Чет не поняла для чего так много лишнего написано?
|
|||
|
||||
SlavaMinsk |
|
|||
Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 29.3.2014 Репутация: нет Всего: нет |
Информативнее пожалуйста. Что лишнее. Как вращать и двигать UIImage одновременно? Напишите как надо если знаете. |
|||
|
||||
Bitter |
|
|||
![]() Опытный лентяй ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1209 Регистрация: 15.8.2004 Где: Харьков, Ukraine Репутация: 10 Всего: 27 |
На самом деле вопрос не такой уж и простой, вы пытаетесь работать с аффинными преобразованиями, которые во-первых требуют понимания принципов этих преобразований, а во-вторых они довольно капризны. Аффинные преобразования оперируют матрицами. То есть для описания объекта в пространстве используется матрица, в которую заносятся данные о повороте по осям, масштабе и перемещении. Перемножая матрицы друг на друга, получаете комбинации преобразований поворот-перенос-масштаб.
В вашем случае свойство transform и есть та матрица. Комбинируйте матрицы поворота и переноса, чтобы добиться того чего хотите. Как их комбинировать легко найдете в инете. Вот кстати тут похожая тема и ответ помечен решенным, так что может вам поможет http://stackoverflow.com/questions/1983751...iimage-and-move Это сообщение отредактировал(а) Bitter - 2.4.2014, 23:17 |
|||
|
||||
SlavaMinsk |
|
|||
Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 29.3.2014 Репутация: нет Всего: нет |
Спасибо за подсказку - очень помогла. Проблема решилась именно так: Tank.transform = CGAffineTransformConcat(CGAffineTransformMakeRotation(angle), CGAffineTransformMakeTranslation(X,Y)); Но появился новый косяк - картинка вращается не относительно центра - при повороте против часовой (слайдер влево) - относительно левого края, по часовой - относительно правого. C чем это может быть связано? Это сообщение отредактировал(а) SlavaMinsk - 3.4.2014, 10:57 |
|||
|
||||
Shklyar |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 211 Регистрация: 28.11.2007 Где: Kyiv Репутация: нет Всего: 3 |
Посмотрите не Tank.transform = CGAffineTransformMakeRotation(angle). Так тоже вращение относительно края?
Вот блин, вы то зачем делаете CGAffineTransformMakeTranslation(X,Y)? Это сообщение отредактировал(а) Shklyar - 3.4.2014, 16:51 --------------------
https://www.youtube.com/watch?v=JZN8Xaebs_U |
|||
|
||||
SlavaMinsk |
|
|||
Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 29.3.2014 Репутация: нет Всего: нет |
CGAffineTransformMakeRotation(angle) я и так использую, CGAffineTransformMakeTranslation(X,Y) - чтобы обрабатывать перемещение объекта, CGAffineTransformConcat - чтобы объединить вращение и перемещение (по сути перемножение матриц вращения и перемещения как я понял). CGAffineTransform может применять к объекту только одну матрицу - поэтому чтобы применить их надо перемнодить и получить одну с помощью CGAffineTransformConcat. Остаётся вопрос - почему он вращает объект не относительно его центра, а относительно краёв, да ещё разных. Это сообщение отредактировал(а) SlavaMinsk - 3.4.2014, 17:53 |
|||
|
||||
Bitter |
|
|||
![]() Опытный лентяй ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1209 Регистрация: 15.8.2004 Где: Харьков, Ukraine Репутация: 10 Всего: 27 |
Если я правильно понимаю, поворот в данном случае происходит не относительно какой-то точки. Вьюха поворачивается, и как бы прилипает к верхнему краю, либо углом либо ребром (попробуйте проверить это поворачивая квадрат).
Добавлено через 4 минуты и 14 секунд Если быть точнее, то она выравнивается по левому верхнему углу после поворота |
|||
|
||||
SlavaMinsk |
|
|||
Новичок Профиль Группа: Участник Сообщений: 16 Регистрация: 29.3.2014 Репутация: нет Всего: нет |
Да, именно так. Вы знаете как это исправить? |
|||
|
||||
Bitter |
|
|||
![]() Опытный лентяй ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1209 Регистрация: 15.8.2004 Где: Харьков, Ukraine Репутация: 10 Всего: 27 |
нет, не знаю. Если бы знал, то уже написал бы.
Могу только предположить, что при вращении нужно отнимать от Х и Y какое-то значение, на которое смещается центр картинки относительно верхнего левого угла. Если это квадрат, то возможно что эта величина может быть рассчитана как-то через синус, то есть delta = sin(angle) * radius. где радиус это половина ширины квадрата. Кроме того надо отбрасывать отрицательные величины, то есть delta = ABS(sin(angle) * radius). ну и напоследок угол для синуса скорее всего тоже надо увеличивать быстрее чем для поворота, например в два раза. То есть финальная дельта delta = ABS(sin(angle * 2) * radius) В итоге вы должны писать
Но это только теория, возможно что к практике оно не имеет никакого отношения Это сообщение отредактировал(а) Bitter - 4.4.2014, 00:11 |
|||
|
||||
SlavaMinsk |
|
|||
Новичок Профиль Группа: Участник Сообщений: 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 |
|||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | iOS | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |