I am trying to animate this cube in Javascript.When I press a key it should move(or jump).However I am simply trying if my code works with the left key and it doesn’t.Any ideas?
this is my css (don’t look at the position or other details I just want to know what’s wrong with javascript)
.cuby {
height:40px;
width:40px;
background-color: coral;
position: absolute;
top:50%;
left:40px;
}
and this is javascript(I am not an expert in this language so if you see some redundant code or something that can be improved feel free to point it out).Probably the issus lies in the requestanimationframe but it’s just a huntch.
var cuby = document.querySelector(".cuby");
var rect = cuby.getBoundingClientRect();
var posx,posy,velx,vely, jumping;
for (key in rect){
if (key=="x"){
posx = rect[key];
}
if (key =="y"){
posy = rect[key];
}
};
cuby ={
x: posx,
y:posy,
velx:0,
vely:0,
jumping :false
};
var controller={
left:false,
right: false,
up: false,
keyListener :function(event){
var keystate = (event.type == "keydown")?true:false;
switch (event.keycode){
case 37:// left key
controller.left = key_state;
break;
case 38:// up key
controller.up = key_state;
break;
case 39:// right key
controller.right = key_state;
break;
}
}
};
loop = function(){
if(controller.left==true){
cuby.velx -= 0.5;
}
cuby.x += cuby.velx;
window.requestAnimationFrame(loop);
};
window.addEventListener("keydown", controller.keyListener);
window.addEventListener("keyup", controller.keyListener);
window.requestAnimationFrame(loop);
you are just updating cube object's x position .
you must modify position of the dom element in order to achieve animation.
try this in loop function
loop = function(){
if(controller.left==true){
cuby.velx -= 0.5;
}
cuby.x += cuby.velx;
document.querySelector(".cuby").style.left=cuby.x+"px";
window.requestAnimationFrame(loop);
};
that must fix it ! let me know if it doesnt.
Firstly, your switch condition does not trigger as it is not event.keycode but event.keyCode.
Secondly you are not updating your element on dom, you are just changing values inside a variable which you have reassigned to store some properties.
Please take a look at my code and see if it works for you.
var cuby = document.querySelector(".cuby");
var rect = cuby.getBoundingClientRect();
var posx,posy,velx,vely, jumping;
for (key in rect){
if (key=="x"){
posx = rect[key];
}
if (key =="y"){
posy = rect[key];
}
};
var cubyprops ={
x: posx,
y:posy,
velx:0,
vely:0,
jumping :false
};
var controller={
left:false,
right: false,
up: false,
keyListener :function(event){
var keystate = (event.type == "keydown") ? true : false;
switch (event.keyCode){
case 37:// left key
{
controller.left = keystate;
}
break;
case 38:// up key
controller.up = keystate;
break;
case 39:// right key
controller.right = keystate;
break;
}
}
};
loop = function(){
if(controller.left==true){
cubyprops.velx += 0.5;
}
cubyprops.x += cubyprops.velx;
cuby.style.left=cubyprops.x+"px";
window.requestAnimationFrame(loop);
};
window.addEventListener("keydown", controller.keyListener);
window.addEventListener("keyup", controller.keyListener);
window.requestAnimationFrame(loop);
Related
I have a canvas where we can move a shape with arrow keys.
However, I want an image to move instead of a shape and I can't work it out.
Any help?
As of now, the image appears but I can't move it.
I tried many things on the internet but they didn't work. The id for the image is image.
This is my current code:
car = {
image : img,
//jumping: true,
x:180, // center of the canvas
x_velocity:0,
y: 160,
y_velocity:0,
};
controller = {
left: false,
right: false,
up: false,
down: false,
keyListener:function(event) {
var key_state = (event.type == "keydown")?true:false;
switch(event.keyCode) {
case 37:// left key
controller.left = key_state;
break;
case 38:// up key
controller.up = key_state;
break;
case 39:// right key
controller.right = key_state;
break;
case 40: //down key
controller.down = key_state;
}
}
};
loop = function() {
if (controller.up) {
car.image.y_velocity -= 0.5;
}
if (controller.left) {
car.image.x_velocity -= 0.5;
}
if (controller.right) {
car.image.x_velocity += 0.5;
}
if (controller.down) {
car.image.y_velocity += 0.5;
}
car.image.x += car.image.x_velocity;
car.image.y += car.image.y_velocity;
car.image.x_velocity *= 0.9;// friction
car.image.y_velocity *= 0.9;
// if car.image is going off the left of the screen
if (car.image.x < -32) {
car.image.x = 1190;
// if car.image goes past right boundary
} else if (car.image.x > 1190) {
car.image.x = -32;
// if car.image goes past lower boundary
} else if (car.image.y > 790) {
car.image.y = 0;
// if car.image goes past upper boundary
} else if (car.image.y < -32) {
car.image.y = 790;
}
context.drawImage(car.image, car.x, car.y);
// call update when the browser is ready to draw again
window.requestAnimationFrame(loop);
};
window.addEventListener("keydown", controller.keyListener) //press down and it moves
window.addEventListener("keyup", controller.keyListener); //lift finger and it stops
window.requestAnimationFrame(loop);
This is the code when the shape was moving:
rectangle = {
height:20,
width:20,
x:180, // location # center of the canvas
x_velocity:0,
y: 160,
y_velocity:0,
};
controller = {
left: false,
right: false,
up: false,
down: false,
keyListener:function(event) {
var key_state = (event.type == "keydown")?true:false;
switch(event.keyCode) {
case 37:// left key
controller.left = key_state;
break;
case 38:// up key
controller.up = key_state;
break;
case 39:// right key
controller.right = key_state;
break;
case 40: //down key
controller.down = key_state;
}
}
};
loop = function() {
if (controller.up) {
rectangle.y_velocity -= 0.5;
}
if (controller.left) {
rectangle.x_velocity -= 0.5;
}
if (controller.right) {
rectangle.x_velocity += 0.5;
}
if (controller.down) {
rectangle.y_velocity += 0.5;
}
rectangle.x += rectangle.x_velocity;
rectangle.y += rectangle.y_velocity;
rectangle.x_velocity *= 0.9;// friction
rectangle.y_velocity *= 0.9;// friction
// if rectangle is going off the left of the screen
if (rectangle.x < -32) {
rectangle.x = 1190;
// if rectangle goes past right boundary
} else if (rectangle.x > 1190) {
rectangle.x = -32;
// if rectangle goes past lower boundary
} else if (rectangle.y > 790) {
rectangle.y = 0;
// if rectangle goes past upper boundary
} else if (rectangle.y < -32) {
rectangle.y = 790;
}
context.fillRect(0, 0, 1200, 800);// x, y, width, height
context.fillStyle = "white";// hex for red
context.beginPath();
context.rect(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
context.fill();
// call update when the browser is ready to draw again
window.requestAnimationFrame(loop);
};
window.addEventListener("keydown", controller.keyListener) //press down and it moves
window.addEventListener("keyup", controller.keyListener); //lift finger and it stops
window.requestAnimationFrame(loop);
I made an object out of a div in html and CSS to make a player for my game I am making and I can't get the player to move when I press the arrow keys. Does anyone know what is wrong with my code?
Here is the Javascript:
var player = document.getElementById("player");
var velocity = 5;
let player = {
height:20,
width:20,
x:200,
y:200
}
document.addEventListener("keydown", function(event){
if(event.keyCode === 37){
player.x -= velocity:
else if(event.keyCode ===38){
player.y -=velocity;
}
});
What is wrong?
Moving a div using simple Javascript just adding switch on keydown event on document and then customzing the css of div (player) top-left
var player = $('#player');
var velocity = 5;
$(document).keydown(function(e) {
switch (e.which) {
case 37:
player.css('left', player.offset().left - velocity);
break;
case 38:
player.css('top', player.offset().top - velocity);
break;
case 39:
player.css('left', player.offset().left + velocity);
break;
case 40:
player.css('top', player.offset().top + velocity);
break;
}
})
#player {
background: #ccc;
height: 50px;
width: 50px;
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<div id="player"></div>
</body>
</html>
With an addition to Ibnelaiq's answer, here's a way to make sure the players can move better -
var key = [];
function keys(db, e) {
var code = e.which || e.keyCode;
if (db == false && key.includes(code) === false) {
key.push(code);
} else if (db === true) {
key.splice(key.indexOf(code));
}
}
setInterval(() => {
console.log(key);
}, 30);
document.getElementsByClassName('game')[0].getContext('2d').fillText('Click here and press keys', 10, 10);
.game {
background-color: #f1f1f1;
outline: none;
border: 1px solid black;
}
<canvas class='game' tabindex='1' width='400px' height='290px' onkeydown='keys(false, event)' onkeyup='keys(true, event)'>
What this does:
<canvas> (not limited to <canvas> though) waits for keydown and adds event.keycode or event.which to the array. It also waits for keyup, and removes whatever event.keycode or event.which was released from the array.
The setInterval is just there to log the array into the console. The last line in the code is there to write text into <canvas>.
Of course, you can add his switch statement into the setInterval, but in there only.
I am new to Javascript!
How do I assign a variable to the current xy coordinates, so I can use relative positions to draw lines? Trying to do etch-a-sketch with keyboard. Up, down, left, right arrow keys... with JS, CSS, and HTML.
Thanks!
window.addEventListener("keydown", keyd);
function keyd(event) {
var etchMain = document.getElementById('etchMain');
var etchContext = etchMain.getContext('2d');
var key = event.keyCode;
**var etchContextPositionX;
var etchContextPositionY;**
if (key == 37) {
// left arrow
if (etchMain.toDataURL() == document.getElementById('blank').toDataURL()) {
etchContext.beginPath();
etchContext.moveTo(etchMain.width / 2, etchMain.height / 2);
// arrow specific drawing goes here
}
else {
}
}
if (key == 38) {
// up arrow
if (etchMain.toDataURL() == document.getElementById('blank').toDataURL()) {
etchContext.beginPath();
etchContext.moveTo(etchMain.width / 2, etchMain.height / 2);
// arrow specific drawing goes here
}
else {
}
}
if (key == 39) {
// right arrow
if (etchMain.toDataURL() == document.getElementById('blank').toDataURL()) {
etchContext.beginPath();
etchContext.moveTo(etchMain.width / 2, etchMain.height / 2);
// arrow specific drawing goes here
}
else {
}
}
if (key == 39) {
// down arrow
if (etchMain.toDataURL() == document.getElementById('blank').toDataURL()) {
etchContext.beginPath();
etchContext.moveTo(etchMain.width / 2, etchMain.height / 2);
// arrow specific drawing goes here
}
else {
}
}
}
function clearCanvas() {
var etchMain = document.getElementById('etchMain');
var etchContext = etchMain.getContext('2d');
etchContext.clearRect(0, 0, etchMain.width, etchMain.height);
}
i implemented a really basic idea of what you're talking about just because it sounded kind of fun. hit run snippet, then click on the canvas box to give that frame focus. the event handler will prevent window scrolling and instead use the arrow inputs to increment or decrement x and y and draw from there or you can hit space bar to clear the canvas!
the bit of design you were missing was storing x and y outside of the event handler and using the difference between the previous state of x and y to draw your canvas lines:
var pos = {
x: 50,
y: 50,
}
var etchMain = document.getElementById('etchMain');
var etchContext = etchMain.getContext('2d');
window.addEventListener('keydown', function(e) {
e.preventDefault();
if(e.keyCode === 32) {
clearCanvas();
} else {
etchContext.beginPath();
etchContext.moveTo(pos.x, pos.y);
switch (e.keyCode) {
//left arrow
case 37:
pos.x--;
break;
//up arrow
case 38:
pos.y--;
break;
//right arrow
case 39:
pos.x++;
break;
//down arrow
case 40:
pos.y++;
break;
default:
break;
}
etchContext.lineTo(pos.x, pos.y);
etchContext.stroke();
}
});
function clearCanvas() {
etchContext.clearRect(0, 0, etchMain.width, etchMain.height);
}
#etchMain {
border: 1px solid black;
}
<canvas id="etchMain" height="100" width="100" />
What am I trying to accomplish?
I'm trying to get the TrumpHead to continue moving until another key is pressed moving it in a different direction, like in the game snake. The only thing I can think of it making a bunch of cases with functions filled with cases in each? Any ideas welcome and help needed, new to javascript.
My code
var width = 1000, height = 1000; //Width and Height of Canvas
var cvs = document.getElementById('Snake'); //cvs is representing Canvas
var ctx = cvs.getContext('2d'); //ctx is context represented in 2 dimentions.
cvs.width = window.innerWidth; //setting the canvas width to be the width above.
cvs.height = window.innerHeight; //setting the canvas height to be the height above.
var img = new Image();
img.src = 'snakeHead.png';
var TrumpHead = canvasImage(100, 100, img);
window.addEventListener('keydown',this.checkOn,false);
//window.addEventListener('keyUp',this.checkOff,false);
function canvasImage(x, y, img) {
this.image = img;
this.x = x;
this.y = y;
this.width = img.width;
this.height = img.height;
return this;
}
function checkOn(e) {
//var pos = getTrumpPos();
//var x = pos [0];
//var y = pos [1];
//alert(e.keyCode);
switch (e.keyCode) {
case 37://left
if (TrumpHead.x == cvs.width) { //this is just alerting you lose if
you go off the canvas
alert("You Lose");
} else if (TrumpHead.x < 0) {
alert("You Lose");
} else {
LeftDirection ();
console.log("Pressed Left");
console.log(x,y);
}
break;
case 38: //up key
if (TrumpHead.y < 0) {
alert("You Lose");
} else if (TrumpHead.y > cvs.height) {
alert("You Lose");
} else {
console.log("Pressed Up");
UpDirection();
console.log(x,y);
}
break;
case 39: //right
if (TrumpHead.x > cvs.width) {
alert("You Lose");
} else if (TrumpHead.x < 0) {
alert("You Lose");
} else{
console.log("Pressed Right");
console.log(x,y);
RightDirection();
}
break;
case 40: //down
if (TrumpHead.y < 0) {
alert("You Lose");
} else if (TrumpHead.y > cvs.height) {
alert("You Lose");
} else{
console.log("Pressed Down");
console.log(x,y);
DownDirection(); //this is a function defined in the movementFunctions section.
}
break;
// default: alert(e.keyCode); //Everything else
}
}
function gameLoop()
{
// change position based on speed
checkOn();
setTimeout("gameLoop()",10);
}
function LeftDirection ()
{
TrumpHead.x = TrumpHead.x - 50;
ctx.clearRect(0,0,cvs.width,cvs.height); //clears the gamescreen
ctx.drawImage(TrumpHead.image, TrumpHead.x, TrumpHead.y, 50, 50);
//Puts Trump down.
}
function RightDirection ()
{
TrumpHead.x = TrumpHead.x + 50;
ctx.clearRect(0,0,cvs.width,cvs.height);
ctx.drawImage(TrumpHead.image, TrumpHead.x, TrumpHead.y, 50, 50);
}
function UpDirection ()
{
TrumpHead.y = TrumpHead.y - 50;
ctx.clearRect(0,0,cvs.width,cvs.height);
ctx.drawImage(TrumpHead.image, TrumpHead.x, TrumpHead.y, 50, 50);
}
function DownDirection () {
TrumpHead.y = TrumpHead.y + 50;
ctx.clearRect(0,0,cvs.width,cvs.height);
ctx.drawImage(TrumpHead.image, TrumpHead.x, TrumpHead.y, 50, 50);
}
You need two loops: one for input, and one for actually drawing on the display. You can use browser events to check for key input (shown here with the up and left arrow keys, and set state based off of which keys were pressed. Then you can use this in your update loop. Here's an example:
var movingLeft = false, movingUp = false;
document.body.onkeydown(function(e) {
switch(e.keyCode) {
case 38:
movingUp = true;
movingLeft = false;
break;
case 37:
movingLeft = true;
movingUp = false;
break;
}
});
// and a loop:
function loop() {
if (movingLeft) {
updateDisplayByLeftIncrement(); //update display how you want
else if(movingUp) {
updateDisplayByUpIncrement(); //update display how you want
} //...and so on for all the movements
}
//and then you can use setInterval() to loop with a delay between iterations
setInterval(loop, timeOut);
You need to break the program execution into at least two loops/pumps.
1) An input loop,
2) An update loop
If you don't then your scene update will be at the mercy of your user input or vis-a-vis.
Good luck!
here is my code,i want to move the picture(pic1) with the four arrow keyboards,draw some lines as background areas,and the pic move 1s a time,but i meet a problem that i can't move the pic1,who can tell me why it's doesn't work
<script type="text/javascript">
var canvas = document.getElementById("painting");
//canvas.addEventListener("keydown", doKeyDown, true);
var context2D = canvas.getContext("2d");
var pic = new Image();
var pic1=new Image();
var X=0,Y=200;
var X1=200,Y1=200;
pic.src = "music.jpg";
pic1.src = "qingwa.jpg";
function drawline()
{
context2D.moveTo(0,100);
context2D.lineTo(35,100);
context2D.lineTo(35,60);
context2D.lineTo(85,60);
context2D.lineTo(85,100);
context2D.lineTo(155,100);
context2D.lineTo(155,60);
context2D.lineTo(205,60);
context2D.lineTo(205,100);
context2D.lineTo(275,100);
context2D.lineTo(275,60);
context2D.lineTo(325,60);
context2D.lineTo(325,100);
context2D.lineTo(395,100);
context2D.lineTo(395,60);
context2D.lineTo(445,60);
context2D.lineTo(445,100);
context2D.lineTo(515,100);
context2D.lineTo(515,60);
context2D.lineTo(565,60);
context2D.lineTo(565,100);
context2D.lineTo(600,100);
context2D.stroke();
}
function doKeyDown(e)
{
switch (e.keyCode)
{
// the up key
case 38:
Y1 = Y1 - 10;
break;
//the down key
case 40:
Y1 = Y1 + 10;
break;
//the left key
case 37:
X1 = X1 - 10;
break;
//the right key
case 39:
X1 = X1 + 10;
break;
}
}
function drawfrogger()
{
context2D.drawImage(pic1,X1,Y1);
}
function draw()
{
context2D.clearRect(0,0,600,600);
context2D.save();
context2D.drawImage(pic,X,Y);
drawfrogger();
drawline();
context2D.restore(); //绘制结束以后,恢复画笔状态
if(X>600)
X = 0;
X = X + 100;
}
setInterval(draw, 1000);
</script>
Only elements that can receive focus such as form inputs will generate key events. You have two options:
Add a tabindex attribute to your <canvas> element to allow it to receive focus. A value of 0 will place the element in the default tab order (i.e. HTML source order). Here is article with some more detail.
Handle key events on document instead. This has the disadvantage of capturing key events that originate anywhere in the document, not just the <canvas> element you're interested in.
Change the keydown to:
document.addEventListener("keydown", function(e) {
doKeyDown(e);
});
#jbabey - this works: http://jsfiddle.net/neuroflux/cjRVn/3/