Реализовать джойстик аркадной игры с помощью Vue

Vue.js
Реализовать джойстик аркадной игры с помощью Vue

предисловие

Самая ранняя реализация этого эффекта была достигнута в iOS в 2011 году с помощью Objective-C. Оригинальный адрес склада:code.Google.com/archive/afraid/from…

Реализовать это во Vue бесполезно, ведь Vue не игровой фреймворк, а кто это?VueЭта тема самая популярная 😁, я все еще надеюсь, что когда я пишу статью, ее увидит больше людей...

У меня такое впечатление, что я реализовал этот кейс на трех языках в разное время. Так что независимо от того, какой фреймворк или язык вы используете, если вы понимаете лежащие в его основе принципы, его легко реализовать.

Некоторые пункты знаний в этой статье аналогичны эффекту перетаскивания карточек в Vue на прошлой неделе.Вот версия Vue3Подготовка к 2021 году, имитация эффекта перетаскивания карт с помощью Vue3

Трехслойный пользовательский интерфейс

Весь пользовательский интерфейс разделен на три слоя

  • Первый слой - головка клюшки, размер не меняется, перетаскивается视觉效果Площадь.
  • Второй слой — тело стержня, сильно растяжимое, для拟物流Мимический реализм.
  • Третий слой — это нижний, который просто размещен на картинке, чтобы сделать визуальный опыт более полным.

Конечно, нет второго слоя и третьего слоя, который не влияет на функцию джойстика, но кто мне сказал, что это拟物流Внешний интерфейс偏执狂Шерстяная ткань?

пропустить эти три слоя через绝对定位+z-indexсложить, установивtouchСобытия делают главу клуба перетаскиваемой. Для того, чтобы все четко видели слои, мы сначала сделали голову прозрачной.

круговая область перетаскивания

Ну, в круглом отверстии есть палка (неда), поэтому мы должны ограничить перетаскивание круглой областью

onTouchMove(e){
  var curTouch=e.touches[0];
  var tleft=curTouch.clientX-startLeft;
  var ttop=curTouch.clientY-startTop;
  //获取点击位置和起点的直线距离,也就是半径
  var distance = getDistance(tleft,ttop,0,0);
  //如果这个距离是否大于圆形可移动区域的半径,则强行变更
  if(distance>=this.ballMoveRadius)distance = this.ballMoveRadius;

  //最后通过夹角,正弦,余弦,半径还原x,y坐标
  var angle = Math.atan2((ttop-0), (tleft-0));
  this.left=Math.cos(angle)*distance;
  this.top=Math.sin(angle)*distance;
}

Основная часть кода: мы сначала передаем所在点а также原点радиус местоположенияdistance, а угол междуangle. Затем восстановите его, определив радиус и прилежащий угол.x,yкоордината. Вы можете добиться эффекта управления и перетаскивания в круглой области.

//获取两点间直线距离的算法
var getDistance=function(x1, y1, x2, y2) {
  var _x = Math.abs(x1 - x2); 
  var _y = Math.abs(y1 - y2); 
  return Math.sqrt(_x * _x + _y * _y);
}

застенчивый жезл

Самой проблемной деталью здесь является корпус штока, и его нужно менять на расстояние перетаскивания джойстика.长度и поверните угол в соответствии с положением джойстика.

<view class='stick' :class="{animation:inDraging===false&&transition}" :style="{height: stickHeight+'px',transform:'translateX(-50%)'}">
  <view :style="{transform:'rotate('+(angle/(3.14159/180)-90)+'deg)'}" style="transform-origin: 50% 0%;width: 100%;height: 100%;">
    <slot name="stick">
    </slot>
  </view>
</view>

Здесь я использовал два слоя дом, чтобы закончить корпус удилища, один слой использовалheightДля изменения высоты один слой используетtransfromЗадайте угол поворота и центральную точку поворота. У вас есть лучший способ реализовать это, дайте мне знать в области комментариев.

Включенный алгоритм угла поворотаangle/(3.14159/180), минус 90, чтобы градусы начинались с12点钟позиция.

