Graphical health meter

From SCI Wiki
Jump to: navigation, search

Originally posted on the SCI Programming Forums by Gumby.


Here's a really simple solution to accomplish this. First, the laborious part; you need to make a view starting with a health bar at 'full strength', and then in each frame remove one 'line' of heath. My implementation used a health meter with a length of roughly 100 pixels (so 100 cells in the view). We will instantiate this as our 'lifeMeter' view.

Once you have your view created, add this code to your room script:

Code:
   (local
        flag
    )
 
    (instance public rm001 of Rm
       (method (init)
           ...
           (lifeMeter:init())      // display the life meter on the screen
           = flag FALSE            // init the flag variable
       )
 
       (method (doit)
           (super:doit)
                // when we hit particular cells in the view, display messages to the user
		(switch (lifeMeter:cel())
		   (case 35
		   	   (if (not flag)
		   	      Print("You don't feel so well.")
		   	      = flag TRUE
			   )
		   )
		   (case 70
		   	   (if (not flag)
		   	      Print("You are doubling over in pain.")
		   	      = flag TRUE
			   )
		   )
		   (case 95
		   	   (if (not flag)
		   	      Print("Death is imminent.")
		   	      = flag TRUE
			   )
		   )
		   (case 100
		   	   (if (not flag)
		   	      Print("You are dead.")
		   	      = flag TRUE
			   )
		   )
		   (default               // need this so that for the 10 seconds that this cell is active
		   	   = flag FALSE   // for the states specified in the switch above that the message is
                                          // only displayed once
		   )
		)
        )			
    )
 
    (instance RoomScript of Script
      (method (changeState mainState)
           (var currentCel)
           = seconds 10  // wait 10 seconds
           = currentCel (lifeMeter:cel())   // get the current cell of the health meter view
           (lifeMeter:setCel(+ currentCel 1))  // advance to the next view in the cell, life meter is now shorter
      )
    )
 
    (instance lifeMeter of Prop (properties y 8 x 165 view 11))  // meter located top-center of screen

 

Basically, the changeState() method runs continuously, every 10 seconds it shortens the health bar by advancing the view to the next cell. The doit() method waits for the view to hit certain cells, and when it does it alerts the user of their failing heath.

Obviously, this is a really simple implementation, suitable perhaps if the ego is poisoned and steadily losing health, or maybe dying from starvation. If you wanted something that was more 'event-driven', you could go without the changeState() entirely, and handle the changing of the lifeMeter view through specific events in your game (monster attack, ego touches a particular control color, etc).


With regard to heap/hunk space consumption:
Looks like it loads the whole view into 'hunk space' upon init. Which in my case consumed 31K (which is the size of the view reported by Companion), but I still have plenty of hunk left (128K) and that's with lots of other views already init()ed. Doesn't seem to matter whether the view cycles or doesn't, no change there.


To see a full implementation (with source code) of the health meter described here, see 120 Degrees Below Zero