简体   繁体   中英

Object Oriented Bouncing Ball

So it has been a good long while since I programmed in a functional language. I have this code functioning normally; however I dislike it due to my OOD preferences.

var canvasWidth = 900;
var canvasHeight = 200;

var canvas0;
var context0;
var x0 = 20;
var y0 = 20;
var dx0 = 4;
var dy0 = 4;

function draw() {
    context0.clearRect(0, 0, context0.canvas.width, context0.canvas.height);
    context0.beginPath();
    context0.fillStyle = "red";
    context0.arc(x0, y0, 20, 0, 2 * Math.PI, true);
    context0.closePath();
    context0.fill();

    // Boundary Logic
    if (x0 < 13 || x0 > context0.canvas.width - 13) {
        dx0 = (-dx0);
    }
    if (y0 < 13 || y0 > context0.canvas.height - 13) {
        dy0 = (-dy0);
    }
    x0 += dx0;
    y0 += dy0;
}

function init() {
    'use strict';
    canvas0 = document.getElementById("gfxCanvas");
    context0 =  canvas0.getContext('2d');
    context0.canvas.width  = canvasWidth;
    context0.canvas.height = canvasHeight;
    setInterval(draw, 10);
}

I have tried to refactor it into more object oriented design but I am having problems with the graphics processing. I can get the ball to appear once but I can not get it to move. Here is my refactored code; be aware that it is in a mid point of refactoring so there are some clear errors due to random tinkering.

function Ball(x, y, r, color) {
    this.radius = r;
    this.x = x;
    this.y = y;  
    this.color = color;
    console.log("x in creation" + this.x);
    console.log("y in creation" + this.y);
    draw();

}
Ball.prototype.draw = function(){
    context1.beginPath();
    console.log("x in DRAW()" + this.x);
    console.log("y in DRAW()" + this.y);
    context1.fillStyle = this.color;
    context1.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, true);
    context1.closePath();
    context1.fill();
};

Ball.prototype.move = function(dx, dy){
    // Boundary Logic
    if (this.x < 13 || this.x > context1.canvas.width - 13) {
        dx = (-dx);
    }
    if (this.y < 13 || this.y > context1.canvas.height - 13) {
        dy = (-dy);
    }

    this.x += dx;
    this.y += dy;

};

function initialize() {
    canvas1 = document.getElementById("gfxCanvas2");
    context1 =  canvas1.getContext('2d');
    context1.canvas.width  = 900;
    context1.canvas.height = 200;
    ball1 = new Ball(20,20,20, "red");
    setInterval(ball1.move(4,4), 10);
}

I would preferably like this method to be the movement method. The actual method would take the direction/speed vectors.

setInterval(ball1.move(4,4), 10);

setInterval(ball1.move(4,4), 10);

This doesn't work the way you intended it: It calls ball1.move(4,4) once, then calls the result of that every 10ms. You want the move method to be called every 10ms instead, right? There are two ways to do that:

setInterval(function() {
  ball1.move(4,4);
}, 10);

or like this (more elegant in my opinion):

setInterval(ball1.move.bind(ball1,4,4), 10);

You can use bind :

setInterval(ball1.move.bind(ball1, 4, 4), 10);

That is equivalent of wrapping your call to move in an anonymous function:

setInterval(function() { ball1.move(4, 4); }, 10);

Then you will also need to update move so that it calls draw appropriately too.

In addition, I would not use a global variable to access the drawing context - even if I wasn't going to go completely OOP I would make sure that the draw method and the move method take a context (which, for the sake of simplicity could be "owned" by the ball).

Thanks for all the help, everyone. You clarified everything very well and pointed me in the correct direction. I suspected it was working in the manner you articulated however I wasn't entirely sure. I knew a couple of things where wrong with my implementation but couldn't put it so succinctly with my current knowledge.

However, I discovered my problem which your solutions were remedying in a more direct manner. I can't treat javascript with OOD paradigms. I will be refactoring the code using a more functional design pattern. Not attempting to coerce the code into a OO design will make things considerably easier. Your solutions helped but the bounds checking code was the next problem I ran into.

I'l be working this into a module design pattern for the ball objects which should be much more suited for js scope/closures and procedural workflow.

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