onTouchMove(e){
  var curTouch=e.touches[0];
  var tleft=curTouch.clientX-startLeft;
  var ttop=curTouch.clientY-startTop;

  var distance = getDistance(tleft,ttop,0,0);
  if(distance>=this.ballMoveRadius)distance = this.ballMoveRadius;

  var angle = Math.atan2((ttop-0), (tleft-0));
  this.left=Math.cos(angle)*distance;
  this.top=Math.sin(angle)*distance;

  //同步杆体的高度,旋转角度
  this.stickHeight = distance;
  this.angle = angle;
}

Теперь UE джойстика в основном завершено.Дальше нам нужно вывести некоторые значения.Ведь джойстик не может быть один., который необходимо использовать для управления движением других элементов.

Значение джойстика

  • направление

Когда мы двигаем стержень, мы уже записали направление, то есть уголangle.

  • прочность
power = 当前半径/最大半径;

Силы джойстика в King of Fighters нет, но она разделена на множество игр.轻推а также重推(По сути, это отношение текущего расстояния джойстика к максимальному расстоянию), например轻推да иди,重推это бежать.

Кадр гифки немного опущен, вы видите скорость движения?

составной

Теперь инкапсулируйте приведенные выше результаты в компонент vue для повторного использования.

<ezjoystick
    :touchRadius="100"
    :ballMoveRadius="50"
    :transition="true"
    @onJoyStickUpdate="onBeetleJoystickUpdate"
    >
    <view slot="ball">
    </view>
    <view slot="stick">
    </view>
    <view slot="bottom">
    </view>
</ezjoystick>
  • три свойства
    1. touchRadiusФактический радиус обнаружения касания
    2. ballMoveRadiusМаксимальный радиус перемещения головки клюшки
    3. transitionВключить ли смягчение возврата
  • три слота
    1. ballглава клуба
    2. stickтело стержня
    3. bottomконец

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

  • два события
    1. onJoystickUpdateСрабатывает при изменении значения
    2. onJoystickCancelЗапускается, когда касание остановлено

Реализовать классический интерфейс

Компонент инкапсулирован, давайте воспользуемся нашим компонентом для реализации нескольких классических интерфейсов

  • аркадная палка

  • поперечный ключ

Суть имитации крестового ключа заключается в повороте угла на 4 направления.Вот это я написал вскользь, должна быть более изящная реализация.

onCrossJoyStickUpdate(obj){
    this.crossupPressed=false;
    this.crossrightPressed=false;
    this.crossdownPressed=false;
    this.crossleftPressed=false;
    if(obj.angle>-2.35&&obj.angle<-0.75){
        this.crossupPressed=true;
    }else if(obj.angle>-0.75&&obj.angle<0.75){
        this.crossrightPressed=true;
    }else if(obj.angle>0.75&&obj.angle<2.35){
        this.crossdownPressed=true;
    }else{
        this.crossleftPressed=true;
    }
}
  • джойстик королевской славы

Вращение стрелки во внешней ассоциации - это просто...

Репозиторий исходного кода

GitHub.com/Как насчет Эчжоу/Prank…

После клонирования исходного кода используйте HBuilerX, чтобы открыть его, чтобы быстро увидеть экземпляр, или скопируйте компоненты в проект vuecli для импорта и использования.

Позже, как реализовать трюк

Что натирает? Это последовательное выполнение нескольких направлений + кнопки в течение определенного периода времени, чтобы вызвать движение. Например, трюк Май Ширануи на этой картинке нужно выполнить, чтобы←↙↓↘→+илиступня.

Задумывались ли вы о том, как этого добиться, когда видите это?
С нетерпением жду ваших статей
После написания, пожалуйста, напишите мне, чтобы вам понравилось

Если никто не писал об этой теме, то я напишу специальную搓招пойми

Обратите внимание на Дашуая и займитесь полным стеком

Последние статьи (Спасибо за вашу поддержку и поддержку 🌹🌹🌹)


Добро пожаловать в Paizhuan, давайте вместе обсудим более элегантную реализацию