text following the mouse

Started by fanton, Wed 19/05/2004 02:32:40

Previous topic - Next topic

fanton

I have this code

function repeatedly_execute() {
Ã,  if(mouse.x >= 215 && mouse.y >= 218)
Ã,  Ã,  SetGUIPosition(LABEL, 215, 218);
Ã,  else if(mouse.x >= 215)
Ã,  Ã,  SetGUIPosition(LABEL, 215, mouse.y);
Ã,  else if (mouse.y >= 218)
Ã,  Ã,  SetGUIPosition(LABEL, mouse.x - 50, 218);
Ã,  else
Ã,  Ã,  Ã, SetGUIPosition(LABEL, mouse.x - 50, mouse.y);
}

If i would use variables instead of doing it this way, would it be slightly faster or slightly lower. I know we won't see the diffrence, because of fast computers we use this day. A 386 might see a diffrence. But I am curios.

or doing it this way

int LABELx;
int LABELy;

function repeatedly_execute() {

Ã,  if(mouse.x >= 215 && mouse.y >= 218) {
Ã,  Ã,  Ã, LABELx = 215;
Ã,  Ã,  Ã, LABELy = 218Ã,  Ã, 
Ã,  }
Ã,  else if(mouse.x >= 215) {
Ã,  Ã,  Ã, LABELx = 215;
Ã,  Ã,  Ã, LABELy = mouse.y;
Ã,  }
Ã,  else if (mouse.y >= 218) {
Ã,  Ã,  Ã, LABELx = 215;
Ã,  Ã,  Ã, LABELy = mouse.y;
Ã,  }
Ã,  else {
Ã,  Ã,  Ã, LABELx = mouse.x - 50;
Ã,  Ã,  Ã, LABELy = mouse.y;
Ã,  }

Ã,  Ã,  Ã, SetGUIPosition(LABEL, LABELx, LABELy);
}

my guess is that the first one is slightly faster. By 2 clock cycles let's say :P Since i am doing a test, as in the second one, but i am also calling a function which copies the three values and return something. Now in the second one, i am using two spaces for ints in memory, then i am doing the test, assigning values to ints, then calling the functions, copying the values, etc, etc.

Which one would be faster?

P.S. this is my indy-like mouse-label instead of statusbar. Whoever needs the code may use it as long as he is lazy to make one himself. All you need is a transparent gui of 100w x 22h with a label of the same size and the text centered. Put @overhotspot@ in the label. and to make the gui transparent just change the GUI background color to ZERO and outline to ZERO. and you're done :P

It's tested and works. I did not test the second one, but it makes sense, except errors which might occur.

[edit] the GUI must be called "LABEL" and it only works for a viewport of 320x240. that is 320 x 240 and 640 x 480 resolutions.

strazer

The first one is probably a fraction of a nanosecond faster, since if any of the conditions in the second example is true, it would have to execute 3 lines of code instead of one (LABELx and LABELy in addition to SetGUIPosition).

A related question:
I have often wondered if it is wise to use local variables in the rep_ex at all.
Declaring and destroying variables 40 times a second somehow doesn't feel right... :)

fanton

that is my exact feeling. i am against using a lot of unecessary variables. but repeatedly execute runes i don't know how many times per second. you said 40.

well. both ways work. but i see people delcaring a lot of variables for uncessesary operations. ex:

x = strlen("hello") - 5;
function(1 + x);

