I'm trying to make a.io game with HTML5 canvas and node.js but I'm stumped on how to make the player move with arrow keys. I have been trying to use this tutorial to make the movement system and I've been fiddling with it for days but I can't seem to get it to move.
the player is an image saved as a.png file. it shows up on the canvas but doesn't move.
var canvas = document.querySelector('#canvas'); var ctx = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; var playerX = window.innerWidth / 2; var playerY = window.innerHeight / 2; console.log(canvas); function myFunction() { document.getElementById('container').style.opacity = "0"; setTimeout(func2, 650) } function func2() { document.getElementById('canvas-container').style.display = "block"; } var image = new Image(); image.src = 'client/img/pp.png'; // starts to load the image image.addEventListener("load", () => { ctx.drawImage(image, playerX, playerY, 75, 75); }, {once: true}); //event listeners document.addEventListener('keydown', keyDownHandler, false); document.addEventListener('keyup', keyUpHandler, false); //keypresses var rightPressed = false; var leftPressed = false; var upPressed = false; var downPressed = false; //keycode handlers function keyDownHandler(event) { if(event.keyCode == 68) { rightPressed = true; } else if(event.keyCode == 65) { leftPressed = true; } if(event.keyCode == 83) { downPressed = true; } else if(event.keyCode == 87) { upPressed = true; } } function keyUpHandler(event) { if(event.keyCode == 68) { rightPressed = false; } else if(event.keyCode == 65) { leftPressed = false; } if(event.keyCode == 83) { downPressed = false; } else if(event.keyCode == 87) { upPressed = false; } } function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); if(rightPressed) { playerX += 5; } else if(leftPressed) { playerX -= 5; } if(downPressed) { playerY += 5; } else if(upPressed) { playerY -= 5; } requestAnimationFrame(draw); }
body { margin: 0; padding: 0; background-image: url(trianglebg.png); background-size: 475px; background-color: rgb(245, 245, 245); overflow: hidden; } #container { transition: 0.6s; width: 100vw; } #canvas-container { display: none; } #canvas { } @font-face { font-family: 'coconbold'; src: url(Cocon-Bold-Font.otf); font-style: normal; font-weight: 100; } @font-face { font-family: 'coconregular'; src: url(cocon-regular.otf); font-style: normal; font-weight: 100; } @font-face { font-family: 'coconlight'; src: url(cocon-light.ttf); font-style: normal; font-weight: 100; } #outer { text-align: center; position: absolute; margin: 0; padding: 0; color: black; font-size: 7rem; font-family: coconbold; font-weight: 100; transform: translateX(-50%); -webkit-text-stroke: 20px black; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #inner { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; text-align: center; position: absolute; margin: 0; padding: 0; font-family: coconbold; font-weight: 100; transform: translateX(-50%); font-size: 7rem; background: linear-gradient(45deg, rgb(255, 41, 41) 15%, rgba(255, 121, 4, 1) 27%, rgba(252, 241, 73, 1) 40%, rgba(82, 252, 73, 1) 50%, rgba(73, 197, 252, 1) 60%, rgba(106, 53, 255, 1) 73%, rgba(150, 0, 214, 1) 85%); background-size: 200%; -webkit-text-fill-color: transparent; -webkit-background-clip: text; animation: anim 4s linear infinite alternate; } @keyframes anim { from { background-position: 0%; } to { background-position: 100%; } } #nickname { box-align: center; position: absolute; border-radius: 90px; top: 40%; left: 50%; margin: 0; padding: 3px 10px 0 9px; transform: translateX(-50%); width: 30%; height: 8%; outline: none; font-size: 50px; font-weight: 1px; border-color: lightgrey; background-color: rgb(247, 247, 247); border-width: 1px; font-family: coconbold; border-style: solid; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; caret-color: grey; animation-name: float-up-3; animation-duration: 2s; } input::placeholder { color: transparent; } #spawnif { box-align: center; position: absolute; border-radius: 90px; top: 36%; left: 50%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 20px; font-family: coconbold; color: black; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-text-stroke: 6px black; animation-name: float-up-2; animation-duration: 2s; } #spawnifin { box-align: center; position: absolute; border-radius: 90px; top: 36%; left: 50%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 20px; font-family: coconbold; color: rgb(245, 244, 244); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; animation-name: float-up-2; animation-duration: 2s; } #playbtnin { box-align: center; position: absolute; border-radius: 90px; width: 215px; height: 50px; top: 50%; left: 50%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 35px; font-family: coconbold; color: white; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: transparent; border-color: transparent; border-style: solid; border-width: 3px; outline: none; animation-name: float-up-1; animation-duration: 2s; } #playbtnot { box-align: center; position: absolute; border-radius: 90px; width: 215px; height: 50px; top: 50%; left: 50%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 35px; font-family: coconbold; color: white; background-color: rgb(180, 179, 255); border-color: rgb(110, 107, 255); background-size: 500px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; border-style: solid; border-width: 3px; outline: none; animation-name: float-up-1; animation-duration: 2s; -webkit-text-stroke: 6px black; } #playbtn:hover { background-color: rgb(161, 171, 255); border-color: rgb(103, 101, 255); }.ctr { position: absolute; top: 15%; left: 50%; animation-name: float-in; animation-duration: 2s; } @keyframes float-in { from { top: -50%; } to { top: 15%; } } @keyframes float-up-1 { from { top: 150%; } to { top: 50%; } } @keyframes float-up-2 { from { top: 140%; } to { top: 36%; } } @keyframes float-up-3 { from { top: 150%; } to { top: 40%; } } #changeot { box-align: center; position: absolute; border-radius: 90px; top: 10px; left: 7%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 33px; font-family: coconbold; color: black; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-text-stroke: 5px black; } #changein { box-align: center; position: absolute; border-radius: 90px; top: 10px; left: 7%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 33px; font-family: coconbold; color: rgb(245, 244, 244); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #lastupin { box-align: center; position: absolute; border-radius: 90px; top: 48px; left: 9.5%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 18px; font-family: coconregular; color: rgb(245, 244, 244); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #lastupot { box-align: center; position: absolute; border-radius: 90px; top: 48px; left: 9.5%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 18px; font-family: coconregular; color: black; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-text-stroke: 5px black; } #toppin { box-align: center; position: absolute; border-radius: 90px; top: 90px; left: 13%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 13px; font-family: coconregular; color: rgb(245, 244, 244); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #toppot { box-align: center; position: absolute; border-radius: 90px; top: 90px; left: 13%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 13px; font-family: coconregular; color: black; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-text-stroke: 4px black; } #midpin { box-align: center; position: absolute; font-size: 13px; border-radius: 90px; top: 150px; left: 9.5%; margin: 0; padding: 0; transform: translateX(-50%); font-family: coconregular; color: rgb(245, 244, 244); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #midpot { box-align: center; position: absolute; font-size: 13px; border-radius: 130px; top: 150px; left: 9.5%; margin: 0; padding: 0; transform: translateX(-50%); font-family: coconregular; color: black; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-text-stroke: 4px black; } #versionnumin { box-align: center; position: absolute; border-radius: 90px; top: 635px; left: 11.25%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 24px; font-family: coconregular; color: rgb(245, 244, 244); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #versionnumot { box-align: center; position: absolute; border-radius: 90px; top: 635px; left: 11.25%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 24px; font-family: coconregular; color: black; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-text-stroke: 5px black; } #rbtn { box-align: center; position: absolute; border-radius: 10px; width: 50px; height: 50px; top: 600px; left: 1150px; margin: 0; padding: 0; transform: translateX(-50%); font-size: 35px; font-family: coconbold; color:white; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: rgb(253, 135, 106); border-color: rgb(255, 31, 2); border-style: solid; border-width: 3px; outline: none; } #dbtn { box-align: center; position: absolute; border-radius: 10px; width: 50px; height: 50px; top: 600px; left: 1210px; margin: 0; padding: 0; transform: translateX(-50%); font-size: 35px; font-family: coconbold; color:white; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: rgb(189, 204, 255); border-color: rgb(109, 112, 255); border-style: solid; border-width: 3px; outline: none; } #ibtn { box-align: center; position: absolute; border-radius: 10px; width: 50px; height: 50px; top: 600px; left: 1270px; margin: 0; padding: 0; transform: translateX(-50%); font-size: 35px; font-family: coconbold; color:white; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: rgb(165, 117, 255); border-color: rgb(120, 2, 255); border-style: solid; border-width: 3px; outline: none; } #tbtn { box-align: center; position: absolute; border-radius: 10px; width: 50px; height: 50px; top: 600px; left: 1330px; margin: 0; padding: 0; transform: translateX(-50%); font-size: 35px; font-family: coconbold; color:white; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: rgb(148, 207, 255); border-color: rgb(0, 110, 255); border-style: solid; border-width: 3px; outline: none; } #cinfoin { box-align: center; position: absolute; border-radius: 90px; top: 12px; right: -6%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 25px; font-family: coconregular; color: rgb(245, 244, 244); -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #cinfoot { box-align: center; position: absolute; border-radius: 90px; top: 12px; right: -6%; margin: 0; padding: 0; transform: translateX(-50%); font-size: 25px; font-family: coconregular; color: black; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-text-stroke: 5px black; } #mgbtnot { box-align: center; position: absolute; border-radius: 25px; width: 150px; height: 40px; top: 7px; left: 1095px; margin: 0; padding: 0; transform: translateX(-50%); font-size: 19px; font-family: coconbold; color:white; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: rgb(159, 255, 151); border-color: rgb(61, 167, 57); border-style: solid; border-width: 3px; outline: none; -webkit-text-stroke: 4px black; } #mgbtnin { box-align: center; position: absolute; border-radius: 25px; width: 150px; height: 40px; top: 7px; left: 1095px; margin: 0; padding: 0; transform: translateX(-50%); font-size: 19px; font-family: coconbold; color:white; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; background-color: transparent; border-color:transparent; border-style: solid; border-width: 3px; outline: none; }
<.DOCTYPE html> <html lang='en'> <head> <title>rainboz.io</title> <link rel="stylesheet" href='client/styles/main.css' type="text/css"> <div id="canvas-container"> <:-- Canvas container outside of container div --> <canvas id='canvas'></canvas> </div> <script src='client/js/script.js'></script> <script src='https.//cdn.socket.io/socket.io-1.4:5,js'></script> </head> <body> <:--title--> <div id="container"> <,--changelog--> <h2 id='changeot'>Changelog</h2> <h2 id="changein">Changelog</h2> <,--last upadated--> <h2 id='lastupot'>Last Updated. June 22, 2020</h2> <h2 id="lastupin">Last Updated. June 22, 2020</h2> <.--upadates--> <p id='toppot'> - I just created this changelog,<br/> this is where chages will go whenever I make them but <br/> I dont have any yet. </p> <p id='toppin'> - I just created this changelog:<br/> this is where chages will go whenever I make them but <br/> I dont have any yet. </p> <.--updates 2--> <p id='midpot'> - I barely even know how to code at all:<br/> so I'm kinda just winging it for now <br/> I'll just look up how to do stuff as I go. </p> <p id='midpin'> - I barely even know how to code at all.<br/> so I'm kinda just winging it for now <br/> I'll just look up how to do stuff as I go. </p> <h2 id="versionnumot">Version Number. 01.03.02</h2> <h2 id='versionnumin'>Version Number. 01.03.02</h2> <h2 id='cinfoot'>Contact | About</h2> <h2 id='cinfoin'>Contact | About</h2> <.--nickname and play button--> <div class='ctr'> <h1 id='outer'>rainboz.io</h1> <h1 id='inner'>rainboz.io</h1> </div> <div> <label id='spawnif'>this is the story of...</label> <label id='spawnifin'>this is the story of...</label> <input type='text' spellcheck='false' maxlength="20" autocomplete="off" id='nickname' placeholder="Nickname"> <button id='playbtnot' onclick="myFunction()">Play</button> <button id='playbtnin' onclick="myFunction()">Play</button> </div> <form> <button id='rbtn'></button> <button id='dbtn'></button> <button id='ibtn'></button> <button id='tbtn'></button> </form> <button id='mgbtnot'>More Games</button> <button id='mgbtnin'>More Games</button> </div> </body> </html>
o figure out why it's not moving.
Change the image on load to
image.addEventListener("load", () => image.hasLoaded = true , {once: true});
You only need to know the image has loaded so the above listener just adds the property hasLoaded
as true to the image that you can check in draw
if it can be drawn
Then
You need to redraw the image every frame.
In the function draw
, some place after the movement code, draw the image.
The draw
function should look something like
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (rightPressed) {
playerX += 5;
} else if (leftPressed) {
playerX -= 5;
}
if (downPressed) {
playerY += 5;
} else if (upPressed) {
playerY -= 5;
}
// make sure the image has loaded
if (image.hasLoaded === true) { // or just if (image.hasLoaded) {
ctx.drawImage(image, playerX, playerY, 75, 75); // draw the image onto the cleared canvas
} else {
ctx.strokeRect(playerX, playerY, 75, 75); // placeholder for image if not loaded yet
}
requestAnimationFrame(draw); // request next frame
}
And the last thing is that I can not see where you start the draw
function
As you are calling a function from HTML from a button labeled "play" then in the function it calls myFunction
change it so the its starts the animation by requesting the first frame.
The function myFunction
should look like.
function myFunction() {
document.getElementById('container').style.opacity = "0";
setTimeout(func2, 650);
requestAnimationFrame(draw); // start the draw loop
}
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.