что это за странное поведение с помощьюEaslJS?

я совсем новичок в javascript и easylJS/createJS, но я думаю, что понимаю их достаточно, чтобы выполнить простую задачу. Я начал экспериментировать с холстом и застрял на одном месте.

В этом маленьком проекте используются Canvas и EaslJS для рендеринга простого шаттла с двумя двигателями и простая физика для его перемещения. (псевдо)Физика работает нормально: для обоих движков выполняются отдельные действия, но рендеринг не проходит. всякий раз, когда я включаю двигатель (клавиши «q» или «w»), загораются оба двигателя.

Я попытался найти простейшее подмножество этого кода, чтобы воспроизвести эту проблему, но мне это не удалось, поэтому я предоставляю весь код этого простого проекта.

<!DOCTYPE HTML>
<html>
<head>
<title></title>

<style>
    /*#myCanvas{
        width: 1200px;
        height: 600px;
    }*/
</style>

<script src="createjs-2013.12.12.min.js"></script>
<script>


/* Keyboard */
var Key = {
    _pressed: {},

    /*LEFT: 37,
    UP: 38,
    RIGHT: 39,
    DOWN: 40,*/
    Q: 81, W: 87, E: 69, R:82, T:84, Y: 89,


    isDown: function(keyCode) {
        return this._pressed[keyCode];
    },

    onKeydown: function(event) {
        this._pressed[event.keyCode] = true;
    },

    onKeyup: function(event) {
        delete this._pressed[event.keyCode];
    },

    getThrottles: function () {
        var resObj = {};
        for(var code in this._pressed){
            resObj[String.fromCharCode(code)] = 1;
        }
        return resObj;
    }
};

/* Vector2 */
function Vector2 (x, y, dx, dy){
    this.x = x ? x : 0;
    this.y = y ? y : 0;
    this.dx = dx ? dx : 0;
    this.dy = dy ? dy : 0;
}

/* Physics */
var Physics = {
    objects: [],

    update: function(){
        for(ind in this.objects){
            var obj = this.objects[ind];

            for(ind2 in obj.forces){
                var f = obj.forces[ind2];


                // velocities calculations
                if(f.x == obj.x && f.y == obj.y){
                    obj.velocity.dx += f.dx/obj.mass;
                    obj.velocity.dy += f.dy/obj.mass;
                }
                else{
                    var len = Math.sqrt((f.x-obj.x)*(f.x-obj.x) + (f.y-obj.y)*(f.y-obj.y));
                    var fpar = new Vector2(0, 0, (obj.x-f.x)/len, (obj.y-f.y)/len);
                    var fper = new Vector2(0, 0, (obj.y-f.y)/len, -(obj.x-f.x)/len);
                    var factorpar = f.dx*fpar.dx + f.dy*fpar.dy;
                    var factorper = f.dx*fper.dx + f.dy*fper.dy;

                    obj.velocity.dx += f.dx/obj.mass;
                    obj.velocity.dy += f.dy/obj.mass;

                    // TODO: here radius should be considered in equation
                    obj.avelocity += factorper/obj.imoment;

                }


            }

            obj.forces.length = 0;

            // rotations and translations
            obj.x += obj.velocity.dx;
            obj.y += obj.velocity.dy;
            obj.rotation += obj.avelocity;

            // dumping
            var dumping = 0.95;
            var adumping = 0.95;
            var minvel = 0.0001;
            var minavel = 0.0001;

            obj.velocity.dx = dumping * obj.velocity.dx;
            obj.velocity.dy = dumping * obj.velocity.dy;
            obj.avelocity = adumping * obj.avelocity;

        }

    }

};



var myStage;

createjs.DisplayObject.prototype.mass =0.5;
createjs.DisplayObject.prototype.imoment = 0.1;
createjs.DisplayObject.prototype.forces = [];
createjs.DisplayObject.prototype.velocity = new Vector2();
createjs.DisplayObject.prototype.avelocity = 0;

