【问题标题】:I'm trying to make an arrow key movement system and its not working. does anyone know what is wrong with my code?我正在尝试制作箭头键移动系统,但它不起作用。有人知道我的代码有什么问题吗?
【发布时间】:2020-10-23 14:50:56
【问题描述】:

我正在尝试使用 HTML5 画布和 node.js 制作一个 .io 游戏,但我不知道如何让玩家使用箭头键移动。我一直在尝试使用本教程来制作运动系统,并且我一直在摆弄它好几天,但我似乎无法让它移动。

播放器是保存为 .png 文件的图像。它出现在画布上,但没有移动。

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>

找出它为什么不动。

【问题讨论】:

    标签: javascript html html5-canvas 2d-games arrow-keys


    【解决方案1】:

    将加载时的图像更改为

    image.addEventListener("load", () => image.hasLoaded = true , {once: true});
    

    您只需要知道图像已加载,因此上述侦听器只需将属性hasLoaded 添加到图像中,如果可以绘制,您可以在draw 中签入

    然后

    您需要每帧重绘图像。

    在函数draw中,运动代码后的某处,绘制图像。

    draw 函数应该类似于

    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
    }
    

    最后一件事是我看不到你从哪里开始 draw 函数

    当您从标记为“播放”的按钮从 HTML 调用函数时,然后在调用myFunction 的函数中更改它,以便它通过请求第一帧来启动动画。

    函数myFunction 应该是这样的。

    function myFunction() {
        document.getElementById('container').style.opacity = "0";
        setTimeout(func2, 650);
        requestAnimationFrame(draw); // start the draw loop
    }
    

    【讨论】:

    • 非常感谢您的帮助,它成功了!对此,我真的非常感激。老实说,我正处于放弃的边缘。
    猜你喜欢
    • 2015-12-23
    • 1970-01-01
    • 2022-11-28
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2022-01-08
    相关资源
    最近更新 更多