1

I have looked through many other answers of this question unable to find an answer.

The issue seems to be that it isn't recognizing the World global in my game.js file.

The html file is ordered properly

<script src="js/world.js"></script>
<script src="js/game.js"></script>

IN world.js -- This constructor should work seeing as it is similiar to my other construcotrs

var World = function(){

    var draw = function(ctx) {
        ctx.drawImage(bg1, 100, 100);
    };
}; 

IN game.js -- The culprit is likely here

Note that neither of these two functions below are nested in anything:

var World;

function init() {
    // Declare the canvas and rendering context
    canvas = document.getElementById("gameCanvas");
    ctx = canvas.getContext("2d");
    localPlayer = new Player(startX, startY); //WORKS CORRECTLY
    World = new World(); //SHOULD ALSO WORK CORRECTLY

......................

outside of the init function is

function draw() {
    // Wipe the canvas clean
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    World.draw(ctx);
    // Draw the local player

    // Draw the remote players
    var i;
    for (i = 0; i < remotePlayers.length; i++) {
        remotePlayers[i].draw(ctx);
    };
    localPlayer.draw(ctx);
};

At World.draw(ctx) is where I am getting the error

Uncaught TypeError: Object [object Object] has no method 'draw' game.js:202 draw

If you need any more details I'd be happy to oblige. I would have posted all of my code except that it is pretty big.

Adi Inbar
  • 12,097
  • 13
  • 56
  • 69
bezzoon
  • 1,755
  • 4
  • 24
  • 52
  • Looks like the `draw()` function is called before `init()`? – Bergi Sep 16 '13 at 23:15
  • Notice that your `World` constructor does not expose a `draw` method (property) on the returned instance, but just has some private variable of that name. See [Javascript: Do I need to put this.var for every variable in an object?](http://stackoverflow.com/questions/13418669/javascript-do-i-need-to-put-this-var-for-every-variable-in-an-object). And you should not assign the `World` instance to the `World` variable, overwriting your constructor function. – Bergi Sep 16 '13 at 23:16

2 Answers2

0

If you are using draw() as a instance method you should define it as:

var World = function(){

    this.draw = function(ctx) {
        ctx.drawImage(bg1, 100, 100);
    };

}; 

The this keyword allows the function to be referred to outside of the World object.

Using var limits the visibility to the inside of the function World's scope.

thgaskell
  • 12,772
  • 5
  • 32
  • 38
0

If you need multiple instances of World, then you will need to make your constructor export the function as a property (on this) - see Javascript: Do I need to put this.var for every variable in an object? for the difference to a private variable. And don't write your instance to the same variable as the constructor then.

function World(){
    this.draw = function(ctx) {
        ctx.drawImage(bg1, 100, 100);
    };
}

var world, ctx;
function init() {
    // Declare the canvas and rendering context
    var canvas = document.getElementById("gameCanvas");
    ctx = canvas.getContext("2d");

    world = new World(ctx);

    …
}

function draw() {

    world.draw(ctx);

    …
}

If you however only need a static module (singleton), forget about initialisation and just use an object literal which you assign to World which acts then as a namespace. This is what @fahadash suggested:

World = {
    draw: function(ctx) {
        ctx.drawImage(bg1, 100, 100);
    }
};

var ctx;
function init() {
    // Declare the canvas and rendering context
    var canvas = document.getElementById("gameCanvas");
    ctx = canvas.getContext("2d");

    // no World initialisation here! Do not try to call `new World`!

    …
}

function draw() {

    World.draw(ctx);

    …
}
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375