Post new topic    
Page «  1, 2
Liquid Metal Slime
Send private message
 
 PostTue Sep 02, 2014 5:49 am
Send private message Reply with quote
Thanks to everyone here, I've managed to get mostly everything working! I've implemented doors, ladders, walls, music updating based on zones, and animations for both running and climbing. There are of course still bugs, some of which pretty major, but they're quite specific and I don't know how to explain them without just playing the game, so I'd like to post it on the games forum here, but I can't figure out quite how to do that... so some help on that would be appreciated.

One thing I failed to get to work properly are NPC's. They stand in the background and the player runs in front of them, and if they push a certain button (z), they will attempt to interact with anything on the tile they are standing on. Each time the z key is pressed, the game runs this code:

Code:

script, try action, begin
   
   x := slice x(player)
   y := slice y(player)
   
   if(npc at spot(x+10/20,y/20)) then(
      use NPC(NPC reference(npc at pixel(x+10,y)))
   )
end


It only refers to the first NPC the player comes in contact with, which happens to be a one time use, so the action will only perform once while playing. Basically, despite what NPC the player is standing on, it will use the first one. I assume I have to just go about this an entirely different way, but I'm not sure which way will work best.

If you want to download it from Media Fire, I have it there, just not here on Slime Salad.
http://www.mediafire.com/download/le30abrun42cenc/standgame.zip
My pronouns are they/them
Ps. I love my wife
Metal King Slime
Send private message
 
 PostTue Sep 02, 2014 10:33 am
Send private message Reply with quote
To upload a game, go to the www.slimesalad.com/forum/gamelist.php and click create "New Topic". Games are actually threads in that forum. Add one or more archives as attachments, and optionally screenshots.

The problem with that script snippet is that "npc reference" shouldn't be used. It returns an npc reference (handle) given an NPC ID number (and the copy number for that ID). You actually don't need to use it in many situations. npcatspot, npcatpixel, and in fact pretty much every other command returns an npc reference, not an npc id. Feeding an npc reference into "npc reference" returns 0 because it's an invalid ID number*. So "use npc" will activate the first copy of NPC ID 0.

Also, "x+10/20" should be written "(x+10)/20"

Finally, the npcatspot and npcatpixel could return different values because they don't check exactly the same thing.

Code:
script, try action, begin
   x := slice x(player)
   y := slice y(player)
   
   if(npc at pixel(x+10,y)) then(
      use NPC(npc at pixel(x+10,y))
   )
end


* I think I should change it to just return the reference number instead though
Liquid Metal Slime
Send private message
 
 PostWed Sep 03, 2014 12:09 am
Send private message Reply with quote
Come to think of it, I don't know why I was using NPC reference.... I think I overthunk it. Anyway it's fixed now, so thank you for the help. I posted the game on the Games page. It's called Stand if you want to find it. [/s]
My pronouns are they/them
Ps. I love my wife
Metal King Slime
Send private message
 
 PostWed Sep 03, 2014 1:21 pm
Send private message Reply with quote
I just tried out your demo. It looks like it's going to be pretty nice! For some reason I thought that this was only going to be a minigame.

You forgot to include the scripts in the zip. It's possible to extract the scripts from the .rpg file though; I'll have a look into some of the glitchy behaviour later (probably too busy tomorrow though)
Liquid Metal Slime
Send private message
 
 PostSat Sep 06, 2014 6:50 am
Send private message Reply with quote
I posted a new version of the demo with a few more features and this time I remembered the scripts!
My pronouns are they/them
Ps. I love my wife
Metal King Slime
Send private message
 
 PostSat Sep 06, 2014 2:39 pm
Send private message Reply with quote
Looks nice!

OK, I had a look and fixed some things.

Firstly, that pause when you use a door is due to "autosave", which actually brings up the save menu if the game hasn't been saved yet, which you can't see because the screen is faded out. Several different solutions. One is to get the player to pick a save slot when they start the game.

player can left/right (obviously) were broken. I see that the version I posted of the script wasn't suitable for how you wanted to use it. So I pretty much rewrote them. The xv global is needed to communicate where the player is going to be. I did test running. The biggest problem with it is that is makes the camera position lag worse. So I fixed that as well by not using "set slice velocity x", which was a one line fix (see below).

