Jumping (down a ledge)

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

Moderators: marionline, SDHawk

Post Reply
User avatar
guo
Metal Slime
Posts: 749
Joined: Fri Dec 04, 2009 9:12 pm

Jumping (down a ledge)

Post by guo »

Hello,

I have a script for jumping down a ledge, but it's not behaving. The attached image shows the path I want the player to follow during this scripted movement.
Here are my scripts:

Code: Select all

script, jump, direction, distance, begin
	suspend hero walls
	walk hero (me, direction, distance) #move (distance) tile in (direction)
  	set hero Z (me, +2)     #Frame 1
	wait(distance)
	set hero Z (me, +4)     #Frame 2
	wait(distance)
	set hero Z (me, +6)     #Frame 3
	wait(distance)
	set hero Z (me, +4)     #Frame 4
	wait(distance)
	set hero Z (me, +2)     #Frame 5
	wait(distance)
	resume hero walls
end
That is the script that will be called for jumps, here is the actual plotscript:

Code: Select all

plotscript, abseil, begin
	suspend player
	suspend obstruction
	suspend NPCs
	jump (down, 2)
	wait for hero (me)
	walk hero (me, left, 3)
	wait for hero (me)
	walk hero (me, down, 1)
	wait for hero (me)
	jump (down, 2)
	wait for hero (me)
	walk hero (me, left, 2)
	wait for hero (me)
	jump (left, 2)
	wait for hero (me)
	resume player
	resume obstruction
	resume NPCs
end
The problem is the "set hero z" commands don't seem to be functioning correctly. If I have them set to minus (-) the hero's Z position instead of (+), the script works fine but it looks weird as the player seems to "duck" instead of jump, but with (+) Z commands the player's Z position isn't changed, he just walks through the ledges as normal.

Also, assuming I get this working properly, should I be resetting the hero's Z position at the end of the script?

Many regards.
Attachments
the area in question
the area in question
HotOHR20160000.png (27.13 KiB) Viewed 1113 times
vvight.wordpress.com
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

HSpeak does not recognise +2 to mean 2. Instead it interprets "set hero Z (me, +2)" to mean "set hero Z (me+2)" with the unspecified Z argument defaulting to 0. Get rid of the +'s. In future I may make HSpeak stricter about disallowing stray commas in certain contexts. And yes, you need to put a "set hero Z (me, 0)" at the end of the script.

Aside from that, only changing the hero's Z coordinate every 2 ticks instead of every tick is going to make the animation less smooth than it could be. Although I can see you did that to make the script simpler and more flexible. Also, I'm always going to have to complain about non-parabolic (non-physical) jump arcs, it's a pet peeve. You're using a triangular rather than parabolic arc, although over just a few ticks there's not much difference. Worse, the script is written for jumping over a two tile wide gap instead of jumping one tile south and dropping by 20 pixels. Doing a physically correct parabolic arc is tricky, it looks something like this (took me a while to get this right), and think it looks much nicer:

Code: Select all

# Move one tile in any direction, while also falling 1 tile
script, jump down, who, direction, begin
  suspend hero walls
  variable(vz, i, old speed)
  old speed := get hero speed(who)
  if (direction == south) then (
    set hero speed(who, 4)
    walk hero(who, south, 2)
  ) else (
    set hero speed(who, 2)
    walk hero(who, south, 1)
    walk hero(who, direction, 1)
  )
  # This line is optional, comment it out to make the camera move in a straight line
  camera follows slice(lookup slice(sl:walkabout sprite component, get hero slice(who)))
  vz := 3
  for (i, 1, 10) do (
    # The +2 here is to make the total Z movement add to 0
    set hero Z(who, hero Z(who) + vz + 2)
    vz -= 1
    wait
  )
  set hero Z(who, 0)
  camera follows hero(who)
  set hero speed(who, old speed)
  resume hero walls
end 
Comment the line marked optional to change the camera movement; see which way you prefer.
Last edited by TMC on Thu Jul 07, 2016 5:57 am, edited 5 times in total.
User avatar
guo
Metal Slime
Posts: 749
Joined: Fri Dec 04, 2009 9:12 pm

Post by guo »

Thankyou for the detailed response.

With your advice, I got my script working and it looks ... fine. But I then tried the one that you kindly provided and it looks much nicer and "realistic".
If I were to reuse the script in the future, what kind of changes would I have to make for other kinds of jumps? For example, if I wanted the hero to jump 3 spaces across a gap without dropping, or jumping down a ledge more than 2 spaces?

I really must thank you for the exemplary help. '

Regards.
vvight.wordpress.com
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Well, unfortunately generalising it isn't that easy (especially if you commented out that 'camera follows slice' line), but I can try it tomorrow. If you just want to jump across a gap without dropping, there's already a script you can use here. I think it even uses the same strength of gravity, so should look fine together with the script I posted
User avatar
guo
Metal Slime
Posts: 749
Joined: Fri Dec 04, 2009 9:12 pm

Post by guo »

Thanks, with the script you have provided I'll work to figure something out, and post if I have issues.

Regards.
vvight.wordpress.com
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

Well, I really got carried away and rewrote the script to do any jump one could want, up, down, level, diagonal, any distance, and you can adjust the constants like the strength of gravity without completely breaking it. So now I can point people at this in the future. There's also some animation code in there, which might need adjusting for the way you're drawn your walkabouts.

