Using input into text boxes to delete objects! SOLVED

Started by cinos, Fri 29/09/2006 13:41:20

Previous topic - Next topic

cinos

 :)Thanks for the help Monkey and Khris. I have taken your advice and chucked the on_key_press idea as this became messy as you suggested. I am now trying text boxes. However I still need some assistance. When I enter '8' the object [1] disappears (as it should) but if I enter another number nothing happens.(I think my 'else ' command or logic is up the creek.) I want object [1]Ã,  to move if the player puts another number other than 8 into the text box . Also as soon as I enter 8 into the text box it deletes the object without me pressing enter! Hope you can help.

ifÃ,  ((object[1].Visible)&&(txtUserInput.Text.AsInt == 8))
Ã,  {object[1].Visible = false;}
else
{object[1].Move(50, 266, 2,eNoBlock,eWalkableAreas);}


Khris

Not about your actual problem, but two things I've noticed:

-If there's only one command to be executed if an if-condition is true, then you don't need those: {}
They are only used for grouping things together.

-When testing if a function doesn't return 0, it's not necessary to put "==1" behind it.

So you can replace
if (IsKeyPressed(48)==1){object[1].Move(50, 266, 2,eNoBlock,eWalkableAreas);} 
with
if (IsKeyPressed(48)) object[1].Move(50, 266, 2,eNoBlock,eWalkableAreas);


monkey0506

Quote from: KhrisMUC on Fri 29/09/2006 14:06:51-When testing if a function doesn't return 0, it's not necessary to put "==1" behind it.

The reason this works is because in AGS (as with most scripting languages), when an expression is put into parentheses and evaluated by certain keywords (namely if and while), it is evaluated as a boolean expression (i.e., true or false (non-zero or zero respectively)). You can also test if an expression is false like this:

Code: ags
if (!expression)


Using an exclamation point to indicate "NOT", i.e., NOT false is true, and vice versa.

I would also recommend using some form of indentation with your parentheses:

Code: ags
if (expression) {
  do_something();
  do_something_else();
}


You can also move the braces around:

Code: ags
if (expression)
{
  do_something();
  do_something_else();
}

if (expression) {
  do_something();
  do_something_else();
  } // this is my preferred method of matching the braces, though any of the previous methods work just as well (it really just comes down to user preference)


Also, though it's not necessary, I prefer to add spaces like Khris did:

Code: ags
if (IsKeyPressed(48)) object[1].Move(50, 266, 2, eNoBlock, eWalkableAreas);

// instead of

if(IsKeyPressed(48))object[1].Move(50,266,2,eNoBlock,eWalkableAreas);


But enough about that. On to the code itself.

Something I noticed you've done is you've used keycode 58, which is the colon (':'). I'm not exactly sure if you intended to do that, but you have. Perhaps you would find it easier to use the character representation instead of the keycode? What I mean is that instead of using IsKeyPressed(48), you can use IsKeyPressed('0') (putting the character between single quotes).

As for the problem with removing the objects, just checking the state of whether each key is pressed could be a messy thing to do. You may want to look at using a TextBox, which would allow you to have the user type their answers into a text box instead of just checking whether the key is pressed. Then you could do something like this:

Code: ags
// replace txtAnswer with the script o-name of the TextBox
// also, I'll use script o-names to represent the text of the objects
if ((o2x4.Visible) && (txtAnswer.Text.AsInt == 8)) o2x4.Visible = false;
if ((o2x5.Visible) && (txtAnswer.Text.AsInt == 10)) o2x5.Visible = false;
if ((o2x6.Visible) && (txtAnswer.Text.AsInt == 12)) o2x6.Visible = false;
if ((o2x7.Visible) && (txtAnswer.Text.AsInt == 14)) o2x7.Visible = false;
if ((o2x8.Visible) && (txtAnswer.Text.AsInt == 16)) o2x8.Visible = false;
if ((o2x9.Visible) && (txtAnswer.Text.AsInt == 18)) o2x9.Visible = false;
// and I'm sure you get the idea


If you don't really understand what a script o-name is, you can read about them here.

