0

I coded an application that isn't entirely OOP. I was considering converting it to "real" OOP.

Right now, the code is structured by setting subfunctions as attributes to main functions.

Ex: Bullet.move.normal is a subfunction/dependency or Bullet.move.

This is how the code looks right now:

Bullet = function(x,y,angle,type){
    return {x:x,y:y,angle:angle,type:type};
}

Bullet.update = function(b){
    Bullet.move(b);
    Bullet.collision(b);
}

Bullet.move = function(b){
    if(b.type === 'normal') Bullet.move.normal(b);
    else if(b.type === 'sinus') Bullet.move.sinus(b);
}

Bullet.move.normal = function(b){
    b.x +=  Math.cos(b.angle);  b.y +=  Math.sin(b.angle);  //not important
}   
Bullet.move.sinus = function(b){
    b.x +=  Math.cos(b.x);  b.y +=  Math.sin(b.y); //not important
}   

Bullet.collision = function(b){
    Bullet.collision.wall(b);
    Bullet.collision.actor(b);
}

Bullet.collision.wall = function(b){} 
Bullet.collision.actor = function(b){}


---

I've started to write the OOP version of the code above but the structure I had doesn't work perfectly.

this parameter doesn't refer to the object if it's a "multilevel" function. (Check Bullet.prototype.move.normal)

What would be the recommended way to restructured the prototype without having to put all subfunctions in the main function? (Check 2nd Bullet.prototype.move)

Is there a solution other than just naming everything like Bullet.prototype.move_normal? I'd prefer to not have everything on the same "level".

And what would be the advantages of using OOP instead of what I had before? Is it worth converting to OOP?

Bullet = function(x,y,angle,type){
    this.x = x; 
    this.y = y;
    this.angle = angle;
    this.type = type;
}

Bullet.prototype.update = function(){
    this.move();
    this.collision();
}

Bullet.prototype.move = function(){
    if(this.type === 'normal') this.move.normal();
    else if(this.type === 'sinus') this.move.sinus();
}

Bullet.prototype.move.normal = function(){  
    //not working, this === Bullet.prototype.move, not the bullet
    this.x +=  Math.cos(this.angle);    //not important
    this.y +=  Math.sin(this.angle);    
}


Bullet.prototype.move = function(){ //I dont want this. I'd like to keep things separated.
    if(this.type === 'normal'){
        this.x +=  Math.cos(this.angle);
        this.y +=  Math.sin(this.angle);    
    }
    else if(this.type === 'sinus'){
        this.x +=  Math.cos(this.x);
        this.y +=  Math.sin(this.y);    
    }
}
3
  • 2
    You can't use multi-level hierarchy for your methods if you want to use the this pointer for the reason you discovered. All methods have to be only only one level down from the object or prototype. Simply change move.normal to moveNormal. Commented Jun 17, 2014 at 3:58
  • Is it the way people normally do things? Put all the functions and attributes on the same level? Commented Jun 17, 2014 at 4:08
  • 1
    Yes, that's the way people normally do things in javascript. For properties, there's no issue with going multiple levels. For methods, creating any extra levels creates this issue with the this pointer so methods on an object stay at one level. Commented Jun 17, 2014 at 4:52

1 Answer 1

1

Replace type code with subclasses would be a good starting point:

function extend(Parent, Child) {
    function Dummy () {}
    Dummy.prototype = Parent.prototype;
    Child.prototype = new Dummy();
    Child.prototype.constructor = Parent;
}

Bullet = function(x, y, angle, type){
    this.x = x;
    this.y = y;
    this.angle = angle;
    this.type = type;
};

Bullet.prototype.update = function(){
    this.move();
    this.collision();
};

Bullet.prototype.collision = function(b){
    this.collisionWall(b);
    this.collisionActor(b);
};

Bullet.prototype.collisionWall = function(b){};
Bullet.prototype.collisionActor = function(b){};

//NormalBullet
NormalBullet = function() {
    //Call parent constructor and pass all the arguments in.
    Bullet.apply(this, arguments);
};

//Set prototype inheritance.
extend(Bullet, NormalBullet);

//Move the bullet move logic into subclass.
NormalBullet.prototype.move = function() {
    this.x +=  Math.cos(this.angle);
    this.y +=  Math.sin(this.angle);
};

//SinusBullet
SinusBullet = function() {
    Bullet.apply(this, arguments);
};

extend(Bullet, SinusBullet);

SinusBullet.prototype.move = function() {
    this.x +=  Math.cos(this.x);
    this.y +=  Math.sin(this.y);
};

var sinusBullet = new SinusBullet(//your arguments);
sinusBullet.move();

var normalBullet = new NormalBullet(//your arguments);
normalBullet.move();

Source

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

3 Comments

I'm not really looking to subdivide the class. I only showed a basic example where subdividing would be easy but it wouldn't work with the actual application. How would you code the collision part with that structure btw?
@RainingChain just move Bullet.collision.wall and Bullet.collision.actor one level up.

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.