Big rolling boulder -- what type of sprite to use?
Moderators: marionline, SDHawk
Big rolling boulder -- what type of sprite to use?
I'm gonna have a corridor in one of the first dungeons in my game with a big boulder, 2 tile widths and 2 tile heights big, that moves down it. I'm already using Walktall. I'm wondering if I should replace a standard NPC with a medium monster sprite, or make two regular NPCs move in synchronization. There will also be a script that will need to activate if the boulder touches the player.
Any ideas what would be easier?
Any ideas what would be easier?
Regardless of what you use, you shouldn't use 'touch' npcs to detect whether the player is crushed, because that'll activate if you stand next to it.
You could use two npcs, but I wouldn't, I prefer to use slices. Collision detection is easy with a single slice.
If you don't use a pair of npcs, then you'll have to animate the slice yourself. However you'll need to do this anyway if you want more than 2 frames of animation.
The following untested script shows how to create and move the boulder slice, how to animate it with 3 frames of animation, and how to do collision detection. There's lots of numbers in this that need changing.
You could use two npcs, but I wouldn't, I prefer to use slices. Collision detection is easy with a single slice.
If you don't use a pair of npcs, then you'll have to animate the slice yourself. However you'll need to do this anyway if you want more than 2 frames of animation.
The following untested script shows how to create and move the boulder slice, how to animate it with 3 frames of animation, and how to do collision detection. There's lots of numbers in this that need changing.
Code: Select all
plotscript, boulder roll, begin
variable(boulder, container, sprite)
container := create container(40, 40) # create a 40x40 hitbox
set parent(container, lookup slice(sl:map layer 2))
sprite := 3
boulder := load large enemy sprite(sprite)
set parent(boulder, container)
put slice(container, 13 * 20, 21 * 20) # initial position
move slice to(container, 13 * 20, 29 * 20, 24) # move down 8 tiles in 24 ticks: 4 ticks/tile is 5 pixels/tick
while (slice is moving (container)) do (
# Every two frames (same as normal walk animation), change the boulder image
# (Loop 3, 4, 5, 3, 4, ...)
sprite += 1
if (sprite > 5) then (sprite := 3)
replace large enemy sprite(boulder, sprite)
# Check whether intersecting the 20x20 walkabout slice of the
# first hero (this ISN'T the 32x40 hero sprite slice)
if (slice collide(get hero slice(0), container)) then (
# splat! (whatever should happen here)
exit script
)
wait(2)
)
free slice(container)
end
Last edited by TMC on Sun Mar 01, 2015 12:28 am, edited 2 times in total.
I gave it a try on a test map with some edits:
* Changed script to plotscript, changed script name 'boulder' to 'boulderroll'
* Map coordinates changes, I'm guessing that slice container positioning is tile position * 20? Can't seem to view plotdict.xml right now or I'd refer to that to make sure.
* Just made a show text box line for the "splat" collision scenario
* I changed instances of 'large enemy sprite' to 'medium enemy sprite' in the script and I have 3 animation frames in medium enemy slots 3, 4 and 5.
First I got a script error from the line
but that went away when I added a couple of extra map layers (I'm just doing this on a mostly empty test map for the time being)
Now I don't get a script error anymore, but nothing seems to happen when I talk to a test NPC that runs the script when activated. No error message, but I also don't see any sprite appearing or being loaded.
* Changed script to plotscript, changed script name 'boulder' to 'boulderroll'
* Map coordinates changes, I'm guessing that slice container positioning is tile position * 20? Can't seem to view plotdict.xml right now or I'd refer to that to make sure.
* Just made a show text box line for the "splat" collision scenario
* I changed instances of 'large enemy sprite' to 'medium enemy sprite' in the script and I have 3 animation frames in medium enemy slots 3, 4 and 5.
First I got a script error from the line
Code: Select all
set parent(container, lookup slice(sl:map layer 2))]Now I don't get a script error anymore, but nothing seems to happen when I talk to a test NPC that runs the script when activated. No error message, but I also don't see any sprite appearing or being loaded.
Well if you don't need collision checking, then the script can become much simpler (you don't need the container slice).
Yes, slice positions are always in pixels, not tiles.
I'd forgotten that map layer slices are missing if the map layers don't exist.
I tested the script and found my error. This:
should have been:
Yes, slice positions are always in pixels, not tiles.
I'd forgotten that map layer slices are missing if the map layers don't exist.
I tested the script and found my error. This:
Code: Select all
while (slice is moving (boulder)) do ( Code: Select all
while (slice is moving (container)) do ( This is working so far so good, here are some edits I've made.
I tried to set a variable 'boulderroll' to the 'move slice to' ticks and have it gradually decrement; that way the boulder can start off slow and gain momentum. But I think that 'move slice to' is taking the starting 200 ticks value and not updating since the decrement loop occurs after that line. I can see why that's happening, but I'm also a bit stumped as to how I can achieve the building momentum effect. My knowledge of slice related scripting stuff is pretty bad/nonexistent...
I tried to set a variable 'boulderroll' to the 'move slice to' ticks and have it gradually decrement; that way the boulder can start off slow and gain momentum. But I think that 'move slice to' is taking the starting 200 ticks value and not updating since the decrement loop occurs after that line. I can see why that's happening, but I'm also a bit stumped as to how I can achieve the building momentum effect. My knowledge of slice related scripting stuff is pretty bad/nonexistent...
Code: Select all
plotscript, boulderroll, begin
variable(boulder, container, sprite, rollspeed)
container := create container(60, 60) # create a 60x60 hitbox
set parent(container, lookup slice(sl:map layer 2))
sprite := 6
rollspeed :=200
boulder := load medium enemy sprite(sprite)
set parent(boulder, container)
put slice(container, 29 * 20, 18 * 20) # initial position
move slice to(container, 29 * 20, 42 * 20, rollspeed) # move down 24 tiles in 200 ticks: 4 ticks/tile is 5 pixels/tick
while (slice is moving (container)) do (
# Every two frames (same as normal walk animation), change the boulder image
# (Loop 6, 7, 8, 6, 7, ...)
sprite += 1
if (sprite > 8) then (sprite := 6)
replace medium enemy sprite(boulder, sprite)
# Check whether intersecting the 20x20 walkabout slice of the
# first hero (this ISN'T the 32x40 hero sprite slice)
if (slice collide(get hero slice(0), container)) then (
# splat! (whatever should happen here)
show text box (1)
)
decrement (rollspeed,2)
wait(2)
)
free slice(container)
endAfter you pass a value in a variable to a command, changing the variable never has an effect, because you're passing the value stored in the variable (e.g 6) rather than the variable itself.
But the solution is simple: just call "move slice to" inside the loop.
Rollspeed is the number of ticks that the movement takes to happen, but since every time you call movesliceto more 2 ticks will have passed, decrementing rollspeed by 2 will result in constant speed. So makes sure to decrement it by 3 or more. Also, you should add a line "if (rollspeed < 1) then (rollspeed := 1)", otherwise you'll get an error.
However... I believe that decrementing the move ticks like that will give a rather bad speedup effect, where the acceleration will be very slow at first, and gets faster and faster until the boulder LEAPS across the last 50% of the distance. Instead, I would use the "set slice velocity y" command, which you can use to set the speed. In this case, change the while loop condition to something like "while (slice y(container) < 42 * 20)"
But the solution is simple: just call "move slice to" inside the loop.
Rollspeed is the number of ticks that the movement takes to happen, but since every time you call movesliceto more 2 ticks will have passed, decrementing rollspeed by 2 will result in constant speed. So makes sure to decrement it by 3 or more. Also, you should add a line "if (rollspeed < 1) then (rollspeed := 1)", otherwise you'll get an error.
However... I believe that decrementing the move ticks like that will give a rather bad speedup effect, where the acceleration will be very slow at first, and gets faster and faster until the boulder LEAPS across the last 50% of the distance. Instead, I would use the "set slice velocity y" command, which you can use to set the speed. In this case, change the while loop condition to something like "while (slice y(container) < 42 * 20)"
Last edited by TMC on Mon Mar 02, 2015 4:03 pm, edited 1 time in total.