Вектор движения
| |
Saitei | Дата: Вторник, 24 Июня 2014, 14:58 | Сообщение # 21 |
старожил
Сейчас нет на сайте
| wcpt, есть картинка корабля размерами 100х100. Центр - это точка на этой картинке, от которой производится вращение и т.п. Хотелось бы, чтобы снаряды летели из другой точки, смещенной относительно центра Ну, чтоб снаряды из пушек летели, что, в принципе, логично))
|
|
| |
wcpt | Дата: Вторник, 24 Июня 2014, 15:07 | Сообщение # 22 |
постоянный участник
Сейчас нет на сайте
| смысл тот же. Пусть кораблик смотрит вверх, а место, где появляется снаряд, выравнено по середине ширины кораблика, но учтены его габариты, то есть, дело обстоит так, что снаряд вылетает примерно из носовой части корабля. Найдешь опять же, вектор (позицию снаряда отнимешь от позиции центра корабля), а затем повернешь его, используя опять-таки, божественную матрицу поворота...
Сообщение отредактировал wcpt - Вторник, 24 Июня 2014, 15:09 |
|
| |
Saitei | Дата: Вторник, 24 Июня 2014, 15:19 | Сообщение # 23 |
старожил
Сейчас нет на сайте
| wcpt, так. Центр находится в (18;50). Если корабль позиционировать абсолютно горизонтально, то я хочу, чтобы снаряды летели из (110;53) Тогда нужный вектор (110-18;53-50)=(92;3)? Если не ошибся, то далее надо (x+92*cos(angle*PI/180); y+3*sin(angle*PI/180))? Так? (x, y - координаты центра (относительно игрового окна(поля)))Добавлено (24.06.2014, 15:15) ---------------------------------------------
Цитата Saitei ( ) Если не ошибся, то далее надо (x+92*cos(angle*PI/180); y+3*sin(angle*PI/180))? Так? (x, y - координаты центра (относительно игрового окна(поля))) Таки ошибся :<Добавлено (24.06.2014, 15:19) --------------------------------------------- ((x+92)*cos(angle*PI/180)-(y+3)*sin(angle*PI/180);(x+92)*sin(angle*PI/180)+(y+3)*cos(angle*PI/180),angle)) тоже не помогло(
Сообщение отредактировал Saitei - Вторник, 24 Июня 2014, 15:13 |
|
| |
wcpt | Дата: Вторник, 24 Июня 2014, 15:21 | Сообщение # 24 |
постоянный участник
Сейчас нет на сайте
| опять же, не ясно - горизонтально - это как? Налево, или направо? Если по умолчанию кораблик смотрит горизонтально направо, позиция центра - (10,10), а гипотетическая позиция снаряда, с учетом направления корабля - (10,20), то снаряд летит прямо, в направлении от корабля. Пусть теперь, если предположить, что кораблик повернут на пи/6 рад против часовой стрелки, то матрица поворота будет |cos(пи/6) -sin(пи/6)| |sin(пи/6) cos(пи/6)| Умножив её на вектор(матрицу-столбец, по правде) направления снаряда, используемого по умолчанию, т.е. на (20-10,10-10), получим новый вектор(ну, матрицу-столбец, но кого это волнует...), т.е. новые координаты снаряда относительно кораблика, повернутого на 30 градусов против часовой стрелки.
Сообщение отредактировал wcpt - Вторник, 24 Июня 2014, 15:22 |
|
| |
Snake174 | Дата: Вторник, 24 Июня 2014, 15:21 | Сообщение # 25 |
участник
Сейчас нет на сайте
| Код X = x0 + (x - x0) * cos(a) - (y - y0) * sin(a); Y = y0 + (y - y0) * cos(a) + (x - x0) * sin(a);
(x0; y0) - точка, вокруг которой вращаем (x; y) - точка, которую вращаем X, Y - новые координаты точки (x; y) a - угол, на который повёрнута башня (в радианах)
Спрайты башни и танка повёрнуты вверх
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games
Сообщение отредактировал Snake174 - Вторник, 24 Июня 2014, 15:31 |
|
| |
Saitei | Дата: Вторник, 24 Июня 2014, 15:27 | Сообщение # 26 |
старожил
Сейчас нет на сайте
| Snake174, абракадабра случилась! Код bullets.push_back(new Bullet(x+92*cos(angle*PI/180) - 3*sin(angle*PI/180), y+3*cos(angle*PI/180)+92*sin(angle*PI/180),angle)); Работает! Спасибо)))
|
|
| |
wcpt | Дата: Вторник, 24 Июня 2014, 15:44 | Сообщение # 27 |
постоянный участник
Сейчас нет на сайте
| можно задать небольшой вопрос - а зачем надо переводить угол в градусную меру?
Сообщение отредактировал wcpt - Вторник, 24 Июня 2014, 15:46 |
|
| |
Saitei | Дата: Вторник, 24 Июня 2014, 17:28 | Сообщение # 28 |
старожил
Сейчас нет на сайте
| Сделал движение в сторону мышки. Странно работает: то бежит нормально, то не хочет (хотя модуль вектора нормальный) Код case 1: { if(sqrt(pow(mouse.getPosition().x - x, 2) + pow(mouse.getPosition().y - y, 2)) >= 550) { x += SPEED*cos(angle*PI/180)*dt.asMilliseconds(); y += SPEED*sin(angle*PI/180)*dt.asMilliseconds(); } break; } Добавлено (24.06.2014, 17:19) --------------------------------------------- wcpt, у меня просто ф-ция, которая вращает спрайт, принимает градусы Сейчас мне это не важно, я суть вкурить хочу Добавлено (24.06.2014, 17:21) --------------------------------------------- а нет, проверка левая. Хм... Добавлено (24.06.2014, 17:28) --------------------------------------------- Почему длина вектора считается неправильно? Формула же sqrt(x^2 + y^2); где x,y - координаты вектора...
|
|
| |
wcpt | Дата: Вторник, 24 Июня 2014, 20:59 | Сообщение # 29 |
постоянный участник
Сейчас нет на сайте
| не знаю, по этому коду ничего конкретного об ошибке предположить нельзя. А откуда число 550?
|
|
| |
Saitei | Дата: Вторник, 24 Июня 2014, 21:42 | Сообщение # 30 |
старожил
Сейчас нет на сайте
| wcpt, левое число, т.к. баг найти не мог. А баг в том, что я брал глобальные координаты, а не локальные...
А как точку заставить вращаться вокруг точки? Не работает...: Код x = mouse.getPosition(*window).x + (x - mouse.getPosition(*window).x)*cos(angle*PI/180) - (y - mouse.getPosition(*window).y)*sin(angle*PI/180); y = mouse.getPosition(*window).y + (y - mouse.getPosition(*window).y)*cos(angle*PI/180) + (x - mouse.getPosition(*window).x)*sin(angle*PI/180); break; Точнее работает, но результат не тот
|
|
| |
wcpt | Дата: Вторник, 24 Июня 2014, 22:46 | Сообщение # 31 |
постоянный участник
Сейчас нет на сайте
| Цитата Saitei ( ) А как точку заставить вращаться вокруг точки? Точка - тот же вектор, только с началом в (0,0). Если х0 у0 - координаты точки, которую хочешь вращать, а х1 у1 - точка, вокруг которой хочешь вращать, то найди вектор (х0-х1,у0-у1) (*), поверни его, а потом найди вектор (х1+х',y1+y'), где (x',y') - вектор (*) после вращения.
Сообщение отредактировал wcpt - Среда, 25 Июня 2014, 00:09 |
|
| |
Saitei | Дата: Вторник, 24 Июня 2014, 23:55 | Сообщение # 32 |
старожил
Сейчас нет на сайте
| Цитата wcpt ( ) Точка - тот же вектор, только с началом в (0,0) Если х0 у0 - координаты точки, которую хочешь вращать, а х1 у1 - точка, вокруг которой хочешь вращать, то найди вектор (х0-х1,у0-у1) (*), поверни его, а потом найди вектор (х1+х',y1+y'), где (x',y') - вектор (*) после вращения. x1+x`, y1+y` - новые координаты корабля? Я уже запутался х_х
|
|
| |
wcpt | Дата: Вторник, 24 Июня 2014, 23:57 | Сообщение # 33 |
постоянный участник
Сейчас нет на сайте
| повернешь (х0-х1,у0-у1) - получишь вектор (x',y'), потом найдешь (х1+х',y1+y') (х1 и у1 даны по условию), а координаты вектора (х1+х',y1+y') и есть новые координаты вращаемой точки.
Сообщение отредактировал wcpt - Среда, 25 Июня 2014, 00:08 |
|
| |
Snake174 | Дата: Среда, 25 Июня 2014, 05:44 | Сообщение # 34 |
участник
Сейчас нет на сайте
|
Love2D code: Код function Tank:update( dt ) -- координаты мыши local mousePos = vector( love.mouse.getX(), love.mouse.getY() ) -- self.pos - точка О (центр танка) local dir = self.pos - mousePos
-- угол, на который нужно повернуть башню танка local angle1 = -math.atan2( dir.x, dir.y ) / (math.pi / 180) -- текущий угол поворота башни local angle2 = self.top_angle
-- плавный поворот башни танка if angle2 < 0 then angle2 = angle2 + 360 end
if angle1 < 0 then angle1 = angle1 + 360 end
local a = angle2 - angle1
if a > 180 then a = a - 360 elseif a < -180 then a = a + 360 end
-- 1.5 - скорость поворота a = a * dt * 1.5
if math.abs(a) > 0.01 then self.top_angle = self.top_angle - a else self.top_angle = angle1 end
self.top_dir.x = math.sin( math.rad( self.top_angle ) ) self.top_dir.y = -math.cos( math.rad( self.top_angle ) )
-- выстрел if Input.mouseDown("l") then local ind = #self.bullets + 1 self.bullets[ ind ] = {}
-- определяем точку, из которой будут вылетать пули (точка A) local x = self.pos.x - ((self.pos.y - 85) - self.pos.y) * math.sin( math.rad( self.top_angle ) ) local y = self.pos.y + ((self.pos.y - 85) - self.pos.y) * math.cos( math.rad( self.top_angle ) )
self.bullets[ ind ].pos = vector( x, y ) self.bullets[ ind ].dir = vector( self.top_dir.x, self.top_dir.y ):normalized() self.bullets[ ind ].img = love.graphics.newImage("data/images/tank_bullet.png") self.bullets[ ind ].size = vector( self.bullets[ ind ].img:getWidth(), self.bullets[ ind ].img:getHeight() ) self.bullets[ ind ].angle = self.top_angle end
for i = #self.bullets, 1, -1 do self.bullets[i].pos = self.bullets[i].pos + self.bullets[i].dir * self.bullet_speed * dt
if self:checkBulletBounds( self.bullets[i] ) then table.remove( self.bullets, i ) end end end
Надеюсь, всё понятно объяснил.
Пример в действии
Цитата Центр находится в (18;50). Если корабль позиционировать абсолютно горизонтально, то я хочу, чтобы снаряды летели из (110;53) X = 18 + (110 - 18) * cos(a) - (53 - 50) * sin(a); Y = 50 + (53 - 50) * cos(a) + (110 - 18) * sin(a);
Цитата Тогда нужный вектор (110-18;53-50)=(92;3)? Нужный вектор (X, Y)
При 0 градусов дуло танка у меня смотрит вверх.
Не следует обманывать инспектора Pipmak Assistant Love2D Exporter Love2D-Helpers Old Consoles Games
Сообщение отредактировал Snake174 - Среда, 25 Июня 2014, 06:19 |
|
| |
Saitei | Дата: Среда, 25 Июня 2014, 16:35 | Сообщение # 35 |
старожил
Сейчас нет на сайте
| А можно как-то через векторное произведение вектора направления игрока (начало - координаты игрока, конец - координаты мышки) и вектора Z(0;0;1)? Получится же новый вектор, перпендикулярный этим двум. Но я немного запамятовал про такие фишки как "левая\правая тройка" и т.п.
Помогите мысль дооформить, пожалуйста Добавлено (25.06.2014, 16:35) --------------------------------------------- (ну это я про движение вправо\влево. Реализовать пытаюсь стрейф. Движение вперед\назад есть: Код case 1: { if(sqrt(pow(mouse.getPosition(*window).x - x, 2) + pow(mouse.getPosition(*window).y - y, 2)) >= 10) { x += SPEED*cos(angle*PI/180)*dt.asMilliseconds(); y += SPEED*sin(angle*PI/180)*dt.asMilliseconds(); } break; } Код case 3: { x -= SPEED*cos(angle*PI/180)*dt.asMilliseconds(); y -= SPEED*sin(angle*PI/180)*dt.asMilliseconds(); break; } )
|
|
| |
wcpt | Дата: Среда, 25 Июня 2014, 23:24 | Сообщение # 36 |
постоянный участник
Сейчас нет на сайте
| Цитата Saitei ( ) А можно как-то через векторное произведение вектора направления игрока (начало - координаты игрока, конец - координаты мышки) и вектора Z(0;0;1)? Получится же новый вектор, перпендикулярный этим двум. Но я немного запамятовал про такие фишки как "левая\правая тройка" и т.п. Векторное произведение a x Z = b всегда будет указывать в одну сторону(в том смысле, что ориентация результирующего вектора будет сохраняться), поэтому для стрейфа в другую сторону, Z надо брать другим (противоположным, если точнее), либо менять местами векторы-"множители". А можно просто брать левый/правый перпендикуляр к вектору направления. Это происходит через вращение, но проще, чем для "непрямых" углов. Если есть вектор (2,3) (в стандартной системе координат, Оу направлена вверх), то правый перпендикуляр к нему будет (3,-2), а левый - (-3,2), и сразу видно, как изменяются координаты, так что и без векторного произведения можно обойтись, по крайней мере, в двухмерных координатах. Векторное же произведение, выраженное через координаты самым простым способом (если и есть какие-то другие, не знаю, если честно) требует 6 умножений (ну, вообще-то, чуть больше, но и так оценишь положение дел) и 3 сложения.
Добавлено (25.06.2014, 23:24) --------------------------------------------- автор, напиши - до тебя дошло, или нет?
Сообщение отредактировал wcpt - Четверг, 26 Июня 2014, 23:11 |
|
| |
Saitei | Дата: Пятница, 27 Июня 2014, 14:59 | Сообщение # 37 |
старожил
Сейчас нет на сайте
| wcpt, дошло, спасибо большое
|
|
| |
wcpt | Дата: Пятница, 27 Июня 2014, 15:01 | Сообщение # 38 |
постоянный участник
Сейчас нет на сайте
| так, и что в итоге выбрал?
|
|
| |
Saitei | Дата: Пятница, 27 Июня 2014, 16:09 | Сообщение # 39 |
старожил
Сейчас нет на сайте
| wcpt, один раз ищу векторное произведение, а потом решаю куда двигать перса (достаточно домножить х и y на -1 для того, чтобы повернуть вектор на 180 градусов). Потом (если не ошибься в терминах) я вектор нормировал и домножал на скорость. В итоге получал новые координаты персонажа(корабля)
|
|
| |
wcpt | Дата: Пятница, 27 Июня 2014, 21:20 | Сообщение # 40 |
постоянный участник
Сейчас нет на сайте
| и ладненько, главное, чтоб работало.
|
|
| |
|