Я пытаюсь создать простую игру SVG, чтобы поймать движущийся круг. Есть кнопка catchCircle
, движущаяся preyCircle
и кнопка Поймай меня. catchCircle
начинает двигаться вертикально снизу экрана, пересекает preyCircle
и исчезает вверху. Идея состоит в том, чтобы нажать кнопку, когда preyCircle
перекрывает catchCircle
. В этом случае мне просто нужно проверить, меньше ли расстояние атрибутов cy
обоих кругов, чем сумма их radius
.
Проблема, с которой я сталкиваюсь здесь, заключается в том, чтобы получить атрибут cy
для catchCircle
, пока происходит переход. Если я попытаюсь получить preyCircle.attr('cy')
из метода события onclick
, появится ошибка:
«Неперехваченная ошибка: слишком поздно; уже выполняется»
<div id = "canvas"></div>
<button id = "catchMe"> Catch Me </button>
<span id = "msg"></span>
<script src = "https://d3js.org/d3.v5.min.js"></script>
<script>
const width = 200, height = 300, radius = 10;
const svg = d3.select('#canvas')
.append('svg')
.attr('width', width)
.attr('height', height);
const catchCircle = svg.append('circle')
.attr('r', radius)
.attr('cx', width / 2)
.attr('cy', 100)
.attr('stroke', 'red')
.attr('stroke-width', 3)
.attr('fill', 'none');
const preyCircle = svg.append('circle')
.attr('r', radius)
.attr('cx', width / 2)
.attr('cy', height - radius)
.attr('fill', 'red')
.transition()
.duration(5000)
.delay(1000)
.attr('cy', radius)
.remove();
d3.select('#catchMe')
.on('click', () => {
catched = false;
// Need to get if catchCircle and preyCircle overlapped while clicking
// I am stuck here!!!
const msgSpan = d3.select('#msg');
msgSpan.node().textContent = catched? "Perfect! :)" : "Oh no! :(";
});
</script>
Мой код работает на https://jsfiddle.net/avi5102005/uh627zt5/62/.
Может ли кто-нибудь указать мне путь, которым я должен был подойти? Заранее спасибо.
Сначала добавьте идентификатор в свои круги
const catchCircle = svg.append('circle')
.attr('r', radius)
.attr('cx', width / 2)
.attr('cy', 100)
.attr("id", "catch") //add ID
.attr('stroke', 'red')
.attr('stroke-width', 3)
.attr('fill', 'none');
const preyCircle = svg.append('circle')
.attr('r', radius)
.attr('cx', width / 2)
.attr('cy', height - radius)
.attr('fill', 'red')
.attr("id", "prey") //add ID
.transition()
.duration(5000)
.delay(1000)
.attr('cy', radius)
.remove();
затем нажмите на кнопку, сделайте:
d3.select('#catchMe')
.on('click', () => {
catched = false;
let py = d3.select("#prey").attr("cy"); // get prey's y
let px = d3.select("#prey").attr("cx"); // get prey's x
let pr = +d3.select("#prey").attr("r"); // get prey's radius
let cy = d3.select("#catch").attr("cy");
let cx = d3.select("#catch").attr("cx");
let cr = +d3.select("#catch").attr("r");
//Pythagoras distance formula
let distance = Math.pow(px-cx, 2) + Math.pow(py-cy, 2);
catched = Math.sqrt(distance) < cr + pr; //check if overlap
const msgSpan = d3.select('#msg');
msgSpan.node().textContent = catched? "Perfect! :)" : "Oh no! :(";
});
рабочий код здесь