2016-05-19 1 views
3

Ich versuche ein Pong-Spiel in Canvas zu machen. Ich dachte, ich würde damit beginnen, den Ball über die Straße zu bewegen. Das Problem ist, wenn ich die Draw-Funktion in eine Schleife verwandle, anstatt in einen Ball an jeder neuen Position. (Siehe Abbildung unten.)JavaScript + Canvas Moving Object

enter image description here

Ich dachte, die Leinwand Clearing- und dann wieder zeichnet alles würde das Problem lösen, aber anscheinend nicht.

Hier ist mein Code:

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

Ich hätte vorgeschlagen, die Zeichenfläche bei jedem Update zu löschen, bevor neue Positionen gezeichnet werden usw. Ich sehe, dass Sie das in Ihrer 'updateBall' Funktion haben, aber es scheint auskommentiert zu sein. Habe ich recht, wenn ich sage, dass es nicht funktioniert hat? –

+0

Der Grund, warum es momentan auskommentiert ist, dass ich ein paar verschiedene Lösungen versuchte (wie "ctx.save() und ctx.restore()"). Leider funktioniert das nicht. –

+1

Ich habe eine Geige (der Code ist leicht aktualisiert, aber das Problem bleibt) http://jsfiddle.net/Q5HDu/288/ –

Antwort

0

Nachfolgend finden Sie eine Arbeitsversion Ihres Fiddle. Es ist für diese 2 Ausgaben Refactoring:

  • Ihre vor Kugeln verbleibenden weil Leinwand nicht Neupositionierung bestehender Ball Zeichnungen ermöglichen. Die .save & .restore Befehle speichern nur & Wiederherstellen der Kontexteigenschaften - sie speichern nicht & Zeichnungen auf der Leinwand wiederherstellen. Stattdessen müssen Sie die Leinwand löschen und den Ball an seiner neuen Position neu zeichnen. So (1) drawBackground, (2) update & (3) drawBall in updateBall ist eine geeignete Methode, um im Canvas zu "bewegen".

  • Sie müssen context.beginPath jedes Mal aufrufen, wenn Sie Ihre context.arc (Ball) zeichnen. Wenn nicht, werden alle früheren Versionen des Befehls .arc neu gezeichnet.

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

Sie müssen die Leinwand löschen jedes Mal, wenn Sie einen Rahmen neu zu zeichnen.

Beim Zeichnen von Pfaden müssen Sie sicherstellen, dass Sie für jeden Rahmen einen neuen Pfad erstellen und nicht dem aktuellen Pfad hinzufügen. Dies geschieht normalerweise durch Aufruf von ctx.beginPath(), um den aktuellen Pfad des Kontexts zu löschen.

+0

Muss ich den Pfad auch schließen? Ich bin mir nicht ganz sicher, was begin/closePath tut, um ehrlich zu sein. –

+0

Nein, closePath erstellt einfach eine Linie zwischen dem letzten Punkt und dem Anfang. Es kann nützlich sein, um sicherzustellen, dass ein Pfad "ordentlich" ist. Hier ist ein Beispiel: http://codepen.io/simonsarris/pen/dMBRaQ?Editoren = 1010 –

+0

Eigentlich ist hier ein besseres Beispiel für closePath: http://codepen.io/simonsarris/pen/QNXgoE?editors=0010 –