简体   繁体   中英

JavaScript + Canvas Moving Object

I'm trying to make a pong-game in Canvas. I figured I would start by making the ball move across the street. The problem is when I loop the draw-function it turns into a line, instead of a ball at each new position. (See screenshot below.)

在此输入图像描述

I thought clearing the canvas and then re-drawing everything would solve the problem, but apparently not.

Here is my 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);
}

Below is a working version of your Fiddle. It's refactored for these 2 issues:

  • Your prior balls are remaining because Canvas does not allow repositioning of existing ball drawings. The .save & .restore commands just save & restore the context properties -- they do not save & restore drawings on the canvas. Instead, you must erase the canvas and redraw the ball in its new position. So (1) drawBackground, (2) update & (3) drawBall in updateBall is a proper way of "moving" on canvas.

  • You must call context.beginPath each time you draw your context.arc (ball). If not, all previous version of the .arc command will be redrawn.

 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=1000/60*1; 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 drawBall(){ ctx.save(); var posX=gameBall.getPosX; var posY=gameBall.getPosY; var size=gameBall.getSize; ctx.fillStyle=gameBall.getColor; ctx.beginPath(); ctx.arc(posX,posY,size,0,2*pi,true); ctx.fill(); ctx.restore(); } function updateBall(){ //clearCanvas(); gameBall.setPosX=gameBall.getPosX+3; gameBall.setPosY=gameBall.getPosY+3; ctx.fillStyle='black'; ctx.fillRect(0,0,canvas.width,canvas.height); drawBall(); } gameBall.setPosX=35; gameBall.setPosY=35; timer=setInterval(updateBall, ms); } eventWindowLoaded(); 
 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: black; } 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; } 
 <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> 

You need to clear the canvas every time you redraw a frame.

When drawing paths, you need to make sure that you are creating a new path each frame, and not adding on to the current path . This is usually done by calling ctx.beginPath() to clear out the context's current path.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM