И have a hockey game in javascript but tво players can not move at the same time. In fact, when one moves, the other remains motionless. It is normal for both players to move at the same time in this game. Do you know a function that can help me? Should a foreign function be added? Thank you for your help.
<html>
<head>
<style>
body {
margin: 0;
}
.P1 {
position: absolute;
font-size: 110px;
background-color: white;
}
.P2 {
position: absolute;
left: 1500px;
font-size: 110px;
background-color: white;
}
</style>
</head>
<body onkeydown="keyD(event)">
<span class="P1">|</span>
<span class="P2">|</span>
</body>
<script>
var P1D = 0;
var P2D = 0;
var spanP1 = document.getElementsByClassName("P1")[0];
var spanP2 = document.getElementsByClassName("P2")[0];
function keyD(e) {
if (e.keyCode == 38 || e.keyCode == 40) {
f1(e);
}
if (e.keyCode == 83 || e.keyCode == 87) {
f2(e);
}
}
function f1(e) {
if (e.keyCode == 40) {
if (P2D >= 620) {
} else {
P2D += 10;
spanP2.style.top = P2D + "px";
}
}
if (e.keyCode == 38) {
if (P2D <= -20) {
} else {
P2D -= 10;
spanP2.style.top = P2D + "px";
}
}
}
function f2(e) {
if (e.keyCode == 83) {
if (P1D >= 620) {
} else {
P1D += 10;
spanP1.style.top = P1D + "px";
}
}
if (e.keyCode == 87) {
if (P1D <= -20) {
} else {
P1D -= 10;
spanP1.style.top = P1D + "px";
}
}
}
</script>
</html>
You would need to remember which keys are pressed down or not. For example by saving their state in an object.
Furthermore, when player 1 has a key pressed and player 2 starts pressing another, the key of player 1 stops repeating for a moment. To prevent this you would need to stop relying on the key repeat of the system of the user. For example by using a setInterval or later implement it into your gameloop. Example:
// Save key states in an object
const keystates = {}
document.addEventListener('keydown', e => {
keystates[e.code] = true
})
document.addEventListener('keyup', e => {
keystates[e.code] = false
})
// Repeat the key action in your gameloop
const repeat_interval = 500
setInterval(() => {
if (keystates['KeyW']) console.log('Player1 up')
if (keystates['KeyS']) console.log('Player1 down')
if (keystates['ArrowUp']) console.log('Player2 up')
if (keystates['ArrowDown']) console.log('Player2 down')
}, repeat_interval)
EDIT:
Also don't use keyCode as it is deprecated
Related
hi i want to make to move something like a car with setinterval but when i clicked the button after once
setinterval called again than its speed looks come more than after clicking so i want use one interval not more can help me?
i know answerd this question befor me but it didnt work for me or i cant use it im so tired about that
//variables
var m_tank = document.getElementById("tank");
//var message = document.getElementById("show_car_info");
var iv, a, s;
//functions
function loaded() {
alert("hello");
}
function start_game(e) {
a = 0;
//for (s = 5000; s == 0; s -= 5) {}
if (e.keyCode == 37 || e.keyCode == 38 || e.keyCode == 39 || e.keyCode == 40) {
s = 1000;
iv = setInterval(() => {
moving(m_tank);
}, s);
}
}
function moving(m_tank) {
a += 10;
var l_num = m_tank.offsetLeft;
var t_num = m_tank.offsetTop;
if (e.keyCode == 39) {
//alert("ArrowRight");
l_num += a;
console.log("right:" + l_num, "a_right:" + a);
} else if (e.keyCode == 37) {
//alert("ArrowLeft");
l_num -= a;
console.log("left:" + l_num, "a_left:" + a);
} else if (e.keyCode == 38) {
//alert("ArrowUp");
t_num -= a;
console.log("Up:" + t_num, "a_up:" + a);
} else if (e.keyCode == 40) {
//alert("ArrowDown");
t_num += a;
console.log("Down:" + t_num, "a_down:" + a);
}
m_tank.style.left = l_num + "px";
m_tank.style.top = t_num + "px";
}
body {
background-color: lightsteelblue;
font-family: Arial, Helvetica, sans-serif;
text-align: center;
overflow: hidden;
}
#tank {
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
background-color: brown;
}
<body onload="loaded()" onkeydown="start_game(e=event)">
<!-- <p id="show_car_info"></p> -->
<div>
<div id="tank">
<p>tank</p>
</div>
</div>
</body>
Hi I'm trying to fix an issue in my JavaScript and unfortunately I'm a little stuck on where I'm going wrong here.
I'm designing a slider where the sliders thumb changes to a different range which is currently 1 - 5. The issue is that I cannot seem to get the emojis to appear as they should when the slider changes.
Here is what I'm working with:
var slider = document.getElementById('myRange')
function onChange(event) {
var x = event.target.value
if (x <= 3) {
slider.className = ''
} else if (x > 3 && x <= 6) {
slider.className = 'MyClass-1'
} else if (x > 6) {
slider.className = 'MyClass-2'
} else if (x > 6) {
slider.className = 'MyClass-3'
}
}
input[type=range] {
-webkit-appearance: none;
height: 20px;
width: 200px;
max-width: 100%;
margin: 25px auto;
background: #08121c;
border: 3px solid #08121c;
border-radius: 100px;
display: block;
}
input[type=range]:focus {
outline: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
border: none;
height: 35px;
width: 35px;
border-radius: 100%;
background-color: transparent;
background-image: url(http://d1cxtglzz1rb2m.cloudfront.net/emoji/SVG/18-slightly-smiling-face.svg);
background-position: center center;
background-repeat: no-repeat;
background-size: 100%;
}
input[type="range"].MyClass-1::-webkit-slider-thumb {
background-image: url(http://d1cxtglzz1rb2m.cloudfront.net/emoji/SVG/06-grinning-face-with-smiling-eyes.svg);
}
input[type="range"].MyClass-2::-webkit-slider-thumb {
background-image: url(http://d1cxtglzz1rb2m.cloudfront.net/emoji/SVG/12-smiling-face-with-sunglasses.svg);
}
input[type="range"].MyClass-3::-webkit-slider-thumb {
background-image: url(http://d1cxtglzz1rb2m.cloudfront.net/emoji/SVG/13-smiling-face-with-heart-eyes.svg);
}
<div class="slider-bar">
<input type="range" id="myRange" min="1" max="5" value="1" />
</div>
What is going on with this function?:
function onChange(event) {
var x = event.target.value
if (x <= 3) {
slider.className = ''
} else if (x > 3 && x <= 6) {
slider.className = 'MyClass-1'
} else if (x > 6) {
slider.className = 'MyClass-2'
} else if (x > 6) {
slider.className = 'MyClass-3'
}
}
The last else if will never execute.
EDIT: If x is the integer that is the same number you want to match the class, you can simply replace all the code above with
slider.className = `MyClass-${x}`;
replace you JS script with this code and it should work.
however you do need to fix your if statement
var slider = document.getElementById("myRange");
slider.addEventListener('mouseup', function(event) {
var x = event.target.value
console.log(x)
if (x <= 3) {
slider.className = ''
} else if (x > 3 && x <= 4) {
slider.className = 'MyClass-1'
} else if (x > 4) {
slider.className = 'MyClass-2'
} else if (x > 5) {
slider.className = 'MyClass-3'
}
})
Your JS onchange event is not wired to anything. Try this
var slider = document.getElementById('myRange')
slider.onchange = function(event) {
var x = event.target.value
if (x <= 3) {
slider.className = ''
} else if (x > 3 && x <= 6) {
slider.className = 'MyClass-1'
} else if (x > 6) {
slider.className = 'MyClass-2'
} else if (x > 6) {
slider.className = 'MyClass-3'
}
JSFiddle
Your conditional statements need some work though, as they will not all be executed. Perhaps something like this:
slider.onchange = function(event) {
var x = event.target.value
if (x <= 3) {
slider.className = ''
} else if (x > 3 && x <= 4) {
slider.className = 'MyClass-1'
} else if (x > 4) {
slider.className = 'MyClass-2'
} else if (x > 5) {
slider.className = 'MyClass-3'
}
}
Im trying to create simple VAT calc in Javascript. It should work that first I set amount of money in #vat-amount then I pick .rate and then I could click one of two buttons which will show my results.
However my console shows that ReferenceError: rateValue is not defined.
But I define it before I call brutto or netto function. What's wrong?
Here's my code & JSFiddle:
// Select your input element.
var fixnumber = document.getElementById('vat-amount');
// Listen for input event on numInput.
fixnumber.onkeydown = function(e) {
if(!((e.keyCode > 95 && e.keyCode < 106)
|| (e.keyCode > 47 && e.keyCode < 58)
|| (e.keyCode == 188)
|| e.keyCode == 8)) {
return false;
}
}
// Jquery function
$('.rate').on('change', function rateValue() {
var value =this.value;
if(value == 'five')
{
var ratemoney = 5
}
else if (value == 'eight')
{
var ratemoney = 8
}
else {
var ratemoney = 23
}
});
var vatamount;
function setValues() {
vatamount = Number(document.getElementById("vat-amount").value);
}
function brutto() {
setValues();
rateValue();
result = (vatamount * (ratemoney / 100) + vatamount);
score = result.toFixed(2);
document.getElementById("howmuch").innerHTML = score;
}
function netto() {
setValues();
rateValue();
result = (vatamount - ((ratemoney / 100) * vatamount));
var score = result.toFixed(2);
document.getElementById("howmuch").innerHTML = score;
}
https://jsfiddle.net/rq620kzo/2/
Sorry that I mix Jquery with Javascript.
I moved the rateValue function out to the scope you are trying to access it from. If you are going to modify values used outside of a function, don't redeclare them inside of the function
// Select your input element.
var fixnumber = document.getElementById('vat-amount');
var ratemoney;
// Listen for input event on numInput.
fixnumber.onkeydown = function(e) {
if (!((e.keyCode > 95 && e.keyCode < 106) ||
(e.keyCode > 47 && e.keyCode < 58) ||
(e.keyCode == 188) ||
e.keyCode == 8)) {
return false;
}
}
// Jquery function
$('.rate').on('change', rateValue);
var vatamount;
function rateValue() {
var value = $('.rate').val();
if (value == 'five') {
ratemoney = 5
} else if (value == 'eight') {
ratemoney = 8
} else {
ratemoney = 23
}
}
function setValues() {
vatamount = Number(document.getElementById("vat-amount").value);
}
function brutto() {
setValues();
rateValue();
result = (vatamount * (ratemoney / 100) + vatamount);
score = result.toFixed(2);
document.getElementById("howmuch").innerHTML = score;
}
function netto() {
setValues();
rateValue();
result = (vatamount - ((ratemoney / 100) * vatamount));
var score = result.toFixed(2);
document.getElementById("howmuch").innerHTML = score;
}
body {
padding: 0;
margin: 0;
}
.site-background {
background: #cccccc;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.container {
max-width: 70vw;
background: #c1c1c1;
}
.first-vat-calc h2 {
display: inline;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="site-background">
<div class="container">
<h1>Kalkulatory dla pracownika</h1>
<h2>Oblicz VAT 23% </h2>
<div class="first-vat-calc">
<h2>Podaj kwotę</h2><input id="vat-amount" type="number" style="vat-money-input" pattern="[0-9]+([\.,][0-9]+)?" step="0.01" min="0">
<h2>Podaj stawkę VAT</h2><select name="vatrate" class="rate" style="vat-money-input">
<option value="five">5%</option>
<option value="eight">8%</option>
<option value="twentythree">23%</option>
</select>
<input type="button" onclick="brutto()" value="oblicz brutto">
<input type="button" onclick="netto()" value="oblicz netto">
<p>Wynik to:<span id="howmuch" style="howmuch" style="color: white;padding-left: 0,5vw;"></span></p>
</div>
</div>
</div>
You cannot define named functions inside event handlers like that. Define it outside and you can call it from the handler.
I am having trouble with a basic movement engine I have made, where the Up key triggers a function making a small div go up, and the Down key doing the opposite. I am fairly sure it's to do with the += in the Down() function, and I have tested it with -=, which works fine, just I can't work out what might be clashing with the function.
At the bottom, I have put a comment to indicate where my problem is.
var interval = '';
var key = false;
var interval1 = '';
var key1 = false;
$(document).keydown(function(e) {
if(e.which === 38) {
if(key === false){
interval = setInterval(function(){Up()},20)
key = true;
}
}
if(e.which === 40) {
if(key1 === false){
interval1 = setInterval(function(){Down()},20)
key1 = true;
}
}
});
$(document).keyup(function(e) {
if(e.which === 38) {
clearInterval(interval)
key = false;
}
if(e.which === 40) {
clearInterval(interval1)
key1 = false;
}
});
document.getElementById('Jumper').style.top = '46%';
var Top = parseInt(document.getElementById('Jumper').style.top);
var Topp = parseInt(document.getElementById('Jumper').style.top);
function Up(){
if(Top > 0){
Top = parseInt(document.getElementById('Jumper').style.top);
Top -= 0.2;
document.getElementById('Jumper').style.top = Top+'%';
}
}
function Down(){
if(Topp > 0){
Topp = parseInt(document.getElementById('Jumper').style.top);
Topp += 0.2; //<--PROBLEM
document.getElementById('Jumper').style.top = Topp+'%';
}
}
#Jumper{
position: absolute;
top: 46%;
left: 48%;
height: 8%;
width: 4%;
background-color: red;
opacity: 1;
}
<div id='Jumper'></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
Can anyone please tell me how I can fix this?
Here is a fiddle of it: https://jsfiddle.net/Tobsta/2gnoq5hx/
You must use parseFloat(), because parseInt returns integer ::
Topp = parseFloat(document.getElementById('Jumper').style.top);
https://jsfiddle.net/2gnoq5hx/3/
It was this line that stuffed it all up:
Topp = parseInt(document.getElementById('Jumper').style.top);
Thanks Juhana for pointing that out.
Here's the working thing:
var interval = '';
var key = false;
var interval1 = '';
var key1 = false;
var interval2 = '';
var key2 = false;
var interval3 = '';
var key3 = false;
$(document).keydown(function(e) {
if(e.which === 38) {
if(key === false){
interval = setInterval(function(){Up()},20)
key = true;
}
}
if(e.which === 40) {
if(key1 === false){
interval1 = setInterval(function(){Down()},20)
key1 = true;
}
}
if(e.which === 37) {
if(key2 === false){
interval2 = setInterval(function(){Left()},20)
key2 = true;
}
}
if(e.which === 39) {
if(key3 === false){
interval3 = setInterval(function(){Right()},20)
key3 = true;
}
}
});
$(document).keyup(function(e) {
if(e.which === 38) {
clearInterval(interval)
key = false;
}
if(e.which === 40) {
clearInterval(interval1)
key1 = false;
}
if(e.which === 37) {
clearInterval(interval2)
key2 = false;
}
if(e.which === 39) {
clearInterval(interval3)
key3 = false;
}
});
document.getElementById('Jumper').style.top = '46%';
document.getElementById('Jumper').style.left = '48%';
var a = parseInt(document.getElementById('Jumper').style.top);
var b = parseInt(document.getElementById('Jumper').style.left);
function Up(){
if(a > 0){
a -= 1;
document.getElementById('Jumper').style.top = a+'%';
}
}
function Down(){
if(a < 92){
a += 1;
document.getElementById('Jumper').style.top = a+'%';
}
}
function Left(){
if(b > 0){
b -= 0.5;
document.getElementById('Jumper').style.left = b+'%';
}
}
function Right(){
if(b < 96){
b += 0.5;
document.getElementById('Jumper').style.left = b+'%';
}
}
#Jumper{
position: absolute;
top: 46%;
left: 48%;
height: 8%;
width: 4%;
background-color: red;
opacity: 1;
}
<div id='Jumper'></div>
Or the js fiddle
http://www.jsfiddle.net/Tobsta/2gnoq5hx/2
I'm creating a minigame using HTML5 and jQuery without canvas (!) and, while developing the bounce part (when circle collide with stage limit), I found a bug:
When the circle collides with the bottom or right limits and you keep pressing the down/right arrow key, the circle continues bouncing with the stage limit, but when you do the same thing with the opposite stage limits (top and left), the circle bounce one or two times, and then stops (I want to get the second reaction, when it bounce and then stop). I've also discovered that this bug only occur in Safari. Can someone help me to solve it?
JSFiddle
Demo on site
<!DOCTYPE html>
<html>
<head>
<title>VelJS 3 Pre-Alpha</title>
<!-- This app was coded by Tiago Marinho -->
<!-- Special thanks to Drizr, from the interwebs -->
<!-- Do not leech it! -->
<link rel="shortcut icon" href="http://i.imgur.com/Jja8mvg.png">
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
var yvel = 0, xvel = 0;
var up = false, // W or arrow up
left = false, // A or arrow left
right = false, // D or arrow right
down = false; // S or arrow down
// Keydown:
document.addEventListener("keydown", function (evt) {
if (evt.keyCode == 87 || evt.keyCode == 38) { // up
up = true;
}
if (evt.keyCode == 65 || evt.keyCode == 37) { // left
left = true;
}
if (evt.keyCode == 68 || evt.keyCode == 39) { // right
right = true;
}
if (evt.keyCode == 83 || evt.keyCode == 40) { // down
down = true;
}
if (evt.keyCode == 8 || evt.keyCode == 80) { // del/p
}
});
// Keyup:
document.addEventListener("keyup", function (evt) {
if (evt.keyCode == 87 || evt.keyCode == 38) { // up
up = false;
}
if (evt.keyCode == 65 || evt.keyCode == 37) { // left
left = false;
}
if (evt.keyCode == 68 || evt.keyCode == 39) { // right
right = false;
}
if (evt.keyCode == 83 || evt.keyCode == 40) { // down
down = false;
}
});
function y(obj){
return $(obj).offset().top;
}
function x(obj){
return $(obj).offset().left;
}
setInterval(function(){
// Keydown/keyup handler:
if (up == true) {
yvel -= 2;
} else {
if (yvel < 0) {
yvel++;
}
}
if (left == true) {
xvel -= 2;
} else {
if (xvel < 0) {
xvel++;
}
}
if (right == true) {
xvel += 2;
} else {
if (xvel > 0) {
xvel--;
}
}
if (down == true) {
yvel += 2;
} else {
if (yvel > 0) {
yvel--;
}
}
var nextposx = $("circle").offset().left+xvel/16;
var nextposy = $("circle").offset().top+yvel/16;
if(nextposy < 0 || nextposy+20 > window.innerHeight){
yvel = Math.round(yvel*-0.5);
}
if(nextposx < 0 || nextposx+20 > window.innerWidth){
console.log(xvel);
xvel = Math.round(xvel*-0.5);
console.log(xvel);
}
$("circle").css({
top:$("circle").offset().top+yvel/16,
left:$("circle").offset().left+xvel/16
});
},8);
</script>
<style>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700,600' rel='stylesheet' type='text/css'> * {
margin: 0;
}
html,
body {
-webkit-text-smoothing: antialiased;
height:100%;
overflow:hidden;
color: #fff;
background-color: #181818;
}
circle{
position:absolute;
top:0;
left:0;
width:20px;
height:20px;
border-radius:10px;
background:#fff;
}
</style>
</head>
<body>
<circle></circle>
</body>
</html>
I'm not using canvas because I've already tried to create this minigame using EaselJS, but I found lots of problems and there's no reason to use it in my case, since this game doesn't have any images (then there's no need for hardware acceleration).
This answer is a full update of a previous non-working answer.
The complete code of the answer is available at the bottom.
I had to check all browser to see what were the problems:
-On Chrome all were working perfectly so I had nothing to change.
-On Safari the ball was bouncing on the bottom and on the right. I figured out that the problem was caused by a position which was set in float and not in int so I just had to round the displacement.
$("circle").css({
top:Math.round($("circle").offset().top+yvel/16),
left:Math.round($("circle").offset().left+xvel/16)
});
My first answer was resolving the problem by cheating in displacements, this time the answer fix it. This amelioration shouldn't affect Chrome (but I can't test it now).
-On Firefox the ball was stopping before the bottom of the page. I just had to change comparators for collision by the body and add a margin of 0px to it.
In older versions of Firefox, when you press UP the ball was going a little DOWN before going UP, I his this bug is due to the xvel--, xvel++, yvel-- and yvel++ that are faster than xvel+=2, xvel-=2, yvel+=2 and yvel-=2 so I replace them by two times ++xvel, two times --xvel, two times ++yvel and two times --yvel which should be faster (again I can't test it right now so I hope this is working). These amelioration should't affect Chrome and Safari.
Then I optimise your code to make it more efficient.
Your HTML hasn't change.
Your css is now:
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700,600' rel='stylesheet' type='text/css'> * {
margin: 0;
}
html, body {
-webkit-text-smoothing: antialiased;
height:100%;
overflow:hidden;
color: #fff;
background-color: #181818;
margin: 0px;
}
circle {
position:absolute;
top:0;
left:0;
width:20px;
height:20px;
border-radius:10px;
background:#fff;
}
Your JavaScript is now:
var yvel = 0, xvel = 0;
var up = false, // W or arrow up
left = false, // A or arrow left
right = false, // D or arrow right
down = false; // S or arrow down
// Keydown:
document.addEventListener("keydown", function (evt) {
if (evt.keyCode == 87 || evt.keyCode == 38) { // up
up = true;
}
if (evt.keyCode == 65 || evt.keyCode == 37) { // left
left = true;
}
if (evt.keyCode == 68 || evt.keyCode == 39) { // right
right = true;
}
if (evt.keyCode == 83 || evt.keyCode == 40) { // down
down = true;
}
if (evt.keyCode == 8 || evt.keyCode == 80) { // del/p
}
});
// Keyup:
document.addEventListener("keyup", function (evt) {
if (evt.keyCode == 87 || evt.keyCode == 38) { // up
up = false;
}
if (evt.keyCode == 65 || evt.keyCode == 37) { // left
left = false;
}
if (evt.keyCode == 68 || evt.keyCode == 39) { // right
right = false;
}
if (evt.keyCode == 83 || evt.keyCode == 40) { // down
down = false;
}
});
function y(obj){
return $(obj).offset().top;
}
function x(obj){
return $(obj).offset().left;
}
setInterval(function(){
// Keydown/keyup handler:
if (up) {
--yvel;
--yvel;
} else if (yvel < 0) {
yvel++;
}
if (left) {
--xvel;
--xvel;
} else if (xvel < 0) {
xvel++;
}
if (right) {
++xvel;
++xvel;
} else if (xvel > 0) {
xvel--;
}
if (down) {
++yvel;
++yvel;
} else if (yvel > 0) {
yvel--;
}
var nextposx = $("circle").offset().left+xvel/16;
var nextposy = $("circle").offset().top+yvel/16;
if(nextposy < 0 || nextposy+20 > $('body').height()){
yvel = Math.round(yvel*-0.5);
}
if(nextposx < 0 || nextposx+20 > $('body').width()){
xvel = Math.round(xvel*-0.5);
}
$('circle').css({
top:Math.round($('circle').offset().top+yvel/16),
left:Math.round($('circle').offset().left+xvel/16)
});
},8);
You have a JSFiddle of the result here.
The only error that remain is that in Firefox the circle exceeds of few pixels at the right but it's very minimal.
Sorry if my english is bad, I hope you get all what I write.
I think my job here is done...
Have fun with that =D.