I just picked up Construct 2 this Monday. Our studio is switching from RPG maker, and so far I am finding Construct 2 to be vastly more powerful, full featured, and transparent! I'm new to Javascript, and I'm working on setting up our damage dice etc, and I want to have a popup appear over a character's head when they take damage. I figured out how to get it to instantiate a text object with runtime.createInstance(), which will drift up and fade, but I'm having trouble accessing the SetText action in the text so I can insert the damage value. I've . The area I seem to be having trouble is around Line 173. I can also paste the whole capx if needed.
Thank you!
Edit: apparently I am too new to pastebin the code, but here it is. BBCode doesn't seem to support line numbers, but it's about 3/4 of the way to the bottom, under the "Defend" action.
// ECMAScript 5 strict mode
"use strict";
assert2(cr, "cr namespace not created");
assert2(cr.behaviors, "cr.behaviors not created");
/////////////////////////////////////
// Behavior class
// *** CHANGE THE BEHAVIOR ID HERE *** - must match the "id" property in edittime.js
// vvvvvvvvvv
cr.behaviors.RPGChar = function(runtime)
{
this.runtime = runtime;
};
(function ()
{
// *** CHANGE THE BEHAVIOR ID HERE *** - must match the "id" property in edittime.js
// vvvvvvvvvv
var behaviorProto = cr.behaviors.RPGChar.prototype;
/////////////////////////////////////
// Behavior type class
behaviorProto.Type = function(behavior, objtype)
{
this.behavior = behavior;
this.objtype = objtype;
this.runtime = behavior.runtime;
};
var behtypeProto = behaviorProto.Type.prototype;
behtypeProto.onCreate = function()
{
};
/////////////////////////////////////
// Behavior instance class
behaviorProto.Instance = function(type, inst)
{
this.type = type;
this.behavior = type.behavior;
this.inst = inst; // associated object instance to modify
this.runtime = type.runtime;
};
var behinstProto = behaviorProto.Instance.prototype;
behinstProto.onCreate = function()
{
// Load properties
this.HP = this.properties[0];
this.MaxHP = this.properties[1];
this.Armor = this.properties[2];
this.InvulnerabilityTimer = false;
this.InvulnerabilityDelay = 1000;
this.AttackTimer = false;
this.AttackDelay = 300;
this.Popup = undefined;
this.PopupImgPt = 0;
// object is sealed after this call, so make sure any properties you'll ever need are created, e.g.
// this.myValue = 0;
};
behinstProto.onDestroy = function ()
{
// called when associated object is being destroyed
// note runtime may keep the object and behavior alive after this call for recycling;
// release, recycle or reset any references here as necessary
};
// called when saving the full state of the game
behinstProto.saveToJSON = function ()
{
// return a Javascript object containing information about your behavior's state
// note you MUST use double-quote syntax (e.g. "property": value) to prevent
// Closure Compiler renaming and breaking the save format
return {
// e.g.
"hitPoints": this.HP
};
};
// called when loading the full state of the game
behinstProto.loadFromJSON = function (o)
{
// load from the state previously saved by saveToJSON
// 'o' provides the same object that you saved, e.g.
// this.myValue = o["myValue"];
// note you MUST use double-quote syntax (e.g. o["property"]) to prevent
// Closure Compiler renaming and breaking the save format
};
behinstProto.tick = function ()
{
var dt = this.runtime.getDt(this.inst);
// called every tick for you to update this.inst as necessary
// dt is the amount of time passed since the last tick, in case it's a movement
};
// The comments around these functions ensure they are removed when exporting, since the
// debugger code is no longer relevant after publishing.
/**BEGIN-PREVIEWONLY**/
behinstProto.getDebuggerValues = function (propsections)
{
// Append to propsections any debugger sections you want to appear.
// Each section is an object with two members: "title" and "properties".
// "properties" is an array of individual debugger properties to display
// with their name and value, and some other optional settings.
propsections.push({
"title": this.type.name,
"properties": [
// Each property entry can use the following values:
// "name" (required): name of the property (must be unique within this section)
// "value" (required): a boolean, number or string for the value
// "html" (optional, default false): set to true to interpret the name and value
// as HTML strings rather than simple plain text
// "readonly" (optional, default false): set to true to disable editing the property
{"name": "My property", "value": this.myProperty},
{"name": "Attack Timer", "value": this.AttackTimer},
//{"name": "Popup", "value": this.Popup}
]
});
};
behinstProto.onDebugValueEdited = function (header, name, value)
{
// Called when a non-readonly property has been edited in the debugger. Usually you only
// will need 'name' (the property name) and 'value', but you can also use 'header' (the
// header title for the section) to distinguish properties with the same name.
if (name === "My property")
this.myProperty = value;
};
/**END-PREVIEWONLY**/
//////////////////////////////////////
// Conditions
function Cnds() {};
// the example condition
Cnds.prototype.IsDead = function ()
{
// ... see other behaviors for example implementations ...
return this.HP < 0;
};
// ... other conditions here ...
behaviorProto.cnds = new Cnds();
//////////////////////////////////////
// Actions
function Acts() {};
// the example action
Acts.prototype.Attack = function ()
{
// ... see other behaviors for example implementations ...
};
Acts.prototype.Defend = function (damage)
{
if (damage === undefined) {
damage = "0";
}
var dmg = (Number(damage) - this.Armor);
if (dmg > 0) {
this.HP -= dmg;
if (this.Popup != undefined ) {
var popinst = this.inst.runtime.createInstance(this.Popup, this.inst.layer, this.inst.getImagePoint(this.PopupImgPt, true), this.inst.getImagePoint(this.PopupImgPt, false));
if (popinst === undefined) {alert("wtf")} else {
popinst.SetText(String(dmg));
}
} else {alert("Popup undefined!")}
}
// ... see other behaviors for example implementations ...
};
Acts.prototype.SetPopup = function (object, imgpt)
{
//alert("setting popup on " & this.inst.toString() & " to " & this.Popup);
this.Popup = object;
this.PopupImgPt = imgpt;
};
// ... other actions here ...
behaviorProto.acts = new Acts();
//////////////////////////////////////
// Expressions
function Exps() {};
// the example expression
Exps.prototype.HP = function (ret) // 'ret' must always be the first parameter - always return the expression's result through it!
{
ret.set_int(this.HP); // return our value
// ret.set_float(0.5); // for returning floats
// ret.set_string("Hello"); // for ef_return_string
// ret.set_any("woo"); // for ef_return_any, accepts either a number or string
};
Exps.prototype.Attack = function (ret) // 'ret' must always be the first parameter - always return the expression's result through it!
{
if (this.AttackTimer ) {
ret.set_string("0");
} else {
ret.set_string( String(1+Math.floor(Math.random()*5)));
this.AttackTimer = true;
var self = this;
setTimeout(function(){ self.AttackTimer = false},this.AttackDelay)
}
// ret.set_float(0.5); // for returning floats
// ret.set_string("Hello"); // for ef_return_string
// ret.set_any("woo"); // for ef_return_any, accepts either a number or string
};
// ... other expressions here ...
behaviorProto.exps = new Exps();
}());[/code:3b0o1be9]
While I was poking around I stumbled accross the inst.text and inst.text_changed. I set the text to what I wanted and text_changed to true, and that seemed to work. I checked in the settext action of the text plugin, and I found that there were three lines there. [code:3b0o1be9]popinst.text = String(dmg);
popinst.text_changed = true;
this.runtime.redraw = true;[/code:3b0o1be9]
I added the redraw line to my code, but I don't imagine it's good coding practice to duplicate the action this way. I would much rather find a way to test to make sure I spawned a text object, then invoke it's SetText action, so it can handle the text change itself. Any ideas on how I might do this in a more correct manner?
Edit: I found inst.type.plugin.acts.SetText(dmg); But it seems to crash Text_Plugin.js at line 707, column 24. This is the redraw line above. It says "cannot set property 'redraw' of undefined". I'm guessing that I am trying to call the action before the text object is properly intialized. Is there a way to schedule an action for the next frame? Or should I initialize the popup instance somehow? I tried runtime.trigger(Object.getPrototypeOf(this.Popup.plugin).cnds.OnCreated, popinst); but that didn't seem to work.