function Engine(width, height){
    var that = this;
    this.width = width;
    this.height = height;
    this.innerThrottle = 0;

    this.throttle = function(value){
        if(value!==null)
            that.innerThrottle = value;

        that.flame.graphics.clear();
        that.flame.graphics.beginFill("#ff0000").drawRoundRect(
                        -that.width*that.innerThrottle/2,
                        that.height+that.margin,
                        that.width*that.innerThrottle,
                        that.width*that.innerThrottle,
                that.margin);

        return that.innerThrottle;
    };



    //drawing
    this.margin = 0.1 * this.width;
    this.body = new createjs.Shape();
    this.body.graphics.beginFill("#999999").drawRect(-this.width/2, 0, this.width, this.height);
    this.addChild(this.body);

    this.flame = new createjs.Shape();
    this.flame.graphics.beginFill("#ff0000").drawRoundRect(
                    -this.width*this.throttle()/2,
                    this.height+this.margin,
                    this.width*this.throttle(),
                    this.width*this.throttle(),
            this.margin);
    this.addChild(this.flame);
}
Engine.prototype = new createjs.Container();

function Shuttle(radius){
    var that = this;
    this.engineNames = ['Q','W','E','R','T','Y'];
    this.engines = {};
    this.addEngine = function (x,y,rotation){
        var tmpEn = new Engine(radius/2, radius/1);
        tmpEn.x = x;
        tmpEn.y = y;
        tmpEn.rotation = rotation;
        that.addChild(tmpEn);

        that.engines[that.engineNames[Object.keys(that.engines).length]] = tmpEn;
    };

    this.steering = null;

    this.shuttleTick = function(){
        var throttles = that.steering.getThrottles();
        var engines = that.engines;

        for(var key in engines)
            engines[key].throttle(0);

        for(var key2 in throttles){
            if(engines[key2]){
                engines[key2].throttle(throttles[key2]);

                var end = engines[key2].localToGlobal(0,-0.1);
                var start = engines[key2].localToGlobal(0,0);

                that.forces.push(new Vector2(start.x, start.y, (end.x-start.x)*throttles[key2], (end.y-start.y)*throttles[key2]));
            }
        }


    };



    // drawing
    var core = new createjs.Shape();
    core.graphics.beginFill("#000000").drawCircle(0,0,radius);
    this.addChild(core);
}
Shuttle.prototype = new createjs.Container();

var shuttle;
function init(){

    // Key object initialization
    window.addEventListener('keyup', function(event) { Key.onKeyup(event); }, false);
    window.addEventListener('keydown', function(event) { Key.onKeydown(event); }, false);


    myStage = new createjs.Stage("myCanvas");

    //var engine = new Engine(200,300);
    var r = 10;
    shuttle = new Shuttle(r);
    shuttle.steering = Key;
    shuttle.addEngine(-r,0,0);
    shuttle.addEngine(r,0,0);
    shuttle.x = 500;
    shuttle.y = 200;
    //shuttle.velocity.dx = 1;
    //shuttle.avelocity = 1;

    myStage.addChild(shuttle);

    Physics.objects = [shuttle];

    createjs.Ticker.setFPS(60);
    createjs.Ticker.addEventListener('tick', tick);

}

function tick(){
    shuttle.shuttleTick();
    Physics.update();
    myStage.update();
}
</script>


</head>
<body onload="init()">
<canvas id="myCanvas" width="1200" height="600">

</canvas>
</body>
</html>

person Przemek B    schedule 04.05.2014    source источник


Ответы (1)


Ваша конкретная проблема заключается в том, что вы расширяете класс Container, но не инициализируете его при создании экземпляров Engine. Если вы вставите это в начало функции Engine(width, height), это должно работать:

this.initialize();

Однако в более общем плане вам, вероятно, следует изучить, как работает прототипное наследование Javascript - ваш код довольно сложно читать и излишне сложен.

Существует множество различных методов реализации «классических» шаблонов наследования ООП в JS, но, поскольку вы работаете с CreateJS, наиболее полезным подходом в вашем случае, вероятно, будет сначала изучить их метод, настроить свои классы, чтобы они следовали одному и тому же шаблону, и работать с там - см. например этот вопрос.

person d0gb3r7    schedule 06.05.2014