Code: Select all

define constant(1, gravity)

# Make a hero jump a certain number of tiles in the X, Y and Z directions,
# possibly diagonally.
# 'z tiles' is the amount to travel upwards (negative for downwards),
# e.g. -1 to fall to a platform that's one tile lower,
# 0 for a jump between two level platforms, 2 to gain 2 tiles height, etc.
script, jump hero, who, x tiles, y tiles, z tiles = 0, begin

  # How hard do we have to jump upwards? This part might need some adjusting,
  # and if 'initial vz' isn't large enough when jumping upwards, the hero will get
  # jerked to the destination
  variable(initial vz)
  if &#40;z tiles < 0&#41; then &#40;initial vz &#58;= 4&#41;  # Just hop over the edge &#40;assuming we don't jump far&#41;
  else if &#40;z tiles == 0&#41; then &#40;initial vz &#58;= 6&#41;  # Jumping straight
  else &#40;initial vz &#58;= 6 + z tiles * 2&#41;  # Jumping upwards

  # First calculate ahead of time how long it's going to take to jump
  # Keep dropping until we've fallen to the desired z value on the way down &#40;vz is negative&#41;
  variable&#40;ticks, z, vz&#41;
  vz &#58;= initial vz
  while &#40;vz >= 0 || z > z tiles * 20&#41; do &#40;
    z += vz
    vz -= gravity
    ticks += 1
  &#41;

  # Move in an arc using puthero
  camera follows slice &#40;lookup slice&#40;sl&#58;walkabout sprite component, get hero slice&#40;who&#41;&#41;&#41;
  variable&#40;startx, starty, i&#41;
  startx &#58;= hero X &#40;who&#41;
  starty &#58;= hero Y &#40;who&#41;
  vz &#58;= initial vz
  # Skip one tick&#58; the last frame is when we realign, not inside the for loop
  for &#40;i, 1, ticks -- 1&#41; do &#40;
    put hero &#40;who, 20 * start x + 20 * x tiles * i / ticks, 20 * start y + 20 * y tiles * i / ticks&#41;
    set hero Z &#40;who, hero Z &#40;who&#41; + vz&#41;
    vz -= gravity
    # For no walking animation during the jump, comment this line&#58;
    if &#40;i < 5&#41; then &#40;set hero frame &#40;who, &#40;i/2, mod, 2&#41;&#41;&#41;
    wait
  &#41;

  # Realign the hero, converting Z displacement to Y position
  set hero position &#40;who, start x + x tiles, start y + y tiles -- z tiles&#41;
  set hero Z &#40;who, 0&#41;
  set hero frame &#40;who, 1&#41;   # Ideally, change this to the 'standing' instead of 'stepping' walk frame
  camera follows hero &#40;who&#41;
end
Here's a convenient script to test it:

Code: Select all


plotscript, onkeypress test jump, begin
  if &#40;keyval&#40;key&#58;1&#41; > 1&#41; then &#40;
    do a jump&#40;1, 0&#41;
  &#41; else if &#40;keyval&#40;key&#58;2&#41; > 1&#41; then &#40;
    do a jump&#40;2, 0&#41;
  &#41; else if &#40;keyval&#40;key&#58;3&#41; > 1&#41; then &#40;
    do a jump&#40;3, 0&#41;
  &#41; else if &#40;keyval&#40;key&#58;d&#41; > 1&#41; then &#40;
    do a jump&#40;1, -1&#41; # down
  &#41; else if &#40;keyval&#40;key&#58;p&#41; > 1&#41; then &#40;
    do a jump&#40;1, -3&#41; # plummet
  &#41; else if &#40;keyval&#40;key&#58;u&#41; > 1&#41; then &#40;
    do a jump&#40;1, 1&#41; # up
  &#41;
end

script, do a jump, distance, z, begin
  switch &#40;hero direction&#40;me&#41;&#41; do &#40;
    case&#40;south&#41; jump hero&#40;me, 0, distance, z&#41;
    case&#40;north&#41; jump hero&#40;me, 0, -1*distance, z&#41;
    case&#40;east&#41;  jump hero&#40;me, distance, 0, z&#41;
    case&#40;west&#41;  jump hero&#40;me, -1*distance, 0, z&#41;
  &#41;
end
Last edited by TMC on Sun Jul 10, 2016 11:04 am, edited 2 times in total.
User avatar
guo
Metal Slime
Posts: 749
Joined: Fri Dec 04, 2009 9:12 pm

Post by guo »

Oh my, this is fantastic. I'm not much of a coder so I'm going to go through it carefully and figure out what exactly is happening. I can't thank you enough!
vvight.wordpress.com
TMC
Metal King Slime
Posts: 4308
Joined: Sun Apr 10, 2011 9:19 am

Post by TMC »

I probably should comment/clean it up a little more, and give it a proper page on the wiki.

Of course, normally, you should at least suspend/resume player at the beginning/end of the script, but I skipped that because the script you're calling from already has it.

The game I was testing with has the hero drawn with legs apart on the first frame in each direction, and is standing in the second frame, in which case the jump looks quite nice. The
Post Reply