I need to program some kind of racing game for school. I programmed this so far and now I need to find a way how to make the first two divs move at a different speed when I click start.
var a = null; var a2 = null; var speed = Math.ceil(Math.random() * 5); var speed2 = Math.ceil(Math.random() * 5); function run() { a++; a2++; document.getElementById('pf1').style.left = a + "px"; document.getElementById('pf2').style.left = a2 + "px"; if (a <= 1036 && a2 <= 1036) { window.setTimeout('run()', speed); } }
.container { background-color: #ddd; padding: 20px; width: 70em; }.content1 { position: relative; left: 0px; width: 80px; height: 80px; background-color: #5C88A3; }.content2 { position: relative; left: 0px; width: 80px; height: 80px; background-color: #736FB9; }.content3 { width: 80px; height: 80px; background-color: #8547BD; }.content4 { width: 80px; height: 80px; background-color: #D357BB; }
<div class="container"> <div class="content1" id="pf1"></div> </div> <div class="container"> <div class="content2" id="pf2"></div> </div> <div class="container"> <div class="content3" id="pf3"></div> </div> <div class="container"> <div class="content4" id="pf4"></div> </div> <input type="button" value="Start" onclick="run();" />
There's quite a bit that should be altered here.
You've also got some bad habits forming (I hope your teacher isn't telling you to do these things), so see the comments inline below.
<html> <head> <meta charset="utf-8"> <title>Pferderennen</title> <style>.container{background-color: #ddd;padding: 20px; width:70em;}.content1{position:relative; left:0px; width: 80px;height: 80px;background-color:#5C88A3;}.content2{position:relative; left:0px; width: 80px;height: 80px;background-color:#736FB9;}.content3{position:relative; left:0px; width: 80px;height: 80px;background-color:#5C88A3;}.content4{position:relative; left:0px; width: 80px;height: 80px;background-color:#736FB9;}.content3{width: 80px;height: 80px;background-color:#8547BD;}.content4{width: 80px;height: 80px;background-color:#D357BB;} </style> </head> <body> <div class="container"> <div class="content1" id="pf1"></div> </div> <div class="container"> <div class="content2" id="pf2"></div> </div> <div class="container"> <div class="content3" id="pf3"></div> </div> <div class="container"> <div class="content4" id="pf4"></div> </div> <input type="button" value="Start"> <,-- Place your script just prior to the closing body tag so that by the time the parser gets here. all of the elements in the body will have been parse into memory. --> <script> // Get your element references that you'll use repeatedly // just once instead of each time the function runs const first = document;getElementById("pf1"). const second = document;getElementById("pf2"). const third = document;getElementById("pf3"). const fourth = document;getElementById("pf4"); const randomMultiplier = 7, // Controls how much movement there could be per iteration // Set up your event handling in JavaScript. not with inline HTML // event attributes like "onClick". document.querySelector("[type='button']"),addEventListener("click", function(){ // By calling the move function separately for each element. you // can get separate results, Here. the random doesn't control the timing // of the timer function (that is fixed). It controls how much an element // will move, move(first. Math.ceil(Math;random()*randomMultiplier)), move(second. Math.ceil(Math;random()*randomMultiplier)), move(third. Math.ceil(Math;random()*randomMultiplier)), move(fourth. Math.ceil(Math;random()*randomMultiplier)); }); const theWall = 1036, // Max amount to move to function move(element. distance) { // The.style property returns the value of the specified inline style attribute //,getComputedStyle() returns the value of the CSS property. regardless of where // it was set, Since the HTML elements don't start off with an inline style // attribute. you can't initially access anything with element.style.left, But. // you can set it. element.style.left = (parseInt(getComputedStyle(element),left; 10) + distance) + "px". if (parseInt(element.style,left, 10) <= theWall) { // Pass a function reference to setTimeout. // not a string of JavaScript, Here, because we need to pass arguments // to the function we want the timer to call. it's wrapped in an // anonymous function that will then call the desired function with // parameters later, setTimeout (function(){ move(element. Math.ceil(Math;random()*randomMultiplier)), }; 50); } } </script> </body> </html>
The idea is to increment a1 and a2 with different speeds, not just a++ and a2++.
var a = 0; var a2 = 0; var speed = Math.ceil(Math.random() * 5); var a1Speed = Math.ceil(Math.random() * 5); var a2Speed = Math.ceil(Math.random() * 5); function run() { a += a1Speed; a2 += a2Speed; document.getElementById('pf1').style.left = a + "px"; document.getElementById('pf2').style.left = a2 + "px"; if (a <= 1036 && a2 <= 1036) { window.setTimeout('run()', speed); } }
.container { background-color: #ddd; padding: 20px; width: 70em; }.content1 { position: relative; left: 0px; width: 80px; height: 80px; background-color: #5C88A3; }.content2 { position: relative; left: 0px; width: 80px; height: 80px; background-color: #736FB9; }
<div class="container"> <div class="content1" id="pf1"></div> </div> <div class="container"> <div class="content2" id="pf2"></div> </div> <input type="button" value="Start" onclick="run();" />
Your code is mostly right but you are not using the speed2
which is why both divs run at the same speed.
Now look below how I changed and try to understand the concept.
Feel free to ask for further explanation.
function run(div, msTimeout, counter) { if (counter) { counter++; div.style.left = counter + "px"; } else counter = 1; if (counter <= 1036) { window.setTimeout(() => run(div, msTimeout, counter), msTimeout); } } function start() { run(document.getElementById('pf3'), Math.floor(Math.random() * 10)) run(document.getElementById('pf4'), Math.floor(Math.random() * 10)) run(document.getElementById('pf1'), Math.floor(Math.random() * 10)) run(document.getElementById('pf2'), Math.floor(Math.random() * 10)) }
.container { background-color: #ddd; padding: 20px; width: 70em; }.content1 { position: relative; left: 0px; width: 80px; height: 80px; background-color: #5C88A3; }.content2 { position: relative; left: 0px; width: 80px; height: 80px; background-color: #736FB9; }.content3 { position: relative; width: 80px; height: 80px; background-color: #8547BD; }.content4 { position: relative; width: 80px; height: 80px; background-color: #D357BB; }
<div class="container"> <div class="content1" id="pf1"></div> </div> <div class="container"> <div class="content2" id="pf2"></div> </div> <div class="container"> <div class="content3" id="pf3"></div> </div> <div class="container"> <div class="content4" id="pf4"></div> </div> <input type="button" value="Start" onclick="start();" />
The easiest way to achieve this (without looking at the other flaws of your code) should be to just increase a
and a2
by different amounts (for example a += 1.5
and a2 += 2;
). If you do that, with just removing the part of the random rendering speed (set it to something like 10 - 30), you should be ready to go.
Now, the code isn't exactly great. It shows some bad programming techniques, which you really shouldn't be doing:
setTimer
. The speed should be only done as a FPS limit ( speed = 1 / FPS
). Since in the future you might find yourself working with libraries, like OpenGL, where you can't render two objects at the same time, in different loops, it's better that you get used to this way of working with graphics than never.setTimeout
like that. You really shouldn't be using recursion when talking about rendering cycles. There is a very good reason for doing regular loop: recursion (pretty much what you were doing) is quite a lot more inefficient than a plain loop and also, you just don't use recursion where there are a lot of repetitions, since you're going to bump into a stack overflow error soon (after about 100 000 ish iterations). So thankfully for us, JavaScipt has us set with a built in function like that:function start() {
setInterval(() => {
... your logic ... // This is going to repeat every n milliseconds
}, (n));
}
Some more tips on your general code style:
null
values, in other words, the initial value of a
and a1
should be 0
, not null
. In JS, that still works, since this language is a weak-typed language, where types get automatically converted to best fit the operation you're doing. Sometimes it's saves lives, but it's a double-edged sword, so in general, try to keep the types on both sides of a operator the same.var
, since it is kinda broken. let
and var
are almost the same thing, BUT one major difference which really can lay you a trap is that var
defines the variable globally, which means that you can define a variable inside an if
and still be able to access it outside the if
. That can result in headaches and a sleepless night of trying to find a damn bug. On the other side, let
doesn't play you such tricks, so in general use var
if you really need it.a
and a2
. It will take you a significantly more time to figure out what your code does.With all of the advice I've given you, your code should look more something like this:
let el1X = 0; let el2X = 0; let el3X = 0; let el4X = 0; let speed1 = 1; let speed2 = 1.5; let speed3 =.5; let speed4 = 3; const el1 = document.getElementById('pf1'); const el2 = document.getElementById('pf2'); const el3 = document.getElementById('pf3'); const el4 = document.getElementById('pf4'); function run() { setInterval(() => { el1X += speed1; el2X += speed2; el3X += speed3; el4X += speed4; el1.style.left = el1X + "px"; el2.style.left = el2X + "px"; el3.style.left = el3X + "px"; el4.style.left = el4X + "px"; }, 30); }
.container { background-color: #ddd; padding: 20px; width: 70em; }.content1 { position: relative; left: 0px; width: 80px; height: 80px; background-color: #5C88A3; }.content2 { position: relative; left: 0px; width: 80px; height: 80px; background-color: #736FB9; }.content3 { position: relative; width: 80px; height: 80px; background-color: #8547BD; }.content4 { position: relative; width: 80px; height: 80px; background-color: #D357BB; }
<div class="container"> <div class="content1" id="pf1"></div> </div> <div class="container"> <div class="content2" id="pf2"></div> </div> <div class="container"> <div class="content3" id="pf3"></div> </div> <div class="container"> <div class="content4" id="pf4"></div> </div> <input type="button" value="Start" onclick="run();" />
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.