[SOLVED] Health Decrease Over Time

Started by Priabudiman, Sun 28/06/2015 19:20:09

Previous topic - Next topic

Priabudiman

Hello all,

I have tried browsing the board, and combine all of the techniques available, but still, i havent got my problem solved.

what i have now is ive set

@ globalscript.ash
Code: ags
int health=100;


@ globalscript.asc
function game_start()
Code: ags
{
  LabelHealth.Text = String.Format("Health : %d", health);
}


and ive set a gui with label called LabelHealth

I have try a code for
Code: ags
function obj_blue_Interact()
{
health -= 5;
}


when player interact with some object, but the GUI label not changing, and i dont know if the value is already subtracted.

Lastly, i wonder if i can somehow program for the health to deteriorate over time? say .. every 15 second, until finally 0 / dead.

obviously im not good at coding, and im head over heels already with this, but im gonna try. so im very sorry if im asking int he wrong section. please guide me if you can..

thank you in advance!
~cheers

Slasher

#1
Quick basic answer...

For the label to keep being updated you need to put it in function repeatedly_execute_always in Global.

To deteriorate over time set a timer to start (1,600) every 15 seconds.

Then set IsTimerExpired  in global function repeatedly_execute_always

Code: ags

function repeatedly_execute_always() {

  LabelHealth.Text=String.Format("%d",health); // to update label

  if(IsTimerExpired(1)){
  health -= 5;  // takes 5 from health
  SetTimer(1, 600); //  updates counter health every 15 seconds (40 game loops= 40per sec x 15 =15 seconds. so 5 is 
 // taken off every 15 seconds.
 }
} 


PS You also need a to set a condition for when health has ran out...

quick reply and hopefully correct ;)



Priabudiman

#2
thank you there Slasher!

I've tried the code, ran without error, but the text in GUI are not changed somehow after 15 seconds.

I've also tried to move

Code: ags
int health=100;


from the globalscript.ash to the globalscript.asc but it gave me error

Code: ags
GlobalScript.asc(28): Error (line 28): undefined symbol 'health'


I suppose i will have to set the condition in the same code brackets as above?

Snarky

Quote from: slasher on Sun 28/06/2015 20:52:26
quick reply and hopefully correct ;)

Looks correct to me (except for the indentation)! Nicely done!

If it were my code I'd make some nitpicky changes, but this should work fine.

Quote from: Priabudiman on Sun 28/06/2015 21:32:26
thank you there Slasher!

I've tried the code, ran without error, but the text in GUI are not changed somehow after 15 seconds.

I've also tried to move

Code: ags
int health=100;


from the globalscript.ash to the globalscript.asc but it gave me error

Code: ags
GlobalScript.asc(28): Error (line 28): undefined symbol 'health'


I suppose i will have to set the condition in the same code brackets as above?

The "int health=100" should definitely go in GlobalScript.asc - this might possibly be why you're not seeing the label update. And it can't go inside of a function, because then it will disappear as soon as the function is over, and won't exist any more in the next loop.

I'm not sure about the error: could it be that you're putting "int health=100" below either obj_blue_Interact() or repeatedly_execute_always()? It needs to be above, so that the script knows about it before it gets to where you try to use it. Typically, variable definitions go at the top of the script, before any of the functions. But if you let us know what line 28 in your script is, that would make this much easier to answer.

Khris

There's a Global variables section in the project tree which you can use to create them without having to declare and export/import them in the proper places manually.
Declaring a variable in the header is a bad idea, because that will create separate variables, one local to the global script, and one for each room.

Also, while the label text has to updated again and again, you don't have to do so in one of the repeatedly_execute functions; it's enough to do it whenever the value of health changes.

Here's what I'd do:
Code: ags
// globalscript.ash

import bool ChangeHealth(int amount);
import int GetHealth();

// globalscript.asc

int health = 100;
bool ChangeHealth(int amount) {
  health += amount;
  return health > 0;
}
int GetHealth() {
  return health;
}


