Safe (locked box) GUI

Started by aedwards00, Sat 13/03/2010 23:39:39

Previous topic - Next topic

aedwards00

Hey, I'm thinking that I would like to create a custom GUI for a safe that I have in a particular room. However, I want it to be a 'classic' safe, with a tumbler lock rather than a keypad.

What I would love is if the player can actually rotate the tumbler by clicking on it and dragging the cursor in a circle, if that makes sense. I've found the entry in the manual on dynamic sprites and how to rotate them, but I'm not sure if/how that can be applied to GUIs. I also don't really know where to begin with the click-dragging part.

I'm not after anyone to write great chunks of code for me, but if someone can point me in the right direction, or at least warn me off if it will be horrendous to code I'd appreciate it.

Thanks  :)

monkey0506

#1
I think there may already be some existing code to provide this type of functionality though I'm not sure and you said you weren't looking for someone to provide you with the full code anyway, so.

Regarding your current line of thinking, a GUI can take advantage of a DynamicSprite by using the GUI.BackgroundGraphic and DynamicSprite.Graphic properties, such as:

Code: ags
// global script
DynamicSprite *lockSprite; // this pointer must be global or the sprite will be deleted!

// turn on GUI (inside some function)
if (lockSprite != null) {
  if (gLock.BackgroundGraphic == lockSprite.Graphic) gLock.BackgroundGraphic = 0; // prevents error about deleting a sprite in use
  lockSprite.Delete();
}
lockSprite = DynamicSprite.CreateFromExistingSprite(NORMAL_LOCK_SPRITE_SLOT);
gLock.BackgroundGraphic = lockSprite.Graphic;


Then for the actual rotation perhaps you could store the current rotation level in a float variable, use the DynamicSprite.Rotate function to process the turning of the lock, and some simple math to determine which is the currently selected number.

I don't imagine it would be that horrible to code something like this. :D

Edit: P.S. Regarding the note about the pointer having to be "global" I just meant global scope within the script. You don't have to import/export it or use the Global Variables pane for the pointer unless you specifically need access to it from multiple scripts. Just be sure the pointer is declared outside of all functions.

aedwards00

Cheers, I had a quick fiddle with it, and so far just got 2 buttons that rotate another image one way or the other. However, the image degrades pretty badly with each rotation :s, it there any way to avoid this with better sprite design, or smaller incremental rotations or something? For now i was just using a test sprite 44x44 pixels - a black outlined white filled circle, with a red cross through it.

Possibly I didnt make it perfectly symmetrical and thats causing the problem

monkey0506

What might be useful to you is if you create static sprites for, say, every 45 degrees and then calculate the appropriate angle first, determine which base sprite to use, and then rotate that sprite appropriately. That would help prevent the image degrading.

I haven't really made much use of DynamicSprite.Rotate so I'm not sure how much a 45 degree rotation might damage your image but I imagine if you were to call Rotate 45 times on the same sprite that might make it exponentially worse. I would also recommend starting with a fresh sprite for each rotation and not using a previously rotated sprite.

aedwards00

#4
Thats a good idea thanks, with my test sprite it seemed fine for 45/90 degree angles, but when i tried 10 for example it got worse and worse as you say. Now I just gotta dig out all that geometry thats buried somewhere in my head, took me 5 mins to remember the equation for a circle  :-\

Edit: In fact come to think of it I guess there's not really much need to have the rotate function at all if I create enough sprites, I guess I just need to find the right balance depending on how many positions I want the tumbler to have.

Edit again: I just know I'm gonna want a switch statement in here somewhere :(

monkey0506

I have never honestly seen the benefit between:

Code: ags
switch (condition) {
  case 1:
    // blah
  break;
  case 2:
    // blah
  break;
  default:
    // blah
  break;
}


And:

Code: ags
if (condition == 1) {
  // blah
}
else if (condition == 2) {
  // blah
}
else {
  // blah
}


Languages that provide fall-through I suppose could have some advantage to it.

But I've personally never felt in my programming with AGS that I have ever needed a switch statement.

Scarab

What you could also have is the number which is currently selected not stored within the sprite itself, but on a label on top, and change it depending on the angle of rotation. That way you will always have a legible number and distortion doesn't really become an issue.

Khris

If you rotate a rotated sprite, it's gonna deteriorate quickly.
You can use my module to avoid that.

SMF spam blocked by CleanTalk