Basic advice about the best why to setup in-game Doors

Started by JackAnimated, Thu 07/02/2019 05:29:56

Previous topic - Next topic

JackAnimated

In my project there are Doors in rooms, some are locked but become unlocked later, and visa versa.

What is the best why of setting this up?

Hotspots with conditions, regions with conditions, objects or even completely new room copies with different hotspots?

I'm not sure the best way to go forward.

What is your preference and why please?

Thanks.

Khris

The best approach is usually to replicate real life. The door is an object, and there's a separate walkable area below / behind the door that is disabled initially.
Interacting with the door opens it, i.e. changes the object's sprite and enables the walkable area. This is a good solution if the room design should make it possible for the character to actually pass through the doorway. A region behind the door triggers the room change if walked onto.

Or, if the door is a room exit, one could use special walkto cursor behavior to process a click on it, and send the player to another room (or not) based on the door's state.

It really only gets tricky if you have multiple playable characters and doors that can be accessed from both sides.

JackAnimated

Ok interesting, so the situation in my game is:

The game is in first person perspective and generally I have hotspot over open doors, which when clicked upon take the player to the next room. If I wanted one of these locked or closed, is it possible to have a hotspot be disabled and then activated later after an event or item pickup for example?

Slasher

Yes, you can enable/disable a hotspot...

EX
Code: ags

 hotspot[1].Enabled=true;





JackAnimated

Quote from: Slasher on Thu 07/02/2019 08:09:02
Yes, you can enable/disable a hotspot...


Thank you. Regarding my game setup that its first person and I will be painting full backgrounds including interactable objects within the same painting, are hotspots the best way to go for to make interactable areas for them also?

Slasher

If everything, including interactable elements then yes you can..  But you should not ignore using objects like doors....Objects are drawn over hotspots...in which case it would be when you click on a door to open/close the door..

JackAnimated

So if an object of a door was over a doorway with a hotspot, when clicking on the object the hotspot would not register a click?

Slasher

The hotspot would not register the click if the door was over the hotspot directly.

If the doorway itself was transparent then the click would register if the actual door was open..


JackAnimated

So the object blocks clicking on the hotspot but does not stop action set when the cursor hovers over the hotspot.

My solution is to disable the hotspot when at a certain "chapter act" of my story which coincides with the object being in place. So chapter_act is a global variable.

However my code in the room does not seem to effect the ability of the hotspot:

Code: ags
function room_Load()
{
  if (chapter_act == 1)
  {
  hHotspot3.Enabled = false;
  }
}


What's wrong here?

JackAnimated

It appears that room_load is not working. I tried with function room_AfterFadeIn() and it worked fine.

Crimson Wizard

Quote from: JackAnimated on Thu 07/02/2019 10:14:39
It appears that room_load is not working.

Did you connect the room_Load function to appropriate event in the room events pane?
https://www.adventuregamestudio.co.uk/manual/acintro3.htm

JackAnimated

Ok, that works.

It's a little fussy if you have already scripted it, then add the event, it won't like it.

Khris

Objects cover hotspots when it comes to interactions / clicks, unless the Object is set to be not clickable, in that case the click registers on the hotspot.

The best setup depends on how exactly you want this to work. A hotspot is typically a part of the background image that won't undergo visual changes, like the sky, or a couch standing against the back wall.

You could make the doorway a part of the background, draw a hotspot there, then have a click on the hotspot change the room. Then you cover the hotspot with a door object. Interacting with the door object changes its graphic to an open door sprite, exposing the hotspot in the process (transparent areas of the sprite assigned to an object don't catch clicks either).

Objects can be turned invisible at any point, hotspots can be disabled.

JackAnimated

ok thanks. How would one write a script that changes a cursor when hovering over an object? I've done it for hotspots but seems not be more tricky for objects.

Danvzare

#15
I remember, this used to be the hardest thing for me to code. I used to do something really complicated that involved the open door being an object, and disabling a hotspot. It was really bad.

Nowadays though, I've managed to shove everything into a simple function.
Code: ags
function InteractDoor(this Object*, int closed, int open, int walkX, int walkY, int faceX, int faceY, int gotoRoom, int roomX, int roomY, bool unlocked)
{
  if(this.Graphic == open)
  {
    player.Walk(walkX, walkY, eBlock);
    player.FaceLocation(faceX, faceY, eBlock);
    if(player.x == walkX && player.y == walkY)
    {
      player.ChangeRoom(gotoRoom, roomX, roomY);
    }
    else
      player.Say("I can't get there.");
  }
  else
  {
    player.Walk(walkX, walkY, eBlock);
    player.FaceLocation(faceX, faceY, eBlock);
    if (player.x == walkX && player.y == walkY)
    {
      if(unlocked == false)
      {
        player.Say("The door is locked.");
      }
      else
      {
        this.Graphic=open;
        aDoorOpen.Play();
      }
    }
    else
      player.Say("I can't get there.");
  }
}

To explain it, a typical door might use something like this:
oDoor.InteractDoor(48, 49, 120, 150, 120, 130, 2, 244, 135, true);

The closed and open variables, are for the respective door sprites.
The walk and face variables, are there to get you to walk to the door, and face towards it.
The gotoRoom and room variables, are there to say which room it'll take you to, and at which coordinates.
The unlocked variable, is pretty self explanatory. You can easily use a room variable to fill that bit in, and have it change when you use a key object on the door.

It might seem a bit of an intimidating function. And it could probably do with some refactoring. But it works for me. And I just typically copy and paste that function into all of my projects now. It is for the two-click interface though.

TLDR: To put it more simply for you. Have one door object, that just changes between an open sprite and a closed sprite, and just check which sprite it currently is, to determine whether you should open it or go through it. Don't go messing around with hotspots, regions, and walkable areas. You just need one door object, two sprites (of the exact same size), and a check to see which sprite the door currently is.


Quote from: JackAnimated on Thu 07/02/2019 14:12:48
ok thanks. How would one write a script that changes a cursor when hovering over an object? I've done it for hotspots but seems not be more tricky for objects.
You don't need a script for that. You can set that up in the cursors. As there is an option to "animate" and to "animate only on hotspots"
So just experiment with that a little bit.

Khris

Quote from: JackAnimated on Thu 07/02/2019 14:12:48
ok thanks. How would one write a script that changes a cursor when hovering over an object? I've done it for hotspots but seems not be more tricky for objects.
Again, it depends. Mostly on whether you need this as global behavior for many objects game-wide, or just for a single object.

If you want a cursor change for several, specific objects (say the cursor is supposed to turn into an exit sign while hovering over door objects), it's best to create a custom property and write code accordingly. For a single object you just need a bunch of lines in Room_RepExec.

JackAnimated

Thanks for the help and different ideas everyone!

Quote from: Khris on Thu 07/02/2019 15:29:53
Quote from: JackAnimated on Thu 07/02/2019 14:12:48
ok thanks. How would one write a script that changes a cursor when hovering over an object? I've done it for hotspots but seems not be more tricky for objects.
Again, it depends. Mostly on whether you need this as global behavior for many objects game-wide, or just for a single object.

If you want a cursor change for several, specific objects (say the cursor is supposed to turn into an exit sign while hovering over door objects), it's best to create a custom property and write code accordingly. For a single object you just need a bunch of lines in Room_RepExec.

This is what I have in my global script, unfortunately to zero effect:

Code: ags
 Object*o = Object.GetAtScreenXY(mouse.x, mouse.y);
    if (o == object[1])
    {  
    Mouse.UseModeGraphic(2); 
    } 

SMF spam blocked by CleanTalk