创建一个 class 的 Crafty JS 实体(class 的 class?)

Creating a class of Crafty JS entity (class of a class?)

我正在尝试创建一个 class,它会创建一个具有特定属性的 Crafty 实体。到目前为止,class 中的函数不会 运行 因为 'this' 引用 window 对象

$(document).ready(function () {

Crafty.init(window.innerWidth, window.innerHeight);

var player = new controller(37,38,39,40);

player.d.color("red").attr({
    w: 50,
    h: 50,
    x: 0,
    y: 0
}); 

// Jump Height = velocity ^ 2 / gravity * 2
// Terminal Velocity = push * (1 / viscosity)
var gravity = 1; 
var viscosity = 0.5; 
var frame = (1 / 20);
var distanceMultiplier = 10; //pixels per meter
var timeMultiplier = 20; //relative to actual time
var keystart = [];
var keyboard = [];

function controller (controls) {
    this.d = Crafty.e();
    this.d.addComponent("2D, Canvas, Color, Collision");
    this.d.collision();
    this.d.mass = 1;
    this.d.a = {
    extradistance : 0, 
    velocity : 0,
    acceleration : 0, 
    force : 0, 
    resistance : 0 

    };
    this.d.a.push = 0;
    this.d.v = {
    extradistance : 0, 
    velocity : 0, 
    acceleration : 0, 
    force : 0 
    };
    this.d.jumping = true;
    this.d.onHit("Collision", function () {
        var a = this.d.hit("Collision");
        if (a) {
            for (var b in a) {
                this.d.x = this.d.x - a[b].normal.x * a[b].overlap;
                this.d.y = this.d.y - a[b].normal.y * a[b].overlap;
                if (a[b].normal.y < -0.5) {
                    this.d.jumping = false;
                }
                if (Math.abs(a[b].normal.x) < 0.2) {
                    this.d.v.velocity = this.d.v.velocity * a[b].normal.y * 0.2;
                }
                if (Math.abs(a[b].normal.y) < 0.2) {
                    this.d.a.velocity = this.d.a.velocity * a[b].normal.x * 0.2;
                }
            }
            return;
        }
    });
    this.d.physics = function () {
        if (keyboard[arguments[1]] && !this.jumping) {
            this.v.velocity = 5;
            this.jumping = true;
        }

        if (keyboard[arguments[1]] && this.jumping) {
            var now = new Date();
            if (now.getTime() - keystart[arguments[1]].getTime() < 500) {
                this.v.velocity = 5;
            }
        }

        if (keyboard[arguments[0]] && keyboard[arguments[2]]) {
            this.a.velocity = 0;
        } else {
            if (keyboard[arguments[0]]) {
                this.a.velocity = -3;
            }
            if (keyboard[arguments[2]]) {
                this.a.velocity = 3;
            }
        }

        if (keyboard[arguments[3]]) {
            this.v.velocity = -5;
        }

        this.a.force = this.a.push - this.a.resistance;
        this.a.acceleration = this.a.force / this.mass;
        this.a.velocity = this.a.velocity + (this.a.acceleration * frame);
        this.a.extradistance = (this.a.velocity * frame);
        this.a.resistance = this.a.velocity * viscosity;
        this.attr({
            x: (this.x + (this.a.extradistance * distanceMultiplier))
        });

        this.v.force = gravity * this.mass;
        this.v.acceleration = this.v.force / this.mass;
        this.v.velocity = this.v.velocity - (this.v.acceleration * frame);

        this.v.extradistance = (this.v.velocity * frame);
        this.attr({
            y: (this.y - (this.v.extradistance * distanceMultiplier))
        });
        setTimeout(this.physics, (frame * 1000) / timeMultiplier);
    };
    this.d.listen = function(){ document.body.addEventListener("keydown", function (code) {
        var then = new Date();
        if (!keyboard[code.keyCode] && !this.jumping && code.keyCode == arguments[1]) { //only if not yet pressed it will ignore everything until keyup
            keyboard[code.keyCode] = true; //start movement
            keystart[code.keyCode] = then; //set time
        }
        if (!keyboard[code.keyCode] && code.keyCode != arguments[1]) { //only if not yet pressed it will ignore everything until keyup
            keyboard[code.keyCode] = true; //start movement
            keystart[code.keyCode] = then; //set time
        }
    });
    };
}
player.d.physics();
player.d.listen();
document.body.addEventListener("keyup", function (code) {
    keyboard[code.keyCode] = false;
});

});

在试图把函数作为原型的时候class,我运行遇到了问题。

Crafty.init(500,500);
function block () {
block.d = Crafty.e("2D, Color, Canvas");
block.d.color("red");
block.d.attr({x:0,y:0,h:50,w:50});
}
block.d.prototype.green = function() {
this.color("green");
}
var block1 = new block();
block1.d.color();

如果在构造函数中定义了一个对象,我不能用它来添加原型。

一般来说,在 Crafty 中,我们更喜欢构图。也就是说,您通过向实体添加更多组件来扩展它。您可以通过让一个组件在初始化期间自动添加其他组件来拥有层次结构的 种类

我没有仔细阅读您所有的示例代码,因为太多了!但是考虑第二个块:

function block () {
  block.d = Crafty.e("2D, Color, Canvas");
  block.d.color("red");
  block.d.attr({x:0,y:0,h:50,w:50});
}
block.d.prototype.green = function() {
   this.color("green");
}
var block1 = new block();
block1.d.color();

您正试图以一种不太惯用的方式将 Crafty 的做事方式(实体组件系统)与 类 结合起来。最好这样做:

// Define a new component with Crafty.c(), rather than creating a class
Crafty.c("Block", {
   // On init, add the correct components and setup the color and dimensions
   init: function() {
       this.requires("2D, Color, Canvas")
           .color("red")
           .attr({x:0,y:0,h:50,w:50});
   },
   // method for changing color
   green: function() {
       this.color("green");
   }
});

// Create an entity with Crafty.e()
block1 = Crafty.e("Block");
// It's not easy being green!
block1.green();