Diagonal Stairs

Ask and answer questions about making games and related topics. Unrelated topics go in that other forum.

Moderators: marionline, SDHawk

splendidland
Red Slime
Posts: 42
Joined: Tue Feb 19, 2013 11:06 am
Contact:

Diagonal Stairs

Post by splendidland »

Hello, I'm currently working on a new large project, and an area I'm currently working on ideally should contain some diagonal staircases.

I've managed to make them work before in my previous game "Megaman Sprite Game", but the main problem with them was that they were one way, and once you started moving up the stairs, you could never go back down, I've never used the 'if' functions before and I'm having a hard time with this.

In my previous game, the stairs were simply a chain of invisible NPC's. You'd step on one, which would suspend the player, and then wait for them to press the Right Arrow key, which would make them walk right and up one tile, which would send them to the next NPC and activate it again, and so on until you reached the top where another script would resume the control.

It worked nicely enough given the linearity of the game, especially because it was in the final dungeon area which was full of sections that prevented the player from returning to where they came from, but the game I'm working on now has a much bigger emphasis on exploration so it's not ideal at all.

I'm aware I'll have to make different scripts based on the oreintation of the stairs, but basically what I need help making is something that suspends the player, and makes them move in different directions based on what key is pressed, currently up and left, and down and right.

I hope I explained this well enough, I can expand on this if needed! Thanks in advance.
User avatar
Fenrir-Lunaris
Metal Slime
Posts: 768
Joined: Mon Oct 15, 2007 10:45 pm
Location: OHR Depot

Post by Fenrir-Lunaris »

I've used something like this:

Code: Select all

script,upleftstairs,begin
	set tag (tag:stairs,on)
	suspend player	, suspend hero walls
	walk hero (me,up,2), walk hero (me,left,2), wait for hero (me)
	set tag (tag:stairs,off)
	resume player , resume hero walls
end

script,uprightstairs,begin
	set tag (tag:stairs,on)
	suspend player	, suspend hero walls
	walk hero (me,up,2), walk hero (me,right,2), wait for hero (me)
	set tag (tag:stairs,off)
	resume player , resume hero walls
end

script,downleftstairs,begin
	set tag (tag:stairs,on)
	suspend player	, suspend hero walls
	walk hero (me,down,2), walk hero (me,left,2), wait for hero (me)
	set tag (tag:stairs,off)
	resume player , resume hero walls
end

script,downrightstairs,begin
	set tag (tag:stairs,on)
	suspend player	, suspend hero walls
	walk hero (me,down,2), walk hero (me,right,2), wait for hero (me)
	set tag (tag:stairs,off)
	resume player , resume hero walls
end
The idea is that there's a step-on activated NPC on the bottom and at the top of each set of stairs that triggers their own diagonal walking script. Firstly they'll turn on the tag that disables all the stair NPCs simultaneously. Then depending on which script was run, the hero will walk beyond the edge of the stairs one space beyond where the corresponding NPC that would send them back was. Finally, it'll turn the tag back on, allowing the hero to go back down/up.
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Wow, looking forward to it!

Those scripts look perfectly functional, but how do they send the player one tile past the end of the stairs? I would expect the scripts to contain, e.g. ...

Code: Select all