Code:
script, horizontal movement, begin
   if(read pass block(x/20,y/20 +1),and, northwall) then(
      replace walkabout sprite(player,0)
      #set slice velocity x(player,xv,1)
      climbing := false
      vertical align
   )
end

script, try left, begin
   if(want run) then(
      xv := -10
   ) else (
      xv := -5
   )
   if(player can left) then(
      horizontal movement
   ) else (
      # Prevents running animation
      xv := 0
   )
end

script, try right, begin
   if(want run) then(
      xv := 10
   ) else (
      xv := 5
   )
   if(player can right) then(
      horizontal movement
   ) else (
      xv := 0
   )
end

script, player can left, begin
   variable(new tile x)
   new tile x := (slice x (player) + xv) / 20
   # Nothing to do if not crossing a tile boundary
   # (This check is currently unneeded, but it's better to be robust)
   if (new tile x == slice x (player) / 20)
   then (return(true))

   if( read pass block(new tile x, y / 20), and, eastwall
       || read pass block(new tile x + 1, y / 20), and, westwall  # Tile the player is currently on
       || new tile x < 0
   ) then(
      put sprite(player, (new tile x + 1) * 20, slice y(player))
      return(false)
   ) else (
      return(true)
   )
end

script, player can right, begin
   variable(new tile x)
   new tile x := (slice x (player) + 19 + xv) / 20
   # Nothing to do if not crossing a tile boundary
   # (This check is currently unneeded, but it's better to be robust)
   if (new tile x == (slice x (player) + 19) / 20)
   then (return(true))

   if( read pass block(new tile x, y / 20), and, westwall
       || read pass block(new tile x -- 1, y / 20), and, eastwall  # Tile the player is currently on
       || new tile x >= map width
   ) then(
      put sprite(player, (new tile x -- 1) * 20, slice y(player))
      return(false)
   ) else (
      return(true)
   )
end


Then in front of the block in the main loop that sets the camera position, add
Code:
   put slice(player, slice x(player) + xv, slice y(player))

Note that I commented out the "set slice velocity x" line.

Might have a look at the ladder problems tomorrow.
Liquid Metal Slime
Send private message
 
 PostFri Sep 19, 2014 5:51 am
Send private message Reply with quote
I have updated the demo with a bunch of new things. Ladders still don't work perfectly, but it's getting there.
My pronouns are they/them
Ps. I love my wife
Metal King Slime
Send private message
 
 PostFri Sep 19, 2014 2:07 pm
Send private message Reply with quote
Oh, nice to see you're still around. I was about to ask what had become of you. Now that I know you haven't disappeared, I'll have another look.
Metal King Slime
Send private message
 
 PostSat Sep 20, 2014 9:21 am
Send private message Reply with quote
First of all, I notice ESC doesn't work properly. It's because you need to only open the menu on a new keypress rather than if the esc key is down. Replace
Code:

   if(key is pressed(key:esc)) then(
      open menu(0)
   )

with
Code:

   if(keyval(key:esc) > 1) then(
      open menu(0)
   )

Also, your help note says Alt is meant to work as well.
Unfortunately if you want to open/close the main menu using an Alt key the correct
way to do so isn't obvious. Use key:filtered alt instead of key:alt, because that's
what the engine does (you want to avoid reopening the menu if the player tries to close it with alt):
Code:

   if(keyval(key:esc) > 1 || keyval(key:filtered alt) > 1) then(
      open menu(0)
   )

You might also like to prevent the main menu from being openable in the middle
of a textbox.
It would also be nice if pressing Z a second time, or moving while a textbox is up,
closed the textbox.

The player is meant to equip the hatchet after they pick it up, right? It mgiht be a good
idea to explicitly tell them to do so, or even do it automatically, as Spoonweaver did
in his recent Troll Quest.

I noticed door triggering is lopsided: they trigger at the point that the left
edge of the hero enters the door tile. Yuo can fix that by replacing
"x/20,y/20" in "auto door" with "(x+10)/20,(y+10)/20" (actually there's no
need to round the y coordinate for this jumpless game).