instead of doing
function(1 + strlen("hello) - 5);
/* which is exacty the same thing except that you are not using up memory. */

it might seem silly. but when you have a milin ints in this way, and 4 bytes for each int you would consume about 1 mega of ram. which is not much. who cares anyways :P with the new computers you have 1 GB ram. oh well. back to the OLD-drawing board :D

my guess was first one as well.

Kweepa

For this sort of code which only runs once a frame it's not really relevant which is faster - the game is doing hundreds of thousands if not millions of operations to draw the screen, so a hundred here or there makes no odds.

As for the local variables, I don't know how AGS's scripting language works internally but generally, there is a pre-allocated "stack" (like a tall set of shelves) and when you create a local variable it is added to the first empty shelf from the bottom. When you leave a function, or part of a function (between {}) any shelves that were used are emptied, by changing the "pointer" to the first empty shelf back to the value it had before you entered the {}. This happens whether you have used local variables or not.

The point is that for 95% of game code it's more important to be legible than fast, because you're not going to make it much faster anyway, particularly if you don't know how it works (like me - I'm just guessing).

Steve
Still waiting for Purity of the Surf II

fanton

strazer, your font gives me an error when i try to open it from SCI Studio. I have version 3.01 I will try importing it into the game. Importing it into the game is weird. Both fonts are outlines only. I tried using the font in the game. It works, but both fonts are OUTLINES :P Changing the colour would change the outline and the core would be transparent, since there is none.

SteveMcCrea, yes well. my guess was that the game has functions to declare extra variables. Simmilar to link-lists or malloc or calloc functions where you can declare arrays or reserrve memory in the middle of the program. I don't think that for UNKNOWN variables there are spaces in memory. The restrictions for 2000 dialogue options, 255 rooms, and so forth are because of there initial internal declarations/initialisations. But also there is a restriction for ints. I don't know so you are probably right. Which means that if you use 1 variable or 10 variables, it still works like using 10 variables.  Or it might be that it throws out the unused ones and works like 1 :P i don't know. never-mind

Scorpiorus

Yeah, the difference is close to zero. But, as Steve pointed out, it is very important to keep your code readable, thus it prevents from possible mistakes, bugs and misinterpretations. For instance, the code you provided works well:

function(1 + strlen("hello") - 5);

but doing it that way:

function(-5 + 1 + strlen("hello"));

will return a wrong result, since AGS would parse the last line as:

-(5 + (1 + strlen("hello"))) = -11

whereas we are expecting ((-5 + 1) + strlen("hello")) = 1

That behavior was already discussed before.
So, it's better to have an extra temporary variable.

Having local vars within repeatedly execute is ok. What would really slow down the game is having a couple of RawDrawFrameTransparent()-like procedures drawing at 800x600 res.

It is that functions which should be placed under a certain if-statement to reduce slowdowns to the minimum.

Of course some optimization may be required if the repeatedly_execute runs a fairly continuous loop, but again we can't make much with the script language only.

As for original script you can reduce the number of comparisons by writing it:

if (mouse.x >= 215)
   if (mouse.y >= 218)    SetGUIPosition(LABEL, 215, 218);
   else         SetGUIPosition(LABEL, 215, mouse.y);
else
   if (mouse.y >= 218)    SetGUIPosition(LABEL, mouse.x - 50, 218);
   else          SetGUIPosition(LABEL, mouse.x - 50, mouse.y);

Furthermore, you may want to check GUIs coordinates first and don't call SetGUIPosition() every game loop at all.
But the thing is that you can conserve much more resources by reducing the size of a certain graphic overlay for example.
Therefore such optimizations don't relly necessary.

strazer

QuoteIt works, but both fonts are OUTLINES

Don't know how this happened. ???
Luckily, it wasn't the other way around, so it is fixed now.

Thanks for letting me know!

And I've used SCI Studio 1.50.

fanton

#7
strazer. nice font by the way :P It's big but perfect for large-resolution games. the last version of sci studio has a BIG problem. it crashes after some time. bad management of resources? i will have to talk with the sci creator somehow.

[edit] strazer, i also have an outline for the smallest font in the game. 8 px height. the outline version i think is 9 px. in the SCI pack it was font.030. i have made font.035(normal) and font.036(outline). i just don't have space yet stince i don't have a webpage yet. but if anyone wants them i'll e-mail them to whomever needs.

but. Scorpiorus. i have FURTHER questions:

1. having a hi-colour palette makes a big diffrence? i mean, the same game using the same sprites but one with 256 colours and the other with 16 million. would that make a BIG diffrence? or a smaller diffrence :P

2. a lot of variables would reduce game speed?

3. having many guis would slow down the game? a lot or little. i know that i depends on the guis. for example, i have a game with 4 guis simmultaneously (i hope i spelt that right). one for mouse-label, actions, and two other buttons. now. adding the inventory screen and the menu makes 6.

4. how do you turn off the repeatedly execute?

and lastly. i have this scrips

if(mouse.x >= 188 && mouse.x <= 201)
Ã,  Ã,  Ã,  SetLabelText(LABEL, 0, "Talk to");
Ã,  Ã,  else if(mouse.x >= 204 && mouse.x <= 224)
Ã,  Ã,  Ã,  SetLabelText(LABEL, 0, "Look at");
Ã,  Ã,  else if(mouse.x >= 231 && mouse.x <= 254)
Ã,  Ã,  Ã,  SetLabelText(LABEL, 0, "Move");
Ã,  Ã,  else if(mouse.x >= 257 && mouse.x <= 270)
Ã,  Ã,  Ã,  SetLabelText(LABEL, 0, "Pick up");
Ã,  Ã,  else // (mouse.x >= 293 && mouse.x <= 306)
Ã,  Ã,  Ã,  SetLabelText(LABEL, 0, "Use");

[edit] for this to make sens imagine this in the bottom right corner.

Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, < y = 201
Ã,  [talk to] [look at] [pick up] [use]Ã,  Ã, |
^ ________________________________|
x =188

which sucks :P what I am trying to do is to have a LABEL that follows the mouse (using first code). and display some text accordingly when mouse is over. now, i have not seen anything related to OVER except in the gui creation (image when mouse over).

The problem is that having two guis i have two such scripts. it only works, partially for the second one and the label stays forever in the mode last used.

Ex: if i put my mouse over pickup, and the text label now is "Pick up" when i go outside those regions, and try to click around, the text remains "pick up" that makes sence since i do not kill the label when it exits. but i am struggling to make this work.

i see some games work this way.

in my game the mouse-label is VERY VERY important. i have text for everything. how would i be able to display a specific text without going to. oh wait. i think i know. using a string buffer, and use the buffer instead of raw text. whenever one tries to do something, change the buffer :P

let me try it.

[edit]

The whole repeatedly execute:

function repeatedly_execute() {
Ã, 
Ã,  // mouse-label
Ã,  if(mouse.x >= 265 && mouse.y >= 204)
Ã,  Ã,  SetGUIPosition(LABEL, 215, 210);Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  // |Ã,  Ã,  label _|
Ã,  else if(mouse.x <= 50 && mouse.y >= 204)
Ã,  Ã,  SetGUIPosition(LABEL, 0, 210);Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  // |_ labelÃ,  Ã,  |
Ã,  else if(mouse.x <= 50)
Ã,  Ã,  SetGUIPosition(LABEL, 0, mouse.y + 6);Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  // | labelÃ,  Ã,  Ã, |
Ã,  else if(mouse.x >= 265)
Ã,  Ã,  SetGUIPosition(LABEL, 215, mouse.y + 6);Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  // |Ã,  _label_Ã,  |
Ã,  else if (mouse.y >= 204)
Ã,  Ã,  SetGUIPosition(LABEL, mouse.x - 50, 210);Ã,  Ã,  Ã,  Ã,  Ã,  Ã, // |Ã,  Ã,  Ã, label |
Ã,  else
Ã,  Ã,  Ã, SetGUIPosition(LABEL, mouse.x - 50, mouse.y + 6);Ã,  // |Ã,  Ã, labelÃ,  Ã, |

Ã,  // inventory button (the bag)
Ã,  if(mouse.x <= 52 && mouse.y >= 210) {
Ã,  Ã,  GUIOn(BAG);
Ã,  Ã,  SetLabelText(LABEL, 0, "Inventory");
Ã,  }
Ã,  else {
Ã,  Ã,  GUIOff(BAG);
Ã,  Ã,  SetLabelText(LABEL, 0, "@overhotspot");
Ã,  }

Ã,  // actions barÃ,  Ã, 
Ã,  if(mouse.x >= 188 && mouse.y >= 218 && mouse.x <= 320) {
Ã,  Ã,  GUIOn(ACTIONS);
Ã,  Ã,  if(mouse.x >= 188 && mouse.x <= 201)
Ã,  Ã,  Ã,  SetLabelText(LABEL, 0, "Talk to");
Ã,  Ã,  else if(mouse.x >= 204 && mouse.x <= 224)
Ã,  Ã,  Ã,  SetLabelText(LABEL, 0, "Look at");
Ã,  Ã,  else if(mouse.x >= 231 && mouse.x <= 254)
Ã,  Ã,  Ã,  SetLabelText(LABEL, 0, "Move");
Ã,  Ã,  else if(mouse.x >= 257 && mouse.x <= 270)
Ã,  Ã,  Ã,  SetLabelText(LABEL, 0, "Pick up");
Ã,  Ã,  else // (mouse.x >= 293 && mouse.x <= 306)
Ã,  Ã,  Ã,  SetLabelText(LABEL, 0, "Use");
Ã,  }
Ã,  else {
Ã,  Ã,  GUIOff(ACTIONS);
Ã,  Ã,  SetLabelText(LABEL, 0, "@overhotspot");
Ã,  }
}

I am trying to work my way trough but i cannot make it to work. And i would have required a such label for each inventory item.

Scorpiorus

Quote from: avatar on Wed 19/05/2004 16:58:011. having a hi-colour palette makes a big diffrence? i mean, the same game using the same sprites but one with 256 colours and the other with 16 million. would that make a BIG diffrence? or a smaller diffrence :P
Although it is possible to have paletted images in the hi-color game, AGS doesn't officially support it and therefore that can be changed at any time. It really is a sideaffect, because AGS uses Allegro library which has functions to manipulate images stored at different color depths. Apart from the possibility of palette effects and taking less disk space I see no other reasons to mix hicolor and paletterized images. Actually, I think such combination would reduce performace due to the fact that you can't just blit a 8bit sprite onto 16bit destination bitmap (because they stored in different ways).

Quote2. a lot of variables would reduce game speed?
Variables themselves do not reduce the game speed. They just take more memory. It is the code (which manipulates these variables) that may reduce it.

Quote3. having many guis would slow down the game? a lot or little. i know that i depends on the guis. for example, i have a game with 4 guis simmultaneously (i hope i spelt that right). one for mouse-label, actions, and two other buttons. now. adding the inventory screen and the menu makes 6.
Don't worry about them. Unlike characters or objects they don't need to be checked for walkbehinds and therefore GUIs are drawn relatively fast.

Quote4. how do you turn off the repeatedly execute?
Just put a conditional:

int IsRepExecEnabled = 1;
function repeatedly_execute() {
if (IsRepExecEnabled) {

// your code here


}
}

You can set a IsRepExecEnabled variable to 0 when you want the engine to skip all code within repeatedly_execute.


4.

If I get it right, you want a label not only for hotspots, characters and objects but also for the inventory items and GUI buttons, right?

Again, the repeatedly_execute saves us :)

