0

I am trying to create a game with javascript but it doesn't works. In the developers tools the error is the following: "Uncaught TypeError: Cannot read property 'x' of undefined". So I suppose the error involve the nested array "circles".

This is the code:

<!DOCTYPE html>
<html>
<head>
    <title>Canvas Tutorial</title>
    <script type="text/javascript">
        window.onload = draw;



        var circles = [{x:200,y:150,r:40,direction:1,speedX:1,speedY:2},{x:200,y:150,r:70,direction:1,speedX:2,speedY:1}];



        for (var i=0; i<circles.length; i++) {

            function bottomRight() {
                circles[i].x += circles[i].speedX;
                circles[i].y += circles[i].speedY;
            }

            function upLeft() {
                circles[i].x -= circles[i].speedX;
                circles[i].y -= circles[i].speedY;
            }

            function upRight() {
                circles[i].x += circles[i].speedX;
                circles[i].y -= circles[i].speedY;

            }

            function bottomLeft() {
                circles[i].x -= circles[i].speedX;
                circles[i].y += circles[i].speedY;
            }

            function draw() {


                var canvas = document.getElementById("canvas");
                var ctx = canvas.getContext("2d");

                ctx.fillStyle = "black";
                ctx.fillRect(0,0,400,300);
                ctx.fillStyle = "yellow";
                ctx.beginPath();
                ctx.arc(circles[i].x,circles[i].y,circles[i].r,0,Math.PI*2,false);
                ctx.fill();

                if((circles[i].y > 300 - circles[i].r) && circles[i].direction ===1){
                    circles[i].direction = 2;
                } else if((circles[i].x > 400 - circles[i].r) && (circles[i].direction===2)) {
                    circles[i].direction = 3;
                } else if ((circles[i].y > 300 - circles[i].r) && (circles[i].direction===4)) {
                    circles[i].direction = 3;
                } else if ((circles[i].y <= circles[i].r) && circles[i].direction === 3) {
                    circles[i].direction = 4;
                } else if ((circles[i].x < circles[i].r) && circles[i].direction === 4){
                    circles[i].direction = 1;
                } else if ((circles[i].y < circles[i].r) && circles[i].direction === 2) {
                    circles[i].direction = 1;
                }

                if (circles[i].direction === 1) {
                    bottomRight();
                } else if (circles[i].direction === 2) {
                    upRight();
                } else if (circles[i].direction === 3) {
                    upLeft();
                } else {
                    bottomLeft();
                }

            }



                setTimeout(draw, 10);
            }


    </script>
</head>
<body>
    <canvas id="canvas" width="400" height="300"></canvas>

</body>
</html>

How can I fix the code?

2
  • next to the error in the console, there should be a file name and a line number that would point you to the exact error location Commented Oct 26, 2016 at 9:26
  • please move the function definitions outside of the loop. Commented Oct 26, 2016 at 9:28

2 Answers 2

2

This is kind of attempt of a working version without optimizing.

I moved the function outside of the loop and the direction function inside of draw.

function draw() {

    function bottomRight() {
        circles[i].x += circles[i].speedX;
        circles[i].y += circles[i].speedY;
    }

    function upLeft() {
        circles[i].x -= circles[i].speedX;
        circles[i].y -= circles[i].speedY;
    }

    function upRight() {
        circles[i].x += circles[i].speedX;
        circles[i].y -= circles[i].speedY;
    }

    function bottomLeft() {
        circles[i].x -= circles[i].speedX;
        circles[i].y += circles[i].speedY;
    }

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");

    ctx.fillStyle = "black";
    ctx.fillRect(0, 0, 400, 300);
    ctx.fillStyle = "yellow";
    ctx.beginPath();
    for (var i = 0; i < circles.length; i++) {
        ctx.arc(circles[i].x, circles[i].y, circles[i].r, 0, Math.PI * 2, false);
        ctx.fill();

        if ((circles[i].y > 300 - circles[i].r) && circles[i].direction === 1) {
            circles[i].direction = 2;
        } else if ((circles[i].x > 400 - circles[i].r) && (circles[i].direction === 2)) {
            circles[i].direction = 3;
        } else if ((circles[i].y > 300 - circles[i].r) && (circles[i].direction === 4)) {
            circles[i].direction = 3;
        } else if ((circles[i].y <= circles[i].r) && circles[i].direction === 3) {
            circles[i].direction = 4;
        } else if ((circles[i].x < circles[i].r) && circles[i].direction === 4) {
            circles[i].direction = 1;
        } else if ((circles[i].y < circles[i].r) && circles[i].direction === 2) {
            circles[i].direction = 1;
        }

        if (circles[i].direction === 1) {
            bottomRight();
        } else if (circles[i].direction === 2) {
            upRight();
        } else if (circles[i].direction === 3) {
            upLeft();
        } else {
            bottomLeft();
        }
    }
}

var circles = [{ x: 200, y: 150, r: 40, direction: 1, speedX: 1, speedY: 2 }, { x: 200, y: 150, r: 70, direction: 1, speedX: 2, speedY: 1 }];

setTimeout(draw, 10);
<canvas id="canvas" width="400" height="300"></canvas>

Sign up to request clarification or add additional context in comments.

Comments

0

Firstly, as Nina Scholz said, you should declare draw() outside the loop.

If you want to see why you have an issue here, you can use console.log() to see what happens. Sample output :

Circles.length : 2
I in loop : 0
I in loop : 1
I in draw : 2

So as you can see, when you enter the draw() function, I = 2.

SOLUTION

  • Move the Draw function outside the loop.
  • Don't use setTimeout, or pass a parameter.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.