2016-05-19 2 views
3

Я пытаюсь сделать игру в понг в холсте. Я решил, что начну с того, что мяч переместится через улицу. Проблема в том, что когда я зациклирую функцию draw, она превращается в линию, а не в шарик в каждой новой позиции. (Смотрите скриншот ниже.)JavaScript + холст Перемещение объекта

enter image description here

Я думал, очищая холст, а затем перерисовывая все бы решить эту проблему, но, по-видимому, нет.

Вот мой код:

HTML:

<!doctype html> 
<html lang="sv"> 
    <head> 
     <meta charset="utf-8" /> 
     <link rel="stylesheet" href="style.css"> 
     <title>Super Pong!</title> 
     <script type="text/javascript" src="superPong.js"></script> 
    </head> 

    <body> 
     <nav> 
      <ul id="navlist"> 
       <li><a href="#">Button 1</a></li> 
       <li><a href="#">Button 2</a></li> 
       <li><a href="#">Button 3</a></li> 
       <li><a href="#">Button 4</a></li> 
      </ul> 
     </nav> 
     <div id="content"> 
      <canvas width="1000" height="600">Your browser does not support HTML5 Canvas</canvas> 
     </div> 
    </body> 
</html> 

CSS:

body { 
    background-color: #E93D19; 
    color: #341711; 
    font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif; 
    font-size: 2vw; 
} 

#content { 
    text-align: center; 
    padding-top: 3%; 
} 

canvas { 
    background-color: white; 
} 

nav { 
    height: 100px; 
    width: 100%; 
    text-align: center; 
    font-size: 3vw; 
} 

#navlist { 
    background-color: #FD851D; 
    list-style-type: none; 
    margin: 0; 
    overflow: hidden; 
    padding: 0; 
    transform: translateY(10%); 
} 

#navlist li { 
    display: inline; 
} 

#navlist a { 
    color: #C91D09; 
    text-decoration: none; 
} 

#navlist a:hover { 
    background-color: #C91D09; 
    color: #FD851D; 
} 

JavaScript:

window.addEventListener("load", eventWindowLoaded, false); 

function eventWindowLoaded(){ 
    var canvas=document.querySelector("canvas"); 
    var ctx=canvas.getContext("2d"); 
    var canWidth=canvas.width; 
    var canHeight=canvas.height; 
    var pi=Math.PI; 
    var timer=null; 
    var ms=16; 

    var gameBall={ 
     size:30, 
     positionX:0, 
     positionY:0, 
     color:"#FFF", 

     set setSize(newSize){ 
      this.size=newSize; 
     }, 
     set setPosX(posX){ 
      this.positionX=posX; 
     }, 
     set setPosY(posY){ 
      this.positionY=posY; 
     }, 
     set setColor(newColor){ 
      this.color=newColor; 
     }, 
     get getSize(){ 
      return this.size; 
     }, 
     get getPosX(){ 
      return this.positionX; 
     }, 
     get getPosY(){ 
      return this.positionY; 
     }, 
     get getColor(){ 
      return this.color; 
     } 
    } 

    function clearCanvas(){ 
     ctx.clearRect(0,0,canWidth,canHeight); 
    } 

    function drawBackground(){ 
     ctx.fillStyle="#000"; 
     ctx.fillRect(0,0,canWidth,canHeight); 
    } 

    function drawBall(){ 
     ctx.save(); 
     var posX=gameBall.getPosX; 
     var posY=gameBall.getPosY; 
     var size=gameBall.getSize; 
     ctx.fillStyle=gameBall.getColor; 
     ctx.arc(posX,posY,size,0,2*pi,true); 
     ctx.fill(); 
     ctx.restore(); 
    } 

    function updateBall(){ 
     //clearCanvas(); 
     //drawBackground(); 
     gameBall.setPosX=gameBall.getPosX+3; 
     gameBall.setPosY=gameBall.getPosY+3; 
     drawBall(); 
    } 

    gameBall.setPosX=100; 
    gameBall.setPosY=100; 
    drawBackground(); 

    timer=setInterval(updateBall, ms); 
} 
+0

Я бы предложил очистить холст от каждого обновления, прежде чем рисовать новые позиции и т. Д. Я вижу, что у вас это есть в вашей функции «updateBall», но, похоже, он закомментирован. Правильно ли я говорю, что это не сработало? –

+0

Причина, по которой в настоящее время закомментирована, заключается в том, что я пытался использовать несколько различных решений (таких как «ctx.save() и ctx.restore()»). К сожалению, не работает. –

+1

Я создал скрипку (код немного обновлен, но проблема остается) http://jsfiddle.net/Q5HDu/288/ –

ответ

0

Ниже приводится рабочая версия вашего Fiddle. Это переработано для этих 2-х вопросов:

  • Ваших предыдущие шары остаются, потому что Canvas не позволяет репозиционирование существующих шариковых чертежей. .save & .восстановить команды просто сохранить & восстановить свойства контекста - они не сохраняют & восстанавливают рисунки на холсте. Вместо этого вы должны стереть холст и перерисовать мяч в новом положении. Итак, (1) drawBackground, (2) обновление & (3) drawBall в updateBall - это правильный способ «переместить» на холст.

  • Вы должны позвонить context.beginPath каждый раз, когда вы нарисуете свой context.arc (мяч). Если нет, вся предыдущая версия команды .arc будет перерисована.

