Since the slice returned by "get hero slice()" cannot be manually repositioned, is there another slice, such as the "sl:walkabout slice component" child of the hero slice that can be moved? I'd like to see if I can get some movement done easily with the set slice velocity commands, but would like to hold onto some nifty info, like hero direction.
I didn't know if setting velocity counted as repositioning a slice, so I tried it anyway, on both the hero slice and its walkabout sprite component, and got an invalid slice id error. It was unsurprising, but I'm still unsure where to go from here.
Alternatively, I could just create an entirely new slice and make the camera follow it, but I don't have a full plan on how to execute that.
Moving the Hero with "set slice velocity x()"
Moderators: marionline, SDHawk
Moving the Hero with "set slice velocity x()"
My pronouns are they/them
Ps. I love my wife
Ps. I love my wife
If you got an invalid slice handle error then you must have called something with the wrong arguments.
I checked and found that the Y position of the walkabout sprite component can't be overridden, as it is set every frame to the foot offset. And the camera isn't centered on it anyway (again, there's special behaviour for the foot offset).
I think you're going to need to move around a separate slice.
I checked and found that the Y position of the walkabout sprite component can't be overridden, as it is set every frame to the foot offset. And the camera isn't centered on it anyway (again, there's special behaviour for the foot offset).
I think you're going to need to move around a separate slice.
Sounds good. I started on that anyway because I still wanted to be working on it instead of just giving up.
I have run into a few problems with manipulating a loaded hero sprite (I will be using hero sprites instead of walkabouts in a sidescroller manner). I think I misunderstand what setting the velocity of a slice actually does. Basically, moving left and right works fine, no problems. I have a script setup similar to Baby Bob, wherein a keypress handler sets variables "want left" and "want right" and the main game loop responds accordingly. This works fine at the *edges* of the screen (x pixel values 0-320, where the game window ends), but once the sprite moves beyond that, the velocity accelerates indefinitely, until it reaches the other side of the map, at which point it slows back to normal speed.
The whole movement script is posted below. It's not fully polished, I still need to fix wall conditions. Those don't work at all yet, but I'm pretty sure they won't with the approach I'm using. What's happening in a nutshell is 'xv' is a global variable that represents the player's x velocity. The script "walk override(dir)" sets 'xv' based on direction and wall conditions (in theory), and then sets the slice's x velocity to 'xv'.
Of course, if I'm doing something entirely wrong, that would be good to know. Otherwise, I'd like to use the slice velocity scripts, because I have never used them for anything successfully before and they seem so useful. I just don't understand the weird acceleration bug.
I have run into a few problems with manipulating a loaded hero sprite (I will be using hero sprites instead of walkabouts in a sidescroller manner). I think I misunderstand what setting the velocity of a slice actually does. Basically, moving left and right works fine, no problems. I have a script setup similar to Baby Bob, wherein a keypress handler sets variables "want left" and "want right" and the main game loop responds accordingly. This works fine at the *edges* of the screen (x pixel values 0-320, where the game window ends), but once the sprite moves beyond that, the velocity accelerates indefinitely, until it reaches the other side of the map, at which point it slows back to normal speed.
The whole movement script is posted below. It's not fully polished, I still need to fix wall conditions. Those don't work at all yet, but I'm pretty sure they won't with the approach I'm using. What's happening in a nutshell is 'xv' is a global variable that represents the player's x velocity. The script "walk override(dir)" sets 'xv' based on direction and wall conditions (in theory), and then sets the slice's x velocity to 'xv'.
Of course, if I'm doing something entirely wrong, that would be good to know. Otherwise, I'd like to use the slice velocity scripts, because I have never used them for anything successfully before and they seem so useful. I just don't understand the weird acceleration bug.
Code: Select all
global variable, begin
0,game is running
1,paused
2,want left
3,want right
4,xv
5,player
end
define constant(5,walkv)
define constant(10,runv)
plotscript, new game, begin
suspend player
create hero sprite
main game loop
end
script, create hero sprite, begin
player := load hero sprite(1)
camera follows slice(player)
put sprite(player,hero x(0) * 20,(hero y(0) -- 1) * 20)
end
script, main game loop, begin
game is running := true
while(game is running) do, begin
# Movement
if(want left) then(walk override(left))
else if(want right) then(walk override(right))
else(set slice velocity x(player,0))
# Check Walls
if(check wall(left) || check wall(right)) then(
xv := 0)
# Pause Game Conditions
if(current textbox >= 0
|| top menu == true
)
then(paused := true)
else(wait, paused := false)
if(get slice velocity x(player) == 0) then(
xv := 0)
want left := false
want right := false
# Wait
wait
end
end
plotscript, keypress handler, begin
if(paused == false) then(
if(key is pressed(key:left)) then(
want left := true)
if(key is pressed(key:right)) then(
want right := true)
if(key is pressed(key:z)) then(
activate center item)
if(key is pressed(key:esc) || key is pressed(key:filtered alt)) then(
open menu(0))
)
end
script, walk override, dir, begin
variable(sl)
sl := get moving slice
if(dir == left) then(
if(check wall) then(
xv := 0)
else(
xv := walkv -- (walkv * 2))
)
else(
if(check wall) then(
xv := 0)
else(
xv := walkv)
)
set slice velocity x(player,xv)
end
script, check wall, dir, begin
variable(x,y)
x := slice x(player)
y := slice y(player)
if(dir == left) then(
if(read pass block((x/20) -- 1, y)) then(
return(true)
)
)
else(
if(read pass block((x/20) + 1, y)) then(
return(true)
)
)
end
My pronouns are they/them
Ps. I love my wife
Ps. I love my wife
- Bob the Hamster
- Lord of the Slimes
- Posts: 7660
- Joined: Tue Oct 16, 2007 2:34 pm
- Location: Hamster Republic (Ontario Enclave)
- Contact:
If you are making a sidescroller, you probably should not be using the built-in slice velocity at all.
Your are probably better off tracking your velocity in your xv variable, and then adding it to the slice x once per tick
set slice x(player, slice x(player) + xv)
The built-in velocity feature was intended for animations, and I don't know if anybody has ever successfully used it for a sidescroller or not.
Your are probably better off tracking your velocity in your xv variable, and then adding it to the slice x once per tick
set slice x(player, slice x(player) + xv)
The built-in velocity feature was intended for animations, and I don't know if anybody has ever successfully used it for a sidescroller or not.
The reason why using slice velocity commands doesn't save you any work is that for wall checking you need to calculate where the hero sprite is going to be (trying to move to) anyway. You probably haven't realised that yet because your current wall checking code is tile based rather than pixel based. Basically, you only need to check for a wall when you actually cross the edge of a tile. Baby Bob should be a good reference.
I also notice you have "if(check wall(left) || check wall(right)) then(xv := 0)" in the main loop and the same logic in "walk override". There shouldn't be a need to duplicate it.
Also, writing "top menu == true" is incorrect. topmenu returns a menu handle, or 0 (false) if none is open. "not(top menu == false)" is not the same thing as "top menu == true"! I believe you can implement pausing as a while loop if you want ("while (menu or text open) do (want left := false , want right := false, wait)"), but do you need to be careful: I think this should be put at the top of the main loop. Or just use a "paused" global like you're using, that's fine too. But you need to suspend all the game logic, not just player input, unless the player is the only thing that moves and there's no gravity.
I also notice you have "if(check wall(left) || check wall(right)) then(xv := 0)" in the main loop and the same logic in "walk override". There shouldn't be a need to duplicate it.
Also, writing "top menu == true" is incorrect. topmenu returns a menu handle, or 0 (false) if none is open. "not(top menu == false)" is not the same thing as "top menu == true"! I believe you can implement pausing as a while loop if you want ("while (menu or text open) do (want left := false , want right := false, wait)"), but do you need to be careful: I think this should be put at the top of the main loop. Or just use a "paused" global like you're using, that's fine too. But you need to suspend all the game logic, not just player input, unless the player is the only thing that moves and there's no gravity.
I started working on a pixel based wall check that I am now realizing is whack. Fixing the movement first should fix that along. The wall check in the main loop was actually a debugging attempt to see if wall checks would work in any condition (it wasn't). I shouldn't have left it there.
Thank you for the pointers. I will fix the pausing functions, including the menu check. Also, I notice you say top menu returns 0 if no menu is open. Shouldn't it return -1 for no menu open, considering menu 0 is the main menu? In this case, should "if(top menu >= 0)" work, or would it have to simply be greater than 0?
Thank you for the pointers. I will fix the pausing functions, including the menu check. Also, I notice you say top menu returns 0 if no menu is open. Shouldn't it return -1 for no menu open, considering menu 0 is the main menu? In this case, should "if(top menu >= 0)" work, or would it have to simply be greater than 0?
My pronouns are they/them
Ps. I love my wife
Ps. I love my wife