Page 1 of 1

Text Actor in void issue.

PostPosted: Mon May 18, 2020 7:06 pm
by Jeisenga
I have a problem with a Text Actor. I want the text changed in a void but I can't figure it out. Please have a look at my sample program and change the script so my issue is solved, if possible.

Re: Text Actor in void issue.

PostPosted: Mon May 18, 2020 8:07 pm
by lcl
I can't test your project right now, but I've got a guess of what might be causing the problem.

Are you trying to use it like this:
Code: Select all
sprintf(myTextActor.text, "Print this");

Because that works in normal event scripts, but not in Global Code. It has to do with how GE handles updating actor variables (like the 'text' variable).

The way to make it work in Global Code is to use getclone() to get a pointer to the actor, and use it to update the text. Like this:
Code: Select all
Actor *myActorPointer = getclone("myTextActor.0");
sprintf(myActorPointer->text, "Print this");


I hope this helps! :) If it doesn't, I'll get back to it tomorrow.

Re: Text Actor in void issue.

PostPosted: Mon May 18, 2020 10:49 pm
by Jeisenga
Thanks LCL.
I shortened your code a bit but it got me on the right track, Point deserved.

My original void:
void V_Text()
{
sprintf(Txt.text, "I am Txt Created in Void");
sprintf(Txt2.text, "I am Txt2 Created in Void too");
}


Modified with your code:
void V_Text()
{
Actor *myActorPointer = getclone("Txt2.0");//sprintf(myActorPointer->text, "Print this");
sprintf(Txt.text, "I am Txt Created in Void");
sprintf(Txt2.text, "I am Txt2 Created in Void too");
}

This line is not required: sprintf(myActorPointer->text, "Print this");

Re: Text Actor in void issue.

PostPosted: Tue May 19, 2020 12:17 pm
by lcl
While it's good that your code now works, I must point out that your new code doesn't actually work because it's right, but because even though it's wrong, it happens to trigger Game Editor to update Txt2's variables. But that's a gimmicky fix.

What I mean is that, currently, your code does not actually make sense, it just happens to fix the problem at hand via a side effect of calling getclone(). I'll explain:

Code: Select all
void V_Text()
{
    Actor *myActorPointer = getclone("Txt2.0");            // Line 1
    sprintf(Txt.text, "I am Txt Created in Void");         // Line 2
    sprintf(Txt2.text, "I am Txt2 Created in Void too");   // Line 3
}

On "Line 1" you use getclone() to get an Actor pointer (i.e. a variable that holds information of where in the program memory the data of a certain actor is located) to the first (and only) clone of actor Txt2. The ".0" part means "clone number 0". That last part can actually be left out when there isn't multiple instances of the actor in the game, so it could be simplified to: getclone("Txt2").

The problem is, your code never uses the pointer at all. It just fetches the value and stores it in the variable called "myActorPointer", but doesn't do anything with it. Logically, the code should behave just like your original code, i.e. the text of Txt2 should not update.

Now, the thing that makes the text update anyway, is most likely a side effect of getclone(). It seems that when getclone() is called, Game Editor automatically flags the fetched actor as one that should have it's variables checked for updates in the current code context.

The way to actually use the Actor pointer was shown in the line of code that you left out as "not required". So, the actual code would be:
Code: Select all
void V_Text()
{
    Actor *myActorPointer = getclone("Txt2");
    sprintf(Txt.text, "I am Txt Created in Void");
    sprintf(myActorPointer->text, "I am Txt2 Created in Void too");
}

But this code actually also has the same problem as your original code. It doesn't update the text of the actor "Txt" if the function is not called from an event of the "Txt" actor itself. The reason why it works in your .ged example is because "Txt" is the actor calling the function "V_Text()" and thus, the actor has already been flagged for being updated. Try and move the function call to, say View -> Create Actor. Now you'll see that "Txt" is not updated anymore.

So, to write a code that has logic that makes sense and that works no matter where it's called from you need to use getclone() for both actors, "Txt" and "Txt2". Here's an example:
Code: Select all
void V_Text()
{
    Actor *txtPointer = getclone("Txt");   // Fetch pointer to Txt
    Actor *txt2Pointer = getclone("Txt2"); // Fetch pointer to Txt2

    sprintf(txtPointer->text, "I am Txt Created in Void");       // Use the first pointer to update the text of Txt
    sprintf(txt2Pointer->text, "I am Txt2 Created in Void too"); // Use the second pointer to update the text of Txt2
}


So, always use getclone() when you're trying to edit an actor's variables via a function in Global Code.

I'm sorry for the lengthy explanation, but I hope this cleared some of the confusion regarding the issue at hand. :) If you'd like me to explain more about something, just ask and I'll be happy to help.

------------------------------

By the way, I think you may find this a useful read: viewtopic.php?f=27&t=10848#p74893
It's a tutorial I wrote years ago about making your own functions in Game Editor. I think you may have already read Hblade's tutorial, as he used to call functions "voids" as you do. The keyword void, at the beginning of a function declaration actually only means that the function doesn't return any value.

Re: Text Actor in void issue.

PostPosted: Fri May 29, 2020 10:35 pm
by Jeisenga
Thanks LCL, I don’t think an explanation can be too long for me. I need a lot of explanation and samples to fully understand functions completely. I have read and saved your tutorial 2 years ago, but just recently I’m trying to use functions and clones. I worked my way through all the posts and tutorials, but English is not my first language and that sometimes get me confused or even completely lost. But still I’m trying. The main reasons I’m using GE is to see if I can make an idea into a playable game. The problems that come with that gives me satisfaction when I am able to solve them.
At this moment I am making an Air Traffic Controller game like the Heathrow game for the Spectrum from the 80s. Yes, I date back to those times. My first build is with 15 planes to land an then I added 3 more planes. Because of my lack of knowledge of working with clones, I made them all separate actors with all there collisions and control programming. You can imagine how many script that is. Although the game is playable for 98% of the time, I like to remake it with 1 actor and 17 clones. So if I want to add more planes it is easier with clones than actors and if I want to change a small thing I don’t have to go through all the actors. But I am not sure if I can convert all the commands from a single actor into clone actors because of the pointer issues I get when using clones.
Thanks again for your help and if I run into trouble I know where to find you. BTW, I am only online every 10 days or so, so my response will not be swift.