MetalES / Project-Zelda

Project Zelda, made using Solarus
12 stars 1 forks source link

Stream Fan / Roc's Cape: Add inertia #51

Open MetalES opened 7 years ago

MetalES commented 7 years ago

This is an accurate description (c/p from bellow)

I am now convinced that it is possible only with 2 variables (not counting link's X and Y).

This is what I am trying to be close of, example using images This is how a jump looks like using the Roc's Cape currently.

We are pressing right then down, as shown bellow. sans titre 10

The problem is, modifying the hero's walking speed is problematic, if he is stopped then the jump movement is as well, an inertia using a straight movement only imply the direction the script memorized when using the item.

This is how I see the Roc's cape with inertia (default idea)

The solution is, like Minish Cap, to improve maniability, this. sans titre 11

This is the same movement, but this time, using 2 values, let's call them InertiaX and InertiaY, constantly updated depending on the input pressed and Link's direction This looks better on the paper doesn't it, it would make the jump more realistic and it would be a different way of controlling an event, we are not only dependant on on_command_pressed/released, there are functions that are updated constantly. Why not using them ?

A small example, is this https://www.youtube.com/watch?v=EA4BHiYHQzY

It is more difficult to control due to the lack of inertia, so it limit the level design potential

Plus, there are problems sometimes, for example, pressing up-left or some diagonal direction doesn't work, which will be not the case here, this also happend when I was reworking the map subscreen, no more issue when values was managed in real time instead of being a movement

Looks like I am close to what I'm looking for

My guess: Let's assume that, like the picture, we're going right

MetalES commented 7 years ago

Momentum is never kept, even if I tell the variable to memorize this value + decrease over time, as soon as the input is released, the momentum is canceled

Diarandor commented 7 years ago

I haven't tested this but, try to use a stream that follows the hero. It may work to simulate the inertia.

Edit: if you do this, maybe you will need to reduce the walking speed during the jump, to compensate the extra speed in the direction of the inertia, so that this works correctly.

MetalES commented 7 years ago

This would be difficult, the hero can go backward and speed isn't constant, but I take this idea in note, this is clever indeed.

Yet, I don't know if a stream can go over holes

Diarandor commented 7 years ago

I don't know that either. But still, if you are using a custom entity with traversable ground under the hero during the jump, and the stream is created later, it should be above the traversable ground instead of over the hole. (Note that you can also jump over lava and deep water. I guess the streams should work over lava, but who knows... XD)

Diarandor commented 7 years ago

Another idea (and quite easy) for the speed. Just use a timer to check the direction of the hero, or the direction of the movement, each few milliseconds, and set a slow speed when the direction is not the initial one. That may work too. But if you want to add diagonal jumps, which is convenient, then you should check the direction of the initial movement instead of the direction of the hero. I hope this helps.

MetalES commented 7 years ago

I already use the second idea (direction is fixed so it is easier), but the stream idea is clever and it actually works, now I should try to disable Link's movement in order to make the jump completly handled by the stream. Good thig is streams allow diagonals and there is a game event that catch if we are moving diagonal (game:get_commands_direction())

As you know, my items scripts are managed through menu, so it give me access to all things, menu related, do everything are easier to do

if command == "left" or command == "right" or command == "up" or command == "down" then sol.timer.start(50, function() local speed = stream:get_speed() stream:set_speed(speed - 1) return not game:is_command_pressed(command) or speed > 0 end) end

Diarandor commented 7 years ago

I was wondering if having several streams under the hero may be a problem if only one of them is applied, because that would interfere with the behavior of the fan stream. The second idea (changing the speed) is probably the best idea, and should work perfectly; in this case I would set a speed that depends (in a smoothly way) on the angle of the initial direction of the movement of the hero and the current direction of the movement of the hero, i.e., the bigger angle difference, the less speed (and maybe with a minimum speed).

MetalES commented 7 years ago

Yeah overlapping another stream has a weird issue, I should try a movement with a speed that is constantly repeted until the item is finished

Too bad, it was very easy to do ...

Diarandor commented 7 years ago

Are you freezing and disabling the hero's movement? That sounds bad. Didn't you try to modify the speed of the movement (depending on the angle) as I suggested?

MetalES commented 7 years ago

Using a straight movement there are weird stuffs happening, sometimes it works, sometimes not, I am not freezing the hero for this method (i was freezing him with the stream method)

The problem is, the movement is halted as soon as the hero's state is unfreeze, which can't be avoided because to set a fixed animation, you have to unfreeze the hero

The method I used earlier (set_position()) with variables might be the only way to be as close as I want

Diarandor commented 7 years ago

Ok, so if I understand correctly, you were forcing a movement during the jump. The problem of that is that you cannot control the movement in the air since the hero would be frozen, unless you use "set_position" instead of a built-in movement (as you say above), which should be a nice solution.

I don't understand what you mean by "to set a fixed animation you have to unfreeze the hero".

Edit: what about changing the speed of the movement depending on the direction? (Assuming that you allow control of the hero and want slow speeds if the hero changes direction during the jump.) Does not that work for some reason?

MetalES commented 7 years ago

Yet I don't understand why a stream overlapping another causes malfunction, it was the best solution out there and it worked quite great, I' gonna stuck with the stream solution, the simplest, because fan streams aren't disabled when their speed = 0. Or else, replace streams by a custom entity where, when overlapping it, set the hero's position to the right coordinate, a little bit like your Platform script, diarandor.

Reminder: Epona need inertia as well, why not using the same method as the Roc's Cape ?

Plus, a custom entity for stream is more convenient because other objects like enemies can be moved along the custom stream

I mean this sans titre 12

Is more convenient than this sans titre 14

The map load less objects so that's a good thing

Plus, let's analyse this situation, old VS new, using the Roc's Cape

Link wanna go to the red cross. The streams are active, full speed (120) sans titre 14

He can't in this situation, because the stream is so fast, Link can't even move, because he is constantly centered in the stream.

But, it is possible using the method I use (custom)

sans titre 12

The only thing we need a function to modulate the speed, so when activting, the speed goes smoothly faster, maybe a variable incrementing / decrementing when activating or desactivating will solve the thing.

Edit:

Ehm, it works nicely, enemies andd Link follow the movement ... Plus Link isn't stuck in the center of a 16x16 stream, he can move freely, the fact I can't go to the right is because each frame link's X is X + 1, there is no modulation of the speed yet https://www.youtube.com/watch?v=1eaAz7A4ipw

Plus, this is nice to simulate a windy effect with a very low speed, example: this https://www.youtube.com/watch?v=EA4BHiYHQzY

The scene will be more cool and a bit more challenging with a little wind effect, coming from the same entity used for the stream.

Oh god, this is amazing ...

Diarandor commented 7 years ago

Awesome work!!! Another idea: Appart from modulating the stream speed of the fan (to make a smoother transition) and adding a semitranspartent wind effect, it would be nice also to make the sound transition smooth (when the wind is starting or finishing, the volume of the wind sound could be lower); that would be even more realistic.

MetalES commented 7 years ago

The sound and sprite are planned, the sound is already implemented (See Roc Cape Test video), for the sprite I could use a code like the Hookshot's chain in order to make the wind animation progressive and reverse the creation point before it end so the animation will looks right (https://github.com/MetalES/Project-Zelda/blob/master/data/scripts/gameplay/hero/hookshot_controller.lua#L340)

For the speed modulation do you have any idea ? The movement is managed in add_collision_test and the speed is managed through entity.speed = speed

Diarandor commented 7 years ago

Ok, I didn't notice, nice to know that. I can't help more for now, sorry; I must focus in the creation of new free graphics, it's my main priority (maybe one day in a few years you can release your game with free graphics, and new story/enemies, that would be great).

MetalES commented 7 years ago

The last thing I need is speed modulator, I don't know how to do it, everything is handled in add_collision_test, do you have any idea ?

MetalES commented 7 years ago

Oh wait wait wait, a fan in the project is composed of 6 states (disabled, start_enable, enabled, start_disable, cutscene_start_enable, cutscene_start_disable), perhaps I could play with a timer in start_enable/disable and disable / enable collision ... in each recheck.

This is the current result, I'm gonna play around with the speed variable, I'm quite satified, I know that it is not the expected result but if there are limitations, I can't break them. https://www.youtube.com/watch?v=KhpAznuIOBA