I also noticed that the hero continues moving for one tick after entering their house.
This glitch is because xv is non-zero and the player position isn't updated
until after "auto door". One solution is to reset the speed and animation in "auto door",
somewhere before the "wait(2)", eg.:
Code:

         ... #(in auto door)
         put sprite(player,get door x(new door)*20,get door y(new door)*20)
         x := slice x(player)
         y := slice y(player)
         # Add these:
         xv := 0
         update frame
         ...


Now, the ladders. What I didn't realise at first was that ladder climbing is tile based
movement, while horizontal movement isn't; a bit tricky.
As before, to prevent camera glitches, I decided it would be better
to stop using "move slice by" and instead use yv. Also, I added
a new global, "y move ticks" which counts the number of ticks of
vertical movement to perform. Unlike xv, yv shouldn't be reset at the end of
the main loop. I also fixed various bugs that occur when you press
keys at once while climbing with better guards around try left/right/up/down.

I also moved things around into what looked like a better ordering. Best to first handle controls, then update player position, and then update the sprite.

Note: you could get rid of the "climbing" global if you wanted, it's redundant
and a possible source fo bugs due to being out of date. In my copy it's not
used anywhere except the main loop
Code:

# Contents of the main loop:
      #Movement
      if(yv == 0) then(  # Not climbing
         if(want left) then(
            try left
         )
         if(want right) then(
            try right
         )
      )
      if(xv == 0 && yv == 0) then(  # Not climbing or moving
         if(want up) then(
            try up
         )
         if(want down) then(
            try down
         )
      )
      if(want action) then(
         try action
      )
      
      #### Update position
      put slice(player,slice x(player) + xv, slice y(player) + yv)
      x := slice x(player)
      y := slice y(player)
      put camera(x--160,y--120)
      if (yv) then (
         y move ticks -= 1
         if (y move ticks == 0) then (yv := 0)
      )

      #### Update sprite

      # You're climbing if you're not standing on the ground
      if (y, mod, 20 <> 0 || (read pass block(x/20,y/20+1), and, northwall) == false) then (
         climbing := true
      ) else(
         climbing := false
      )

      if(climbing) then(
         update climb frame
      )
      else(
         update frame
      )
      
      #Reset
      want left:=false
      want right:=false
      want up:=false
      want down:=false
      want action:=false
      want run:=false
      
      xv := 0

      wait(1)


Next, I got rid of all occurrences of "replace walkabout sprite" and instead
placed "replace walkabout sprite(player, 1)" at the top of "update climb frame"
and "replace walkabout sprite(player, 0)" at the top of "update frame". This is
an important principle in programming: you shouldn't be updating
the player sprite all over the place, instead it's far simpler and less bug
prone to do it in just one place: the part which actually updates the display.

Here's try up/down, now much simpler:
Code:

script, try up, begin
   variable(x tile)
   x tile := (x + 10) / 20

   if(read pass block(x tile, y/20 -- 1), and, vehicle A) then(
      # Move up 20 pixels
      yv := -4
      y move ticks := 5
      # x-align hero with ladder.
      x := x tile * 20
      set slice x(player, x)
   )
end

script, try down, begin
   variable(x tile)
   x tile := (x + 10) / 20

   if(read pass block(x tile, y/20 + 1), and, vehicle A) then(
      # Move down 20 pixels
      yv := 4
      y move ticks := 5
      # x-align hero with ladder
      x := x tile * 20
      set slice x(player, x)
   )
end

The realignment when starting a climb can cause jump of up to 10 pixels to the side; a bit jarring.
You could disallow climbing unless the hero is more closely aligned.

Also, you should get rid of the 'north' walls under the ladder tiles of the
top of the ladders in the caves, so that when you step onto the ladder from
the top you change to the climbing sprite.

I didn't try to fix your elevator code, which I think is now more broken than it was before.
But since it's a self contained loop it's OK for it to do things differently (eg to
use "move slice by").
Display posts from previous:
Page «  1, 2