我正在做一个项目,我们必须提出一个游戏,广场将根据math.random
改变位置
我有两个问题
似乎它正在运行该函数的多个实例,因为在正方形重新定位的几个周期之后 - 它会变得疯狂并且在整个地方移动似乎是随机的间隔。
第二个问题是,我第二次点击它时,很难让方格div注册。
链接到JSFiddle:https://jsfiddle.net/ybpdjujb/
$(document).ready(function test() {
$(document).on('click', '#target', function clicker() {
$('#target').css('left', randPosX);
$('#target').css('top', randPosY);
clearInterval(fire)
timeLeft = 2;
});
//Random
var bodyWidth = $("#playArea").width();
var bodyHeight = $("#playArea").height();
var randPosX = Math.floor((Math.random() * bodyWidth / 1.1));
var randPosY = Math.floor((Math.random() * bodyHeight / 1.1));
//TIMER
var timeLeft = 2;
var elem = document.getElementById('time');
var timerId = setInterval(countdown, 1000);
function countdown() {
if (timeLeft == 0) {
doSomething();
timeLeft = 5;
} else {
elem.innerHTML = timeLeft + ' seconds remaining';
timeLeft--;
}
}
function doSomething() {
$('#target').css('left', randPosX);
$('#target').css('top', randPosY);
clearInterval(timerId);
}
var fire = setInterval(test, 2000);
});
答案 0 :(得分:0)
TL; DR :广场正在疯狂的原因是你在两个地方做setInterval()
。您执行var fire = setInterval(test, 2000);
的地方和执行var timerId = setInterval(countdown, 1000);
的地方之一。删除其中一个(并修复一些其他的东西),你的代码就开始工作了。
但是,我们并不想停在那里,如果结构不正确,工作代码很快就会变得难以修改。因此,为了您和程序员社区的利益,让我们看看我们如何重构这些代码。我相信这对未来的编码(和调试)练习很有用。如果这已经是您的常识,请考虑这是一个复习:)
第1步:只添加 document.ready
这是一个简单的问题。文档准备好后你想做什么? 三个的事情
让我们只保留那些并将其余部分移到document.ready
区块之外。你正确完成的一件事是评论你认为应该放在一起的代码区域,让它们转换成函数!在执行此操作时,我们会注意到文件末尾的杂散setInterval()
,我们可以将其删除。
您的代码现在应该如下所示(重构已完成,如下所述):
function doSomething() {
positionSquareRandomly();
clearInterval(timerId);
timeLeft = 2;
startTimer();
}
function positionSquareRandomly(){
var bodyWidth = $("#playArea").width();
var bodyHeight = $("#playArea").height();
var randPosX = Math.floor((Math.random() * bodyWidth / 1.1));
var randPosY = Math.floor((Math.random() * bodyHeight / 1.1));
$('#target').css('left', randPosX);
$('#target').css('top', randPosY);
}
function startTimer(){
var timeLeft = 2;
var elem = document.getElementById('time');
var timerId = setInterval(countdown, 1000);
}
function countdown() {
if (timeLeft == 0) {
doSomething();
} else {
elem.innerHTML = timeLeft + ' seconds remaining';
timeLeft--;
}
}
function clicker() {
doSomething();
}
$(document).ready(function test() {
//Display square
positionSquareRandomly();
// Setup timer
startTimer();
// Setup click handler
$(document).on('click', '#target', clicker);
});
第2步:重构我
positionSquareRandomly()
应该得到坐标和显示正方形。因此,我们将$('#target').css(..)
调用移至该方法clicker()
和doSomething()
看起来非常相似,所以clicker()
现在调用doSomething()
,然后调整timeLeft
,然后定位方块并重置计时器,即清除间隔,重置startTimer()
并致电clearInterval(fire)
。 timeLeft = 5
因不需要而消失。 Uncaught ReferenceError: timeLeft is not defined
也已消失。第3步:重构II
很好,但现在我们发现没有任何反应!按 F12 打开开发者控制台,单击控制台选项卡。我看到的错误是timeLeft
。这是因为在startTimer()
中声明了countdown()
,但我们也试图在timeLeft
中使用它。我们通过在所有函数上声明var elem
(使其成为全局函数)来解决这个问题。
同样,将var timerId = 0
声明置于顶部。
在顶部声明setInterval()
。 elem.innerHTML
返回的ID始终为非零,因此这是一个很好的初始值。 (Set timeout example)
那就是它!在倒计时的if
部分添加一些有用的var timeLeft = 2;
var elem = document.getElementById('time');
var timerId = 0;
function doSomething() {
positionSquareRandomly();
clearInterval(timerId);
timeLeft = 2;
startTimer();
}
function positionSquareRandomly(){
var bodyWidth = $("#playArea").width();
var bodyHeight = $("#playArea").height();
var randPosX = Math.floor((Math.random() * bodyWidth / 1.1));
var randPosY = Math.floor((Math.random() * bodyHeight / 1.1));
$('#target').css('left', randPosX);
$('#target').css('top', randPosY);
}
function startTimer(){
timerId = setInterval(countdown, 1000);
}
function countdown() {
if (timeLeft == 0) {
elem.innerHTML = '0 seconds remaining';
doSomething();
}
else {
elem.innerHTML = timeLeft + ' seconds remaining';
timeLeft--;
}
}
function clicker() {
doSomething();
}
$(document).ready(function test() {
//Display square
positionSquareRandomly();
// Setup timer
startTimer();
// Setup click handler
$(document).on('click', '#target', clicker);
});
,我们就会得到此代码。
body {
height: 100vh;
margin: 0;
display: flex;
background: grey;
}
.left {
flex: 1;
border-right: 1px solid #eeeeee;
background-color: lightblue;
}
.right {
flex: 4;
margin-top: 45px;
margin-right: 30px;
background-color: yellow;
}
我们可以做的更多事情,但现在我相信代码清晰,简洁,最重要的是,可维护。