If, Else variables for Objects

Started by GameMaker_95, Sat 03/01/2015 07:32:32

Previous topic - Next topic

GameMaker_95

Hi,

So I have a room with an object, disguised as a character, working under a car. I also have one standing nearby. I would
like to have it so that if I go to this room before another room, he is working under the car, but if I go to this other room and
get an Item, he will be standing nearby and the only way I believe I can do this is by if, else statements but so far I can't make
it work. Can someone help with this. What I'm trying to do is something like this.

Code: ags

if (player.HasInventory(iBurnie)
object[2].Visible = false;
object[3].Visible = true;
else
object[2].Visible = true;
object[3].Visible = false;


If that makes sense. I just can't seem to code it correctly.

Thanks.

Gurok

When you have multiple statements inside an if() clause, you need to wrap them in braces ("{" and "}"). You're also missing a closing bracket on the if() statement line. Try this corrected version:

Code: ags
if (player.HasInventory(iBurnie))
{
    object[2].Visible = false;
    object[3].Visible = true;
}
else
{
    object[2].Visible = true;
    object[3].Visible = false;
}


Note also the indentation. It's convention to indent lines whenever you put them inside braces.

There are different styles for laying out your braces. The above is my preferred style. Some people prefer not to start a new line for an opening brace.

Code: ags
if (player.HasInventory(iBurnie)) {
    object[2].Visible = false;
    object[3].Visible = true;
}
else {
    object[2].Visible = true;
    object[3].Visible = false;
}


And some people even prefer the else wrapped in braces like so:

Code: ags
if (player.HasInventory(iBurnie)) {
    object[2].Visible = false;
    object[3].Visible = true;
} else {
    object[2].Visible = true;
    object[3].Visible = false;
}


These are all perfectly valid syntax for AGS.
[img]http://7d4iqnx.gif;rWRLUuw.gi

GameMaker_95

Hi Gurok

It worked perfectly, thanks again, you've been a big help. I tried it multiple ways, that was just the basics of what I wanted and
it still didn't help but Thanks, now if I get stuck with something like that again, I can fix it. Thanks for explaining it.

your awesome.

Alberth

A little late, but you can write this much shorter. The key is to realize "bool" values are data, just like "int" numbers.
I'll make very small steps, so I have a lot of code fragments. For brevity, I'll squash the curly bracket stuff as much as possible onto single lines. If you are used to writing the curly brackets at other places, feel free to split things onto separate lines again.

Before looking at your code, let's look at a simpler piece of code. The problem is very simple. I have an integer variable "x", with the value 1 or 2. I want to assign a value to integer variable "y", where "y" should get the value 1 when "x" is 1, and "y" should get the value 2 when "x" is 2. In code:
Code: ags
int x = ...; // x is either 1 or 2.

int y; // y should become 1 if x == 1, and 2 if x == 2.
if (x == 1) {
    y = 1;
} else { // x is not 1, thus x == 2 here.
    y = 2;
}
Works, right?

Now when you look closely at what is actually happening, At the "y = 1" line, we assign "1" to "y" when "x" is also "1". At the line "y = 2", we assign "2" to "y" when "x" is also "2". In other words, the following code also works:
Code: ags
int x = ...; // x is either 1 or 2.

int y; // y should become 1 if x == 1, and 2 if x == 2.
if (x == 1) {
    y = x; // y must become 1, and x is 1 here.
} else {
    y = x; // y must become 2, and x is 2 here.
}


Now if you look at the overall picture, what happens here is that "y = x;" is being executed in both branches. In other words, the same statement "y = x;" is performed no matter what the outcome of "x == 1" is. Thus it is equivalent to:
Code: ags
int x = ...; // x is either 1 or 2.

int y; // y should become 1 if x == 1, and 2 if x == 2.
if (x == 1) {
} else {
}
y = x;
The entire "if" is empty now, and can be removed. The solution to my problem is thus a simple
Code: ags
int x = ...; // x becomes either 1 or 2.

int y; // y should become 1 if x == 1, and 2 if x == 2.
y = x;
Now that's a lot shorter eh?


Back to your problem.
Code: ags
if (player.HasInventory(iBurnie)) {
    object[2].Visible = false;
    object[3].Visible = true;
} else {
    object[2].Visible = true;
    object[3].Visible = false;
}

Let's add a new variable "b" to store the boolean condition, and make the "if" code a little more clear:
Code: ags
bool b = player.HasInventory(iBurnie);
if (b) {
    object[2].Visible = false;
    object[3].Visible = true;
} else {
    object[2].Visible = true;
    object[3].Visible = false;
}
Boolean "b" can have two values, "true" and "false". When "b" is "true", you execute the two lines directly under the "if" line, and when "b" is "false", you execute the two lines directly under the "else" line.

Now I can pull the same trick I just did in the integer example:
Code: ags
bool b = player.HasInventory(iBurnie);
if (b) {
    object[2].Visible = false;
    object[3].Visible = b; // "object[3].Visible" must become "true" here, and "b" is "true".
} else {
    object[2].Visible = true;
    object[3].Visible = b; // "object[3].Visible" must become "false" here, and "b" is "false".
}


Since in both branches, you perform the same "object[3].Visible = b;" statement, it can be moved out of the "if":
Code: ags
bool b = player.HasInventory(iBurnie);
if (b) {
    object[2].Visible = false;
} else {
    object[2].Visible = true;
}
object[3].Visible = b;


Now the "object[2].Visible" assignment. It looks a lot like the "object[3].Visible" assignment above, except the values are reversed, you assign "false" when b" is "true" and vice versa. So how to do this?

Luckily, AGS provide a 'reverse' function with the weird name "!" (exclamation mark), that reverses the value of a boolean. When "b" is "true", "!b" is "false". When "b" is "false", "!b" is "true". The code can be rewritten to:
Code: ags
bool b = player.HasInventory(iBurnie);
if (b) {
    object[2].Visible = !b; // "object[2].Visible" must become "false" here, "b" is "true" thus "!b" is "false".
} else {
    object[2].Visible = !b; // "object[2].Visible" must become "true" here, "b" is "false" thus "!b" is "true".
}
object[3].Visible = b;


And again, both branches perform the same statement, the "if (b)" test makes no difference any more. The assignment can be moved below the "if":
Code: ags
bool b = player.HasInventory(iBurnie);
if (b) {
} else {
}
object[2].Visible = !b;
object[3].Visible =  b; // Added an extra space before the "b" to get nice vertical alignment.


The "if" statement is again empty and can be removed, resulting in:
Code: ags
bool b = player.HasInventory(iBurnie);
object[2].Visible = !b;
object[3].Visible =  b;


Depending on your taste, you can keep it like this, or remove the "b" variable:
Code: ags
object[2].Visible = !player.HasInventory(iBurnie);
object[3].Visible =  player.HasInventory(iBurnie);


While it saves a line, the "player.HasInventory(iBurnie)" text has been copied here. If that expression is long, it is preferred to keep the "bool b = ...;" assignment, as it makes more clear what value gets assigned to "object[2].Visible" and "object[3].Visible".

GameMaker_95

Hi Alberth

Thank you for what you have done there. I will be honest, I'm not up to the level of fully understanding the scripting language so it's difficult to understand
and I appreciate what you have done and I'm going to study this in hopes I can learn from it. While on the subject of if else variables, I have come across another
situation involving these and was wondering If you could help tidy it up, I keep getting a parse error at the first else but not the second.

{
  if (player.HasInventory(iShop))
  dShop2.Start();
  Nick.LoseInventory(iShop);
  Nick.AddInventory(iShop2);
  else
  dShop1.Start();
  if (player.HasInventory(iShop3))
  dShop3.Start();
  else
  dShop1.Start(); 
}

Thanks again. Much appreciated.

arj0n

#5
Code: ags

{
  if (player.HasInventory(iShop))
    {
      Nick.LoseInventory(iShop);
      Nick.AddInventory(iShop2);
      dShop2.Start();
    }
  else if (player.HasInventory(iShop3))
    {
      dShop3.Start();
    }
  else dShop1.Start();  
}

Kitty Trouble

Creating multiple lines that happen as a result of an if statement have to be contained in curly brackets. If you don't put curly brackets, only the very next line of code is executed.

It's also a good idea to indent the lines which are supposed to be included as part of an if statement like that for readability. So:

{
  if (player.HasInventory(iShop))
      dShop2.Start();
  Nick.LoseInventory(iShop);
  Nick.AddInventory(iShop2);
  else (this throws an error because no matching if statement)
      dShop1.Start();
  if (player.HasInventory(iShop3))
      dShop3.Start();
  else
      dShop1.Start(); 
}

This is what the compiler sees. You should put curly brackets around the code that runs when the if statement is true, so:

  if (player.HasInventory(iShop)) {
      dShop2.Start();
      Nick.LoseInventory(iShop);
      Nick.AddInventory(iShop2);
  }

And the same goes for the else. Right now the if (player.HasInventory(iShop3)) line will run always since the previous else doesn't have curly braces. If it's a nested if, meaning that its contained inside the previous else which was declared, then the entire thing needs to be inside the curly brackets of the else statement.

GameMaker_95

Thank you Arj0n for providing the code, it's a big help i can use it again if needed.. Thank you chaosgodkarl for explaining it simply for me to
understand, I think I can understand it and I should be able to fix these problems myself now. I appreciate the help everyone has given me.

SMF spam blocked by CleanTalk