Post new topic    
Red Slime
Send private message
Hero Walkabout Sprite Layering 
 PostThu Jan 24, 2019 6:56 pm
Send private message Reply with quote
Good evening!
I'm hoping to make a short game over the course of a week, and I'd like to implement a system that'll allow the players appearance to be customized. I'd be using the Walktall script as well.
I'd like to make it so that the hero's overworld sprite is composed of 3 sprites: a body, head, and face, and allow for them and their palettes to be changed by other scripts.
If anyone would know how to create such a system it would be much appreciated!
Thank you in advance!
Liquid Metal Slime
Send private message
 
 PostThu Jan 24, 2019 8:20 pm
Send private message Reply with quote
Hi!! <3<3<3

First of all, using the walktall script is all but deprecated at this point, since in the recent nightly builds, you can create walkabouts (and other sprite types) of any size.

It sounds like you'll need to use load walkabout sprite() two separate times and call set parent() on each one with the hero slice to lock them into the right place. (be sure to use put slice(handle, x, y) to make sure the loaded sprites are in the right place relative to the hero slice)

Next you'll have to animate them correctly, which is a little more complicated. I know there's a way to do it, but I'll have to do a little research to find out how. There are some quirks that get in the way.

EDIT: I'm looking at these scripts for guidance. The eachtick script is set up in a similar way to what you'll need. The specifics aren't quite the same, but accessing slice handles and stuff can be tricky, and this does it the right way.
I can't write in cursive.
Metal King Slime
Send private message
 
 PostFri Jan 25, 2019 1:29 am
Send private message Reply with quote
Here are some scripts to do this.
If you try to set the direction of the head and face sprites to be the same as the walkabout (body) sprite, then the direction will lag behind for one tick, because scripts run before the engine processes user input and updates the hero sprites. There are some scripts on the wiki here which can be used to work around that (but they will still lag when you use the mouse to move the hero, or use the "walk hero" command, and some other corner cases). (This is something I really need to fix in the engine).
I tried out these scripts with and without making use of "hero will move", and actually that one-tick lag isn't noticeable, at least for the hero sprites I was using.

If you want to use the "hero will move" scripts, copy in the scripts from the top section of that wiki article.
If you don't want to use them, delete the "next leader direction" script and replace "next leader direction" with "hero direction(me)".

Also, even when making use of "hero will move", the A/B frame of the head and face will be one tick out of sync with the body sprite. It probably doesn't matter, but if it's really a problem it is possible to prevent that with more work.

Code:

define constant(0, timer:hero sprites)

# This is just the leader's walkabout sprite
script, body sprite, begin
  return (lookup slice(sl:walkabout sprite component, get hero slice(0)))
end

script, head sprite, begin
  return (slice child(body sprite, 0))
end

script, face sprite, begin
  return (slice child(body sprite, 1))
end

plotscript, setup hero sprites, begin
  # Create the head sprite
  set parent(load walkabout sprite(1), body sprite)
  # Create the face sprite
  set parent(load walkabout sprite(2), body sprite)

  update hero sprites eachtick
end

script, update hero sprites eachtick, begin
  # Set direction based on what the body sprite *will be* and A/B frame
  # from what the body sprite *is* (so will lag the body by one tick)
  variable(frame)
  frame := (get sprite frame(body sprite), and, 1) + 2 * next leader direction  #hero direction(0)

  set sprite frame(head sprite, frame)
  set sprite frame(face sprite, frame)

  # This schedules the script to run again next tick, continuing forever
  set timer (timer:hero sprites, 0, 1, @update hero sprites eachtick)
end


# Determine the direction that the leader will be facing this tick, after
# user input is accounted for
script, next leader direction, begin
  if (hero is walking(0)) then (
    return (hero direction(0))
  ) else if (hero will move) then (
    return (trying to move direction)
  ) else (
    return (hero direction(0))
  )
end
Red Slime
Send private message
 
 PostMon Jan 28, 2019 5:28 pm
Send private message Reply with quote
ah, it all works perfectly! the slight lag makes the head of the character wiggle slightly when they walk which is cute.
I am wondering is there a way to refresh the script? so that parts can be changed without having to leave the map
Liquid Metal Slime
Send private message
 
 PostMon Jan 28, 2019 9:04 pm
Send private message Reply with quote
If you set "setup hero sprites" to be activated by an NPC or menu item or something, you should be able to do that. Although to change which sprites are loaded, you'd probably have to give "setup hero sprites" two arguments that are then passed into "load walkabout sprite(argument)". If I'm reading this correctly, that should work. You might also have to stop the timer in "setup hero sprites" just to make sure it doesn't get called on the same tick twice.
I can't write in cursive.
Metal King Slime
Send private message
 
 PostTue Jan 29, 2019 4:22 am
Send private message Reply with quote
Actually the head & face slices should remain when you change map. You would need to recreate them only if you change the party or save and reload the game.

You will want to delete the old slices before you create new ones! Like so
Code:

plotscript, setup hero sprites, begin
  if (face sprite) then (free slice (face sprite))
  if (head sprite) then (free slice (head sprite))

  # Create the head sprite
  set parent(load walkabout sprite(1), body sprite)
  # Create the face sprite
  set parent(load walkabout sprite(2), body sprite)

  update hero sprites eachtick
end


There's no need to worry about the timer, as it doesn't matter if "update hero sprites eachtick" gets called twice.
Red Slime
Send private message
 
 PostWed Feb 13, 2019 4:42 pm
Send private message Reply with quote
It mostly works perfectly, though I've run into an error!
https://i.imgur.com/HNS494d.png
https://i.imgur.com/0rV5s7B.png
It works very well for walking around, but upon talking to an NPC, the head and face look upwards for some reason, which will obviously look strange a lot of the time! This also sometimes happens for a single frame after walking off diagonal stairs.
Thank you very much for the help by the way!!
Metal King Slime
Send private message
 
 PostThu Feb 14, 2019 3:06 am
Send private message Reply with quote
Wow, that doesn't look like TCoD ... a new game?

I see that this is because you are using the "next leader direction" script, and it turns out there is a bug in that. I had thought you weren't going to use that script.

The fix is to change the line in "trying to move direction"
Code:
  if (current textbox > -1 || player is suspended) then (exit returning(false))

to
Code:
  if (current textbox > -1 || player is suspended) then (exit script)


Also, to not use "next leader direction" (at the cost of common one-tick delays), you can simply change the line
Code:
frame := (get sprite frame(body sprite), and, 1) + 2 * next leader direction

to
Code:
frame := get sprite frame(body sprite)


I'm not sure about the diagonal stairs problem since I don't know which script you're using, but if the stairs script contains "suspend player" this probably fixes it too.
Red Slime
Send private message
 
 PostThu Feb 14, 2019 8:56 am
Send private message Reply with quote
Ah that seems to have fixed everything, thank you so much for your help!!

And yes, it's a new game called Amazing Treasure Valley! TCoD is something i care about a lot but it's also quite ambitious, and working on something like that for so long without being able to let people play it is hard, so I'm making a smaller exploration game that I can finish in about a month! Look forward to playing it soon!
Display posts from previous: