Четверг, 28 Марта 2024, 16:18

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 2 из 2
  • «
  • 1
  • 2
Форум игроделов » Программирование » Общие обсуждения программистов » Вектор движения
Вектор движения
SaiteiДата: Вторник, 24 Июня 2014, 14:58 | Сообщение # 21
старожил
Сейчас нет на сайте
wcpt, есть картинка корабля размерами 100х100. Центр - это точка на этой картинке, от которой производится вращение и т.п. Хотелось бы, чтобы снаряды летели из другой точки, смещенной относительно центра smile Ну, чтоб снаряды из пушек летели, что, в принципе, логично))
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, у меня просто ф-ция, которая вращает спрайт, принимает градусы smile Сейчас мне это не важно, я суть вкурить хочу

Добавлено (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)?
Получится же новый вектор, перпендикулярный этим двум. Но я немного запамятовал про такие фишки как "левая\правая тройка" и т.п.

Помогите мысль дооформить, пожалуйста smile

Добавлено (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
постоянный участник
Сейчас нет на сайте
и ладненько, главное, чтоб работало.
Форум игроделов » Программирование » Общие обсуждения программистов » Вектор движения
  • Страница 2 из 2
  • «
  • 1
  • 2
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг