0

I am playing with html5 canvas to create bouncing balls. I have this all working but I have to call an initialise function to set certain properties. How can I do this automatically in the constructor without having the initializer firing when the properties are accessed?

var test1 = new Ball(20);
test1.setAngleAndVelocity(); //I dont want to have to call this.

function Ball(speed){
    this.position = new Vector2(canvas.width / 2, canvas.height / 2);
    this.velocity;
    this.speed = speed;
    this.angle;
    this.setAngleAndVelocity = function(){
        this.angle = Math.floor(Math.random() * 360) * 0.0174532925;
        this.velocity = new Vector2(this.speed/10 * Math.cos(this.angle), this.speed/10 * Math.sin(this.angle));
    }
}

2 Answers 2

4

Since setAngleAndVelocity() is a static method, I'd recommend putting it in the prototype of your Ball class:

function Ball(speed){
    this.position = new Vector2(canvas.width / 2, canvas.height / 2);
    this.speed = speed;
    this.setAngleAndVelocity(); //Sets the additional values
}
Ball.prototype.setAngleAndVelocity = function(speed){
    speed = typeof speed != "undefined" ? speed : this.speed;
    this.angle = Math.floor(Math.random() * 360) * 0.0174532925;
    this.velocity = new Vector2(speed/10 * Math.cos(this.angle), speed/10 * Math.sin(this.angle));
}

this.velocity; and this.angle; aren't necessary: They're not defining anything, and the only use they serve is to show the developer what properties may be defined.

After these modifications, your script has become more efficient, and can be used in this way:

var test1 = new Ball(20); //Inititalized
test1.setAngleAndVelocity(22); //Optional, a method to adjust the speed value after the init of the class.
Sign up to request clarification or add additional context in comments.

3 Comments

@skyfoot See the last line of my answer. That part is optional to add, but can (later) be used to change the speed property of the initialised Ball class without creating a new instance.
nice and clean solution I was looking for as the next step was to update the velocity and I wanted to use the same function.
Note that this class cannot be called without the new keyword, because an ordinary function call will just return the return value, or undefined, rather than an instance of the "class". Another method to initialize the class: var test1 = new Ball; test1.setAngleAndVelocity(20);
1

Just inline that computation into the constructor.

function Ball(speed){
    this.position = new Vector2(canvas.width / 2, canvas.height / 2);
    this.speed = speed;
    this.angle = Math.floor(Math.random() * 360) * 0.0174532925;
    this.velocity = new Vector2(this.speed/10 * Math.cos(this.angle), this.speed/10 * Math.sin(this.angle));
}

ADDENDUM

If you want to keep the function around to update the angle and velocity at other times in your application, place that function in the prototype:

Ball.prototype.changeSpeed = function (newSpeed) {
    this.speed = newSpeed;
    this.velocity = new Vector2(this.speed/10 * Math.cos(this.angle), this.speed/10 * Math.sin(this.angle));
}

You can call this method from the constructor if you wish:

function Ball(speed){
    this.position = new Vector2(canvas.width / 2, canvas.height / 2);
    this.angle = Math.floor(Math.random() * 360) * 0.0174532925;
    this.changeSpeed(speed);
}

See http://jsfiddle.net/FnHLX/ for a working example.

You can also write a similar function for angle changes.

2 Comments

Regarding your addendum, How do I call changeSpeed in the constructor. I wont want to have the code duplicated.
@skyfoot, yes of course you don't want to duplicate that code! You can call from the constructor. I've made a fiddle jsfiddle.net/FnHLX and will update the answer right away. Good eye!!

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.