I am new to Crafty.js. I am currently working a 2D Top Down RPG using this frame work. I am trying to create a custom component that will contain the Unit's information such as Health, Mana, Name etc. My component's code are as follows:
Crafty.c("UnitInfo", {
init: function() {
this.bind("EnterFrame", function(){
console.log("Custom Component Test: " + this.message);
});
},
unitinfo: function(message) {
this.message = message;
}
});
Then I added this component to a unit which is in my case, an Enemy entity:
enemy1 = Crafty.e('Enemy, 2D, Canvas, Color, enemy_default, SpriteAnimation, Solid, Collision, UnitInfo')
.attr({x: (screenWidth/2) + 150, y: (screenHeight/2) + 150, w: spriteBaseW, h: spriteBaseH, curHealth: 100 })
.checkHits("Skill")
.unitinfo("Random Msg")
.bind("HitOn", function() {
var rndDmg = 0;
if(currentSkill==1) rndDmg = skillDamage.skill1;
else if(currentSkill==2) rndDmg = skillDamage.skill2;
else if(currentSkill==3) rndDmg = skillDamage.skill3;
else if(currentSkill==4) rndDmg = skillDamage.skill4;
rndDmg = randomRange(rndDmg-9,rndDmg);
this.curHealth -= rndDmg;
Crafty.e("2D, DOM, Text, Tween")
.attr({x: this.x, y: this.y})
.textColor("white")
.text(rndDmg)
.textFont({size: "20px"})
.tween({y: this.y-30, alpha: 0.0}, 2000)
.bind("TweenEnd", function(){
this.destroy();
});
if(this.curHealth<=0) {
//this.destroy();
//console.log("An Enemy was killed!!!!");
}else{
console.log("Enemy HP: " + this.curHealth + ", Damage Taken: " + rndDmg);
}
})
.bind("EnterFrame", function() {
enemyAI(this);
});
When I execute the code, it shows me this error:
I believe that the unitinfo() is properly working as the "Random Msg" is appearing on the console logs and it is being executed every frame. I just don't understand why "this" is being recognized as undefined. Can someone help me on this?
This is because you're attempting to call bind on the result of unitinfo()
, but that method doesn't return the entity.
This is a fundamental aspect of javascript, but it's definitely a gotcha when implementing custom components in Crafty. From the docs
Keep in mind that the method chaining technique (calling
e.place().color()
) is only possible because we explicitly return this from our custom method. Forgetting to do so can be a common source of errors, so keep that in mind if you get a hard-to-pin-down "method undefined" message.
i.e. when you define a method, you have to explicitly return this
to use it in this manner.