function eventWindowLoaded(){ 
 
\t var canvas=document.querySelector("canvas"); 
 
\t var ctx=canvas.getContext("2d"); 
 
\t var canWidth=canvas.width; 
 
\t var canHeight=canvas.height; 
 
\t var pi=Math.PI; 
 
\t var timer=null; 
 
\t var ms=1000/60*1; 
 

 
\t var gameBall={ 
 
\t \t size:30, 
 
\t \t positionX:0, 
 
\t \t positionY:0, 
 
\t \t color:"#FFF", 
 

 
\t \t set setSize(newSize){ 
 
\t \t \t this.size=newSize; 
 
\t \t }, 
 
\t \t set setPosX(posX){ 
 
\t \t \t this.positionX=posX; 
 
\t \t }, 
 
\t \t set setPosY(posY){ 
 
\t \t \t this.positionY=posY; 
 
\t \t }, 
 
\t \t set setColor(newColor){ 
 
\t \t \t this.color=newColor; 
 
\t \t }, 
 
\t \t get getSize(){ 
 
\t \t \t return this.size; 
 
\t \t }, 
 
\t \t get getPosX(){ 
 
\t \t \t return this.positionX; 
 
\t \t }, 
 
\t \t get getPosY(){ 
 
\t \t \t return this.positionY; 
 
\t \t }, 
 
\t \t get getColor(){ 
 
\t \t \t return this.color; 
 
\t \t } 
 
\t } 
 

 
\t function clearCanvas(){ 
 
\t \t ctx.clearRect(0,0,canWidth,canHeight); 
 
\t } 
 

 
\t function drawBall(){ 
 
\t \t ctx.save(); 
 
\t \t var posX=gameBall.getPosX; 
 
\t \t var posY=gameBall.getPosY; 
 
\t \t var size=gameBall.getSize; 
 
\t \t ctx.fillStyle=gameBall.getColor; 
 
    ctx.beginPath(); 
 
\t \t ctx.arc(posX,posY,size,0,2*pi,true); 
 
\t \t ctx.fill(); 
 
\t \t ctx.restore(); 
 
\t } 
 

 
\t function updateBall(){ 
 
\t \t //clearCanvas(); 
 
\t \t gameBall.setPosX=gameBall.getPosX+3; 
 
\t \t gameBall.setPosY=gameBall.getPosY+3; 
 
    ctx.fillStyle='black'; 
 
    ctx.fillRect(0,0,canvas.width,canvas.height); 
 
\t \t drawBall(); 
 
\t } 
 

 
\t gameBall.setPosX=35; 
 
\t gameBall.setPosY=35; 
 

 
\t timer=setInterval(updateBall, ms); 
 
} 
 

 
eventWindowLoaded();
body { 
 
\t background-color: #E93D19; 
 
\t color: #341711; 
 
\t font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif; 
 
\t font-size: 2vw; 
 
} 
 

 
#content { 
 
\t text-align: center; 
 
\t padding-top: 3%; 
 
} 
 

 
canvas { 
 
\t background-color: black; 
 
} 
 

 
nav { 
 
\t height: 100px; 
 
\t width: 100%; 
 
\t text-align: center; 
 
\t font-size: 3vw; 
 
} 
 

 
#navlist { 
 
\t background-color: #FD851D; 
 
\t list-style-type: none; 
 
\t margin: 0; 
 
\t overflow: hidden; 
 
\t padding: 0; 
 
\t transform: translateY(10%); 
 
} 
 

 
#navlist li { 
 
\t display: inline; 
 
} 
 

 
#navlist a { 
 
\t color: #C91D09; 
 
\t text-decoration: none; 
 
} 
 

 
#navlist a:hover { 
 
\t background-color: #C91D09; 
 
\t color: #FD851D; 
 
}
<body> 
 
     <nav> 
 
      <ul id="navlist"> 
 
       <li><a href="#">Button 1</a></li> 
 
       <li><a href="#">Button 2</a></li> 
 
       <li><a href="#">Button 3</a></li> 
 
       <li><a href="#">Button 4</a></li> 
 
      </ul> 
 
     </nav> 
 
     <div id="content"> 
 
      <canvas width="600" height="400">Your browser does not support HTML5 Canvas</canvas> 
 
     </div> 
 
    </body>

0

Вы должны очистить холст каждый раз, когда вы перерисовать кадр.

При рисовании путей вам необходимо убедиться, что вы создаете новый путь для каждого кадра, а не , добавляя к текущему пути. Обычно это делается путем вызова ctx.beginPath(), чтобы очистить текущий путь контекста.

+0

Нужно ли мне также закрыть путь? Честно говоря, я не совсем уверен, что начинать/закрывать. –

+0

Нет, closePath просто создает линию между последней точкой и началом. Это может быть полезно для того, чтобы убедиться, что путь «опрятен». Вот пример: http://codepen.io/simonsarris/pen/dMBRaQ?editors = 1010 –

+0

На самом деле, вот лучший пример closePath: http://codepen.io/simonsarris/pen/QNXgoE?editors=0010 –