Regarding "txtAnswer.Text.AsInt", in the above example txtAnswer is the script o-name of a TextBox. txtAnswer.Text is a String property of the TextBox, and txtAnswer.Text.AsInt is an integer property of the String. txtAnswer.Text.AsInt will evaluate the user's input for an integer expression. If the String (txtAnswer.Text) doesn't contain a number, this will return 0.

Ashen

#4
Where are you triggering this from? Possibly you said originally, but if so you've deleted it in an edit.
And the obvious one: Are you sure you've got a walkable area for the Object to use, and that it's wide enough (3 pixels is a workable minimum, below that it doesn't always work right).

EDIT: Just thought of something else - Depending on where you're triggering it, you might be calling the Object.Move command repeatedly. Since it's non-blocking, this means it doesn't get a chance to actually start moving - and hence doesn't seem to do anything.

Try:
Code: ags

if  ((object[1].Visible)&&(txtUserInput.Text.AsInt == 8 )) {
  object[1].Visible = false;
}
else if (object[1].Moving == false) {
  object[1].Move(50, 266, 2,eNoBlock,eWalkableAreas);
}


Finally, you'll probably need to add something to stop it being triggered by an empty TextBox, or by letters. Try:
Code: ags

else if (object[1].Moving == false && txtUserInput.Text.AsInt != 0) {


It's not perfect, but hopefully it'll show you how to do what you want.
I know what you're thinking ... Don't think that.

cinos

Thanks for the tip Ashen. Here is a brief synopsis of what I am trying to do, the problem I am having, and the code for it.

Ego walks onto region1_a. A sound is played. An object[0] (a skeleton)appears and then object [1] (a rock)appears. This rock has a maths sum on it (2x4). The skelton throws rock towards Ego. The rock stops about half way.
A text box appears. If the player enters 8 via the keyboard than the rock disappears.(Will add to score but have not scripted yet.) the skeleton disappears and a new one appears and throws object[2].
If the player enters another number, say 12, the rock then continues and hits Ego (ArethingsOverlapping) disappears, (Subtracts from score) and a new skelton appears. This process continues for all the 2 x tables.(etc)
The problem I am having is that the object does not stop but continues through to Ego. When the text box appears I can not enter numbers into it. I then get this error   after the rock hits Ego.  post_script_cleanup call stack exceeded:possible recursive function call? running region1_b.
It is almost like I have to stop the script and wait for a key press but when I try this WaitKey() the script runs striaght through.   I REALLY NEED ASSISTANCE

#sectionstart region1_a  // DO NOT EDIT OR REMOVE THIS LINE
function region1_a() {
  // script for Region 1: Player walks onto region


mouse.DisableMode(eModeWalkto); 

PlaySound(1);
Wait(80);
object[0].Visible = true;
cEgo.FaceObject(object[0]);
object[0].SetView(3);
object[0].Animate(2,6,eOnce,eBlock);
object[0].Animate(0,6,eOnce,eNoBlock);
object[0].Move(280,266,1,eBlock,eWalkableAreas);

//2x4object1shield
object[1].Visible=true;PlaySound(2);
object[1].SetView(4);
object[1].Animate(0,1,eRepeat,eNoBlock);
object[1].Move(150, 266, 2,eBlock,eWalkableAreas);object[1].StopAnimating();}


#sectionend region1_a  // DO NOT EDIT OR REMOVE THIS LINE

#sectionstart region1_b  // DO NOT EDIT OR REMOVE THIS LINE
function region1_b() {
// script for Region 1: While player stands on region

//2x4objshied(rock)
//Set up GUI (gTable_answer)and positions it. Enables the text box (txtUserInput) for player to  type into.
gTable_answer.SetPosition(224,90);gTable_answer.Visible=true;gTable_answer.Clickable=true;
txtUserInput.Enabled=true;
//Check to see if the user has typed the number 8 into the text box and if it is true than object [1] is removed.
// and object[2]is placed on the screen.
//If the player types another number(eg 9) than object [1] moves towards the character and hits (overlapps) him then disappears.
//puts object 2 onto the screen.


if  ((object[1].Visible)&&(txtUserInput.Text.AsInt == 8 )) {
  object[1].Visible = false;PlaySound(3);object[0].Animate(1,6,eOnce,eBlock);Wait(40);object[0].Visible=false;object[0].SetPosition(337, 269);
PlaySound(1);Wait(60);object[0].Visible = true; object[0].Animate(2,6,eOnce,eBlock);object[0].Animate(0,6,eOnce,eNoBlock);
object[0].Move(280,266,1,eBlock,eWalkableAreas);txtUserInput.Text=("");Wait(40);

}
else if (object[1].Moving == false) {
  object[1].Move(50, 266, 2,eBlock,eWalkableAreas);
}

if (AreThingsOverlapping(1001, EGO)) {object[1].Visible = false;object[2].Visible = true;
object[0].Animate(0,6,eOnce,eNoBlock);object[2].SetView(4);object[2].Animate(1, 1,eRepeat,eNoBlock);
object[2].Move(150, 266, 2,eBlock,eWalkableAreas);object[2].StopAnimating();txtUserInput.Text=("");}

Ashen

First thing I'd suggest would be to split the rock's movenment into 2 parts (before the textbox appears, moving to hit cEgo). That should make it easier to 'pause' the script at the proper point.
Also, have you tried using an InputBox, rather than a GUI TextBox? It might simplify the 'getting the answer' part. If it works OK, you can probably script a custom GUI to take it's place, but first things first...

That code seems very confused to me ... I think it's the 'Player stands on region' part that's the problem - it's basically checking all the time the player is on the region, even before they know there's something to react to.

Try:
Code: ags

#sectionstart region1_a  // DO NOT EDIT OR REMOVE THIS LINE
function region1_a() {
  // script for Region 1: Player walks onto region
  player.StopMoving();
  object[0].Visible = true;
  object[1].Visible = true;
  object[1].Move(115, 80, 2, eBlock); // Replace coords with your midpoint
  String answer = Game.InputBox("2x4:"); // Leave prompt blank if you want.
  if (answer.AsInt == 8) {
    object[1].Visible = false;
    PlaySound(3);
    object[0].Animate(1,6,eOnce,eBlock);
    Wait(40);
    object[0].Visible=false;
    object[0].SetPosition(337, 269);
    PlaySound(1);
    Wait(60);
    object[0].Visible = true;
    // And add score
  }
  else {
    object[1].Move(cEgo.x, cEgo.y-10, 2, eBlock); // Replace coords with a specific location, if you want.
    // And remove score
  } 
  object[2].Visible = true;
  object[0].Animate(0,6,eOnce,eNoBlock);
  object[2].SetView(4);
  object[2].Animate(1, 1,eRepeat,eNoBlock);
  object[2].Move(115, 80, 2,eBlock,eWalkableAreas); // Replace coords with your midpoint
  answer = Game.InputBox("2x6:"); // Leave prompt blank if you want.
  // if (answer.AsInt == 12) { ... And so on
 
}
#sectionend region1_a  // DO NOT EDIT OR REMOVE THIS LINE


And remove/comment out all the code under 'Player Stands on Region'.
This should work, but is likely to get a bit unwieldy since you want it to happen many times. It should be possible to move the code into a function, for neatness, once we've seen if it actually works for you.
I know what you're thinking ... Don't think that.

cinos

#7
I have tried the code and it does what I want. However the object[1]rock that is 2x4 is actually a graphic with 2x4 on it. I will keep working on it. I thought of putting it as a function but I will try to get it working first. Thanks heaps. I am sure this is the start of lots of work but I am really enjoying all the thinking and the support I am getting through the forum. Thanks for your time and effort.

EDIT:
Ashen it is working fine  but the input box looks a bit yuck! How can I script a custom gui that does the same thing but I can jazz up! As the player will have to solve quite a few times tables a function may be the way to go. I am now researching ags manual to look up how to make a score system. Thanks again.

Ashen

Please don't double post, use the 'Modify' button if you've got something you want to add before someone else replies.

For the score system, you can either use the built-in one (GiveScore) or use variables, it depends on how you want it to work (e.g. if you only want the score calculated for that room variables would be best, if it's for the whole game GiveScore is probably the way to go).
I know what you're thinking ... Don't think that.

SMF spam blocked by CleanTalk