Now you can use those two functions like this:
Code: ags
  // some interaction
  if (GetHealth() < 20) player.Say("I'm too weak to do that.");
  else { ... }


  // losing health
  if (ChangeHealth(-5)) {
    Display("That hurt.");
  }
  else {  // dead
    ...
  }

Priabudiman

#5
@Snarky :
I managed to get the code working, but only in room script, not in global script. ive tested it with a display command on the is timer expired and it works! but still the GUI wont update even i put the codes at repeatedly execute always on the global script.

@Khris :
ive created a global var in project tree called health,int,100 . after that, i tried to paste your code like youve shown, i've pasted mine here..

Globalscript.ash

Code: ags
// Main header script - this will be included into every script in
// the game (local and global). Do not place functions here; rather,
// place import definitions and #define names here to be used by all
// scripts.
import bool ChangeHealth(int amount);
import int GetHealth();


Globalscript.asc

Code: ags
//----------------------------------------------------------------------------------------------------
// game_start
//----------------------------------------------------------------------------------------------------
function game_start() 
{
  LabelHealth.Text = String.Format("Health : %d", health);

  bool ChangeHealth(int amount) 
  {
  health += amount;
  return health > 0;
  }
  
  int GetHealth() 
  {
  return health;
  }
}

//----------------------------------------------------------------------------------------------------
// repeatedly_execute
//----------------------------------------------------------------------------------------------------
function repeatedly_execute()
{
}

//----------------------------------------------------------------------------------------------------
// repeatedly_execute_always
//----------------------------------------------------------------------------------------------------
function repeatedly_execute_always() 
{
}


but im getting this error

Code: ags
GlobalScript.asc(8): Error (line 8): Nested functions not supported (you may have forgotten a closing brace)


phew... my head feels like its burning! :grin:

Snarky

#6
You can
Quote from: Priabudiman on Mon 29/06/2015 07:00:02
@Snarky :
I managed to get the code working, but only in room script, not in global script. ive tested it with a display command on the is timer expired and it works! but still the GUI wont update even i put the codes at repeatedly execute always on the global script.

Ah, I see now what the problem is: slasher's code makes sure to restart the timer when it runs out, but it never starts it in the first place, so it never gets triggered.

With Khris's version, well, the error message is telling you exactly why it's not working: You can't "nest" functions, which means to put one function inside another function, and on line 8 you have the function ChangeHealth() inside of the function game_start(). You should put ChangeHealth() and GetHealth() outside of any other functions (right above game_start(), for example). I would also put the update of the label inside of ChangeHealth() so that you don't have to remember it every time.

Then you need to actually call ChangeHealth(). All in all, this should be your GlobalScript.asc code:

Code: ags

bool ChangeHealth(int amount) 
{
  health += amount;
  LabelHealth.Text=String.Format("%d",health);
  return health > 0;
}
  
int GetHealth() 
{
  return health;
}

function game_start()
{
  SetTimer(1,600);  // Start counting down to when we'll decrease the health
}

function repeatedly_execute()
{
  if(IsTimerExpired(1)) // ... it's time to decrease the health
  {
    ChangeHealth(-5);
    if(GetHealth() > 0)  // ... we're still alive
    {
      SetTimer(1,600);  // just start counting again
    }
    else  // player has died
    {
      // ... whatever you do when dead
    }
  }
}


See if you can try to actually understand this code, and why it's (hopefully) working while the earlier versions didn't.

Khris

Sorry, I forgot about the label :) And like Snarky shows, if you have defined a Global variable, you no longer need "int health = 100;"

Despite not starting with "function", that's still what ChangeHealth() and GetHealth() are, as is also signified by the () after the name. If you look at the code I posted you'll also notice that I haven't indented the first part but did so with the example code; that's because the first part is supposed to be put outside any function, while the usage examples go inside event functions.
If you had been supposed to put the functions inside game_start, I'd also have stated this in my code.