function repeatedly_execute() {

   int gui = GetGuiAt(mouse.x, mouse.y);
   if (gui > -1) {

      int button = GetGUIObjectAt (mouse.x, mouse.y);
      if (button > -1) {

         if    (button == 0) SetLabelText(..., "use");
         else if (button == 1) SetLabelText(..., "talk");
         else if (button == 2) SetLabelText(..., "move");
         else if (button == 3) SetLabelText(..., "look");
      }
      else {
         int item = GetInvAt(mouse.x, mouse.y);
         if (item > 0) {

            string itemName;
            GetItemName(item, itemName);
            SetLabelText(..., itemName);
         }

      }


   }

}

fanton

#9
YEEEEEEEEEEEEES. THANK YOU. That was what i needed. THANK YOU VERY MUCH. No need to yell :P but THANK YOU. I am happy :)))))))))))

This part was taken from the previous post. And put here.

[cut and paste from previous post] I think i have found a way to switch the gui on and off without turning it "I don't know how many" times per second.

Using a flag to swich between the on and off states.

int BagFlag = 1;

function repeatedly_execute() {

// (the bag)

Ã,  if(mouse.x <= 52 && mouse.y >= 210) {
Ã,  Ã,  if (BagFlag == 0) {
Ã,  Ã,  Ã,  GUIOn(BAG);
Ã,  Ã,  Ã,  BagFlag = 1;
Ã,  Ã,  }
Ã,  }
Ã,  else {
Ã,  Ã,  if (BagFlag == 1) {
Ã,  Ã,  Ã,  GUIOff(BAG);
Ã,  Ã,  Ã,  BagFlag = 0;
Ã,  Ã,  }
Ã,  }

// close of repeatedly_execute
}

