javascript游戏-游戏杆问题

时间:2018-07-05 15:44:30

标签: javascript jquery html css

注意:我再次提出了这个问题,因为我无法编辑旧问题。 (不知道这是SO漏洞还是我的Beta Safari漏洞。)

因此,我想生成操纵杆,因为它在许多游戏中都使用过。操纵杆突出于背景和可移动的钢坯。方坯只能在后台移动。

在这里您可以找到两个图像

background

stick

let background = new Image()
let stick = new Image()
let enableMaxDistance = false

background.onload = function() {
  $(this).css({
    position: "absolute",
    left: "2%",
    bottom: "2%",
    width: "30%"
  }).appendTo(document.body)
}
stick.onload = function() {
  $(this).css({
    position: "absolute",
    left: "2%",
    bottom: "2%",
    width: "30%"
  }).appendTo(document.body)
  let zeroPosition = $(this).offset()
  $(this).draggable({
    drag: function(e, ui) {
      let distance = Math.sqrt(Math.pow(zeroPosition.top - $(this).offset().top, 2) + Math.pow(zeroPosition.left - $(this).offset().left, 2));
      if (distance > 60 && enableMaxDistance) {
        e.preventDefault();
      }
    },
    scroll: false

  })
}
background.src = "https://i.stack.imgur.com/5My6q.png"
stick.src = "https://i.stack.imgur.com/YEoJ4.png"
html, body {
  overflow: hidden;
  height: 100%;
}
input {
  margin-top: 10%;
  margin-left: 50%;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>


<input onclick="enableMaxDistance = !enableMaxDistance " value="toggle maximum distance" type="button"/>

但是在实施此操纵杆时出现了一些问题:

我的想法是通过使用jqueryUI使操纵杆可操纵,并在每次拖动事件中计算其到原点的距离。如果距离太大,将使用e.preventDefault();停止(不执行)事件。 -> 如果镜架中有一定距离,则指棒可穿戴。 问题是...

  
    
        
  1. 移开最大距离后,杆不再可拖动。

  2.     
  3. 操纵杆应该可以在边界内移动而不取消事件,因此,如果我触摸边界(超出最大距离),我必须一次又一次抓住操纵杆。

  4.     
  

如何使用jQuery + jQueryUI实现工作操纵杆?

1 个答案:

答案 0 :(得分:0)

您的逻辑问题是,由于JS处理时间的固有延迟,一旦drag事件被阻止,distance的值就会超过60。因此,当distance > 60检查被立即击中时,下一个拖动中的逻辑将立即取消。虽然可以解决此问题,但更好的解决方案是不允许该值永远大于您设置的限制。

要达到这个目的,我不建议您使用jQueryUI。您可以使用本机方法轻松完成此操作,该方法可以直接控制定位,而无需与任何内置逻辑作斗争。

性能也稍高一些,这在处理游戏机制时至关重要;尤其是在处理直接用户输入时,需要尽可能地响应。

话虽如此,您可以使用Twisty对this question的注释中列出的基本逻辑进行修改。然后,这仅仅是改变相关元素的大小的问题,这是一项微不足道的任务。试试这个:

var $canvas = $('#background');
var $pointer = $('#stick');
var $window = $(window);

var settings = {
  width: $canvas.prop('offsetWidth'),
  height: $canvas.prop('offsetHeight'),
  top: $canvas.prop('offsetTop'),
  left: $canvas.prop('offsetLeft')
};
settings.center = [settings.left + settings.width / 2, settings.top + settings.height / 2];
settings.radius = settings.width / 2;

let mousedown = false;
$window.on('mouseup', function() { mousedown = false; });
$pointer.on('mousedown', function() { mousedown = true; });
$pointer.on('mouseup', function() { mousedown = false; });
$pointer.on('dragstart', function(e) { e.preventDefault(); });

$window.on('mousemove', function(e) {
  if (!mousedown)
    return;

  var result = limit(e.clientX, e.clientY);
  $pointer.css('left', result.x + 'px');
  $pointer.css('top', result.y + 'px');
});

function limit(x, y) {
  var dist = distance([x, y], settings.center);
  if (dist <= settings.radius) {
    return {
      x: x,
      y: y
    };
  } else {
    x = x - settings.center[0];
    y = y - settings.center[1];
    var radians = Math.atan2(y, x)
    return {
      x: Math.cos(radians) * settings.radius + settings.center[0],
      y: Math.sin(radians) * settings.radius + settings.center[1]
    }
  }
}

function distance(dot1, dot2) {
  var x1 = dot1[0],
    y1 = dot1[1],
    x2 = dot2[0],
    y2 = dot2[1];
  return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
}
html,
body {
  height: 100%;
}

#background {
  background-image: url('https://i.stack.imgur.com/5My6q.png');
  position: absolute;
  height: 200px;
  width: 200px;
  top: 50%;
  left: 50%;
  margin: -100px 0 0 -100px;
  border-radius: 200px;
  border: dashed #ccc 1px;
}

#stick {
  background: transparent url('https://i.stack.imgur.com/YEoJ4.png') 50% 50%;
  position: absolute;
  width: 100px;
  height: 100px;
  border-radius: 100px;
  margin: -50px 0 0 -50px;
  top: 50%;
  left: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="background"></div>
<div id="stick"></div>