Priabudiman

Snarky and Khris, thank you so much for your guides, I dont know what i would do without you guys := .

I will try again with the code. and hopefully i can understand it all for the future. Be back soon with the code report and the practice it does in game.

Now i know that :
1. you cannot put / nest one int,bool, inside another function. (laugh)
2. i missed that global variables in the project tree
3. artists also can code... it just take longer time than dinosaurs to evolve..

Crimson Wizard

Quote from: Priabudiman on Mon 29/06/2015 12:26:40
Now i know that :
1. you cannot put / nest one int,bool, inside another function. (laugh)

I was not sure what you mean here, that's why I decided to add a clarification:
You cannot put functions inside another function.
But you can put variables (int, bool, etc) inside function.

Monsieur OUXX

Still in 2015, it's impossible for me to ever remember how the damn import/export work. The help is not clear at all. I always need to have a look et my former scripts to remember what to put in the header, in the body, etc.
 

Priabudiman

Quote from: Crimson Wizard on Mon 29/06/2015 12:59:01
Quote
I was not sure what you mean here, that's why I decided to add a clarification:
You cannot put functions inside another function.
But you can put variables (int, bool, etc) inside function.

That.. Sir.. Are the correct one... damn my engrish...

Priabudiman

Quote from: Monsieur OUXX on Mon 29/06/2015 13:10:36
Still in 2015, it's impossible for me to ever remember how the damn import/export work. The help is not clear at all. I always need to have a look et my former scripts to remember what to put in the header, in the body, etc.

I too Monsieur... but for me, as far as this code goes.. I still didnt get what Import/Export supposed to do?! maybe its easier for guy like me to be told, put this in here.. put that in there.. (laugh)

Crimson Wizard

#13
Quote from: Monsieur OUXX on Mon 29/06/2015 13:10:36
Still in 2015, it's impossible for me to ever remember how the damn import/export work. The help is not clear at all.
Back in 2012 I was asking for any contributors to help improving manual.
Back in December 2014 I was asking for any help in moving AGS manual to the better source type.

Any results?
So much to wonder...

E: Do not get me wrong, I guess I could push myself to do this, if I'd apply enough force. Problem is that I feel less and less dedicated to the project, seeing as people do not seem to care...

Khris

To create a global variable manually, declare it in the global script (asc):

Code: ags
// near the top, preferably
int someValue;


As opposed to functions, variables need to be exported somewhere below their declaration. I always do it right in the next line. Note that the export statement does not require the datatype (or [x] for arrays], JUST the name), because we already told AGS exactly what kind of variable it is. So in the very next line, add:
Code: ags
export someValue;


In order to access the variable in rooms, it needs to be imported in the header (which gets put on top of room scripts at compile time).
Code: ags
// global script header
import int someValue;

The line is exactly like the declaration line, with "import" right at the start.

With functions, the process is almost exactly the same, no exporting though.
Code: ags
// header
import String myDate(int gametime);

// script
String myDate(int gametime) {
  ...
}

Again, the import needs the full signature.

Priabudiman

#15
Again, Thank you!

One thing that i still wondering... How many "else" you can have in one "if" ? for example.. can I execute this?

Code: ags
    if(IsTimerExpired(1)) // ... it's time to decrease the health
  {
    ChangeHealth(-5);
    if(GetHealth() > 0)  // ... we're still alive
    {
      SetTimer(1,120);  // just start counting again
    }
    else  // player has died
    {
      Display("You Died..."); 
          
   if (GetHealth()< 20)
  {
    Display("I feel weak");
  }


Like, in some health status, in this case 20.. i want the player to talk, or display something.

Khris, ive saved your guides on my special code learning notes for future references! (laugh)

As for the game, on my side, ive been successfully run it without error and added some functions when the timer expired. Im attaching the prototype run if you guys want to help me test it out?

Download Link :
From Dropbox

Please let me know! ;)

SMF spam blocked by CleanTalk