^^ This script will switch between the two states in repeatedly execute. a way to close the repeatedly execute for some things. if you make a BIG if statement, you have an open or close switch for repeatedly execute :P Sorry for the long post. [end of cut paste]

Now. Playing around withÃ,  the flag I have found a way to toggle between two guis.Ã,  I don't know who might need this but here goes.

int Flag = 1; // 1 = on 0 = off

function repeatedly_execute() {

//GUI 1
if (mouse.x <= 40 && mouse.y >= 200) {
Ã,  if (Flag == 0) {
Ã,  Ã,  Ã,  GUIOn(BAG);
Ã,  Ã,  Ã,  Flag = 1;
Ã,  Ã,  }
elseÃ,  {
Ã,  Ã,  if (Flag == 1) {
Ã,  Ã,  Ã,  GUIOff(BAG);
Ã,  Ã,  Ã,  Flag = 0;
Ã,  Ã,  }
}
if(mouse.x >= 280 && mouse.y >= 200) {
Ã,  if (Flag == 0) {
Ã,  Ã,  Ã,  GUIOn(CRATE);
Ã,  Ã,  Ã,  Flag = 1;
Ã,  Ã,  }
elseÃ,  {
Ã,  Ã,  if (Flag == 1) {
Ã,  Ã,  Ã,  GUIOff(CRATE);
Ã,  Ã,  Ã,  Flag = 0;
Ã,  Ã,  }
}
//end of function
}

what this does is:

when mose is over the 40 px rectangle in the bottomleft it turns BAG on and STAYS. when the mouse is switched to the right 40 pixels in the corner down of the screen the CRATE gui turns on, the other turns off. the nice thing is taht it stays on. one could use this to use a small space for a HUGE gui to appear. and another small space for the gui to dissappear.

I am not shure about the suefullness of this code :P It is testest and it works. Only if I have made a mistake.

Now, taken only half of it, would toggle a single gui on and off when mouse is over and on. I tried this and it still works. The nice thing is taht it toggles the gui on or off ONCE only. i used to toggle it 40 times per second before.

TerranRich

So is this resolved? I could move this to the Technical Archive if so. :)
Status: Trying to come up with some ideas...

fanton

#11
I have found something else!!!

Inventory items behave like hotspots :P
Having the label with @overhotspot@ over and item would display the item's name. Therefore you might not need the code above.

Ok, move it to technical archive, if you think this is usefull.

SMF spam blocked by CleanTalk