注意:我再次提出了这个问题,因为我无法编辑旧问题。 (不知道这是SO漏洞还是我的Beta Safari漏洞。)
因此,我想生成操纵杆,因为它在许多游戏中都使用过。操纵杆突出于背景和可移动的钢坯。方坯只能在后台移动。
在这里您可以找到两个图像
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();
停止(不执行)事件。 -> 如果镜架中有一定距离,则指棒可穿戴。
问题是...
移开最大距离后,杆不再可拖动。
操纵杆应该可以在边界内移动而不取消事件,因此,如果我触摸边界(超出最大距离),我必须一次又一次抓住操纵杆。 p >
如何使用jQuery
+ jQueryUI
实现工作操纵杆?
答案 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>