Driky
Driky

Reputation: 297

Game object become undefined Typescript/Three.js

The code bellow was working fine and suddenly it is not. I probably changed something without realising it.

Still I can't find why the "Game" object is fine before the call to this.render() at the end of the constructor. And become undefined in the render method.

To be more precise when I log the object in the console it give me this before render()

Game camera: Ea renderer: Dd scene: jb __proto__: Object

And this after render()

Game camera: Ea renderer: Dd scene: jb __proto__: Object :3000/game.js:38 undefined

Any suggestion is welcomed.

///<reference path="../typings/index.d.ts"/>
import config from './config';
import * as THREE from 'three'; 

export default class Game {

    private renderer: THREE.Renderer;
    private camera: THREE.PerspectiveCamera;
    private scene: THREE.Scene;

    constructor() {
        console.log('START');
        //var self = this;

        let container = document.querySelector(config.domSelector);
        this.renderer = new THREE.WebGLRenderer();
        this.renderer.setSize(config.rendererW, config.rendererH);
        container.appendChild(this.renderer.domElement);
        console.log('renderer added');

        this.camera = new THREE.PerspectiveCamera(config.cameraViewAngle, (config.rendererW/config.rendererH), config.cameraNear, config.cameraFar);
        this.scene = new THREE.Scene();
        this.scene.add(this.camera);
        console.log('scene initialized');

        /*window.addEventListener('resize', function(){
            self.rendererResize
        });*/

        //mesh
        let sphereMaterial:THREE.MeshLambertMaterial = new THREE.MeshLambertMaterial({color: 0xCC0000})
        let sphere:THREE.Mesh = new THREE.Mesh(
            new THREE.SphereGeometry( 50, 16, 16), sphereMaterial
        );
        sphere.position.z = -300;
        this.scene.add(sphere);
        console.log('sphere added');

        //light
        let pointLight:THREE.PointLight = new THREE.PointLight(0xFFFFFF);
        pointLight.position.x = 10;
        pointLight.position.y = 50;
        pointLight.position.z = 130;
        this.scene.add(pointLight);
        console.log('light added');
        // Schedule the first frame.
        this.render();
    }

    private render(){
        this.renderer.render(this.scene, this.camera);
        requestAnimationFrame(this.render);
    }

    /*private rendererResize():void{
        let width:number = window.innerWidth;
        let height:number = window.innerHeight;
        console.log("height = ",height);
        console.log("width = ",width);

        this.renderer.setSize(width, height);
        this.camera.aspect = width / height;
        this.camera.updateProjectionMatrix();
    }*/


}

The generated javascript

define(["require", "exports", "./config", "three"], function (require, exports, config_1, THREE) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var Game = (function () {
        function Game() {
            console.log('START');
            //var self = this;
            var container = document.querySelector(config_1.default.domSelector);
            this.renderer = new THREE.WebGLRenderer();
            this.renderer.setSize(config_1.default.rendererW, config_1.default.rendererH);
            container.appendChild(this.renderer.domElement);
            console.log('renderer added');
            this.camera = new THREE.PerspectiveCamera(config_1.default.cameraViewAngle, (config_1.default.rendererW / config_1.default.rendererH), config_1.default.cameraNear, config_1.default.cameraFar);
            this.scene = new THREE.Scene();
            this.scene.add(this.camera);
            console.log('scene initialized');
            /*window.addEventListener('resize', function(){
                self.rendererResize
            });*/
            //mesh
            var sphereMaterial = new THREE.MeshLambertMaterial({ color: 0xCC0000 });
            var sphere = new THREE.Mesh(new THREE.SphereGeometry(50, 16, 16), sphereMaterial);
            sphere.position.z = -300;
            this.scene.add(sphere);
            console.log('sphere added');
            //light
            var pointLight = new THREE.PointLight(0xFFFFFF);
            pointLight.position.x = 10;
            pointLight.position.y = 50;
            pointLight.position.z = 130;
            this.scene.add(pointLight);
            console.log('light added');
            console.log(this);
            // Schedule the first frame.
            this.render();
        }
        Game.prototype.render = function () {
            console.log(this);
            this.renderer.render(this.scene, this.camera);
            requestAnimationFrame(this.render);
        };
        return Game;
    }());
    exports.default = Game;
});
//# sourceMappingURL=/game.js.map

Upvotes: 1

Views: 317

Answers (1)

Driky
Driky

Reputation: 297

Ok so i found the problem:

When doing

requestAnimationFrame(this.render);

that scope to window (requestAnimationFrame is part of window). So I need to either do :

requestAnimationFrame(this.render.bind(this));

or change the render function for :

private render = ():void => {
       console.log("Render function start")
       this.renderer.render(this.scene, this.camera);
       requestAnimationFrame(this.render);
}

Burn in hell scope !

Upvotes: 1

Related Questions