walk hero (me,up,2), walk hero (me,left,3), wait for hero (me) 
...that is, an extra horizontal tile. (Also, note that since the command to walk left is the last one, that's the direction that the hero sprite will face).

However, how you draw the stairs will have an effect. I assume that when you're aligned with the topmost tile of the stairs your feet should be just on the edge.
splendidland
Red Slime
Posts: 42
Joined: Tue Feb 19, 2013 11:06 am
Contact:

Post by splendidland »

I'd have no problem making something where the player automatically walks up or down stairs, the main issue I'm having is I'd want the player to maintain control as they walk up. Basically what I need help with is a script that reacts based on whether you press left or right.

What I have currently is this, but it doesn't work at all and the player just gets stuck on the stairs, I really don't have any experience making something that uses the if function!

Code: Select all

plotscript, stairsleft, begin
suspend player

if (key is pressed (key:Left)) then, (walk hero (me, up, 1) walk hero (me,left,1))

else if (key is pressed (key:Right)) then, (walk hero (me, down, 1) walk hero (me,right,1))

end
User avatar
Feenicks
Metal Slime
Posts: 697
Joined: Tue Aug 10, 2010 9:23 pm
Location: ON THE AIR IN THE AIR
Contact:

Post by Feenicks »

I'm not quite sure what the issue is with that script. I'm pretty sure that NPC scripts only trigger once, so asking one for an input will just mess things up.

Anyway, I took a stab at making a stairs script several years ago, but the main problem I ran into with it was that scripts are triggered only after a key is pressed, meaning that you get sent off the grid very quickly.
Basically, what this means is that you'll have to rescript movement/NPC interaction (warps/enemy encounters work fine even with suspend player on, I think) if you want to throw in stuff like stairs; I could take a stab at throwing an example together tonight, if that would be useful for you.
User avatar
Gizmog
Metal King Slime
Posts: 2622
Joined: Tue Feb 19, 2008 5:41 am

Post by Gizmog »

Brotoad wrote:I'd have no problem making something where the player automatically walks up or down stairs, the main issue I'm having is I'd want the player to maintain control as they walk up. Basically what I need help with is a script that reacts based on whether you press left or right.

What I have currently is this, but it doesn't work at all and the player just gets stuck on the stairs, I really don't have any experience making something that uses the if function!

Code: Select all

plotscript, stairsleft, begin
suspend player

if (key is pressed (key:Left)) then, (walk hero (me, up, 1) walk hero (me,left,1))

else if (key is pressed (key:Right)) then, (walk hero (me, down, 1) walk hero (me,right,1))

end
I think this is because it's only checking one time whether or not the player is pressing left or right, and is thus never resuming the player after the suspension. What you're going to want is to set up a while loop to constantly check whether or not the player is still on the stairs.

Code: Select all

#Set this Global Variable to 1 when the player starts into stairs, and 0 when they exit the stairs

GlobalVariable (001,Stairs)


Plotscript,StairsLeft,begin

suspend player

while (Stairs == 1)
do (
 #This might keep the player from getting off the grid.. but it might slime it up too. I dunno!
 waitforhero (me)

 if (key is pressed (key:Left)) then, (walk hero (me, up, 1) walk hero (me,left,1))

 if (key is pressed (key:Right)) then, (walk hero (me, down, 1) walk hero (me,right,1))

 #Wait is needed in this case or else the game will just constantly check   if  you're pressing left or right and freeze
 wait (1)
 )

#If we're in this part of the script, something else must've set Stairs to 0
waitforhero (me)
ResumePlayer
end
User avatar
Bob the Hamster
Lord of the Slimes
Posts: 7660
Joined: Tue Oct 16, 2007 2:34 pm
Location: Hamster Republic (Ontario Enclave)
Contact:

Post by Bob the Hamster »

Are there any walls that the hero could be getting hung up on?

A screenshot of the staircase in the map editor's wallmap mode might help.

Also, if a hero is halfway through walking and you use "walk hero" again, the hero can become misaligned with the tilemap. You might want to use the "hero is walking" command to avoid this:

Code: Select all

if(not(hero is walking(me))) then(
  if (key is pressed (key:Left)) then(
    walk hero (me, up, 1)
    walk hero (me,left,1)
  ) else if(key is pressed (key:Right)) then(
    walk hero (me, down, 1)
    walk hero (me,right,1)
  )
)
EDIT: Oh! You are triggering this from an NPC? listen to the posts above me. I was thinking that this was already part of a while loop or something.
Last edited by Bob the Hamster on Mon Oct 19, 2015 7:09 pm, edited 1 time in total.
User avatar
Feenicks
Metal Slime
Posts: 697
Joined: Tue Aug 10, 2010 9:23 pm
Location: ON THE AIR IN THE AIR
Contact:

Post by Feenicks »

Okay, I'm not sure how much of this will actually work since I haven't tested it yet, but...:

Code: Select all

include, plotscr.hsd
#include, yourGAMEfile.hsi
include, scancode.hsi
 
plotscript,startupScript,begin
#this one goes as a New-game plotscript
suspend player
moveRewrite
#anything else you want to do in the startup script also goes here
end
 
plotscript, moveRewrite, begin
 
variable (playing)
 
playing := true
while(playing) do(
        while(check tag (10)) do( #tag doesn't matter; just turn the one here on when you don't want player movement happening
                switch(zone at spot(hero X, hero Y,0)) do(
                case(1) stairScript(left)       #left stairs
                case(2) stairScript(right)      #right stairs
                case(3) do() #and so on
                case(else) inputReadNormal #default movement
                )
        )
)
 
end
 
plotscript, inputReadNormal, begin
if(not(hero is walking(me))) then(
        if(key is pressed(key:Up)) then(
                walk hero (me, up, 1)
                wait for hero
        )
        else if(key is pressed(key:Left)) then(
                walk hero (me, left, 1)
                wait for hero
        )
        else if(key is pressed(key:Down)) then(
                walk hero (me, down, 1)
                wait for hero
        )
        else if(key is pressed(key:Right)) then(
                walk hero (me, right, 1)
                wait for hero
        )
                else if(key is pressed(key:Space)) then(
                        whatToDoWhenSpaceIsPressed #this is going to more or less be constant, might as well farm it out to another script
)
)
end
 
plotscript, whatToDoWhenSpaceIsPressed, begin
switch(hero direction(me)) do(
case(up) NPCCheck(up)
case(left) NPCCheck(left)
case(down) NPCCheck(down)
case(right) NPCCheck(right)
case(else) do()
)
end
 
plotscript, NPCCheck, heroDirection, begin
switch(heroDirection) do(
        case(up) do(
        use NPC(NPC at spot (hero X, hero Y -- 1, 0))
        )
        case(left) do(
        use NPC(NPC at spot (hero X -- 1, hero Y, 0))
        )
        case(down) do(
        use NPC(NPC at spot (hero X, hero Y + 1,0))
        )
        case(right) do(
        use NPC(NPC at spot (hero X + 1, hero Y, 0))
        )
        case(else) do(
#in the event something horrible happens
        use NPC(NPC at spot (hero X, hero Y, 0))
        )
        #pretty sure touch/step-on NPCs still work fine even with this stuff going on
        #but don't quote me
)
end
 
plotscript, stairScript, stairDirection, begin
if(not(hero is walking(me))) then(
        if(key is pressed(key:Up)) then(
                walk hero (me, up, 1)
                wait for hero
                )
        else if(key is pressed(key:Left)) then(
                suspend hero walls
                if(stairDirection == left) then(
                        walk hero (me, left, 1), walk hero(me, down, 1)
                        )
                else(
                        walk hero (me, left, 1), walk hero(me, up, 1)
                        )
        wait for hero
        resume hero walls
        )
        else if(key is pressed(key:Down)) then(
                walk hero (me, down, 1)
                wait for hero
        )
        else if(key is pressed(key:Right)) then(
                suspend hero walls
                if(stairDirection == left) then(
                        walk hero (me, right, 1), walk hero(me, up, 1)
                        )
                else(
                        walk hero (me, right, 1), walk hero(me, down, 1)
                        )
        wait for hero
        resume hero walls
        )
)
end
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Pheonix's script does more than required, it replaces all player movement in the game with scripted movement (to get around certain engine limitations), but you don't need that you this case.

I would agree that you should use zones to mark where the stairs are, rather than put step-on NPCs at the top and bottom to mark the boundaries. NPCs would not work, because when you are on the edge of the stairs moving left or right should have different effects. For this reason, I think all of the scripts that have been posted so far won't work.

One solution is to use 4 different zones to indicate the 4 different directions diagonal in which you could move. At the end of a set of stairs, you can only go in one of those 4 directions, so there will be a single zone. In the central tiles of stairs (that are more than 1 tile long) there are two diagonal directions, so you would have two overlapping zones.

I combined Pheonix's and James scripts and then did some rewriting:

Code: Select all

include, plotscr.hsd
#include, yourGAMEfile.hsi
include, scancode.hsi


# You only need to call this script once, it will keep running the entire game.
# For example, set as the new-game script.
plotscript, handle stairs, begin
    while(true) do(
        # Have we called a wait command yet?
        variable (waited)
        waited := false

        # Turn tag 999 on when you want to prevent the player movement happening,
        # e.g. whenever you "suspend player" you should also "set tag(999, on)"!
        if&#40;hero is walking&#40;me&#41; == false && check tag &#40;999&#41; == false&#41; then&#40;    ### <--- change me

            if &#40;key is pressed &#40;key&#58;Left&#41;&#41; then&#40;
                # Zone 1 indicates stairs going up-left
                if &#40;read zone&#40;1, hero X, hero Y&#41;&#41; then&#40;
                    walk diagonally&#40;up, left&#41;
                    waited &#58;= true
                &#41;
                # Zone 2 indicates stairs going down-left
                else if &#40;read zone&#40;2, hero X, hero Y&#41;&#41; then&#40;
                    walk diagonally&#40;down, left&#41;
                    waited &#58;= true
                &#41;
            &#41; else if&#40;key is pressed &#40;key&#58;Right&#41;&#41; then&#40;
                # Zone 3 indicates stairs going up-right
                if &#40;read zone&#40;3, hero X, hero Y&#41;&#41; then&#40;
                    walk diagonally&#40;up, right&#41;
                    waited &#58;= true
                &#41;
                # Zone 4 indicates stairs going down-right
                else if &#40;read zone&#40;4, hero X, hero Y&#41;&#41; then&#40;
                    walk diagonally&#40;down, right&#41;
                    waited &#58;= true
                &#41;
            &#41;

        &#41;

        # "walk diagonally" already does a wait, make sure we don't wait a second time,
        # or movement up stairs will stutter.
        if &#40;waited == false&#41; then &#40;wait&#40;1&#41;&#41;
    &#41;
end

# Move the player one tile diagonally while preventing normal movement
script, walk diagonally, up or down, left or right, begin
    suspend player  # Suspend player prevents normal player movement, very important
    suspend hero walls
    walk hero&#40;me, up or down, 1&#41;
    walk hero&#40;me, left or right ,1&#41;
    wait for hero&#40;me&#41;
    resume player
    resume hero walls
end
EDIT: fixed a bug
Last edited by TMC on Tue Oct 20, 2015 11:47 am, edited 3 times in total.
splendidland
Red Slime
Posts: 42
Joined: Tue Feb 19, 2013 11:06 am
Contact:

Post by splendidland »

What I did in my previous game was have multiple NPC's in a diagonal line, so the player would get passed from one to the other, with different scripts at the end for getting off the stairs. I'll be working on my game some more later today so I'll try what Gizmog suggested first!
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

I decided to test the script I posted, and did find a minor bug (fixed in my post above), but otherwise it's fine. I uploaded it here: http://www.slimesalad.com/forum/viewgame.php?p=119127 and copied the scripts to the wiki.
Drawing stairs and getting them to line up with preexisting tiles and the wallmap grid isn't easy! I ended up setting the footoffset to up 14 pixels to mesh comfortably with Fenrir's tiles. Interestingly he used a footoffset of up 5 pixels with this tileset.
splendidland
Red Slime
Posts: 42
Joined: Tue Feb 19, 2013 11:06 am
Contact:

Post by splendidland »

Image

I've been playing around with the diagonal stairs and managed to make something a bit more complicated that I originally planned, (I was originally going to have alternating left and right stairs after each floor) I'm really pleased with how this all works, thank you so much for the help!
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Pleased to hear it, and to see you managed to work out as complicated as that layering.

The title of that game, it almost sounds like a traditional RPG?
splendidland
Red Slime
Posts: 42
Joined: Tue Feb 19, 2013 11:06 am
Contact:

Post by splendidland »

I used a similar layering technique in Megaman Sprite Game's final dungeon area, which had slides and tubes you could walk under at earlier points of the dungeon, I'm still really proud of that area and the game is almost 3 years old now!

As for this game, it's definitely going to be more of a gameplay focused thing than anything I've previously made with OHR, it's about exploring an extensive cave system full of bizaare monsters and has some elements from horror games.

I won't spoil too much since I want people to be suprised by what they discover in the caves, but I've added 2 of the features I've really wanted to have in my previous games, enemies that walk around on the overworld that you have to touch to battle (which I implemented with a very simple script that means I only have to make one NPC per enemy type), as well as a bestiary menu!

Image
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Looks nice; looking forward to it. The art style also reminds me quite a bit of sheamkennedy's.

A note with the diagonal stairs: you might want to ensure that NPCs can't wander onto the top or the bottom of the stairs, or the player would probably be able to walk on top of them (not 100% sure). You can exclude them using zones or step-on NPCs which do nothing.
Post Reply