Closed ashes999 closed 9 years ago
You could achieve in different ways, as you probably noticed. Here is a quick jsfiddle - benefits are you work with vertical velocity so it plays somewhat nicely with gravity. By adding vertical velocity each frame (up to a limit) you get a nice sluggishness effect.
.bind("EnterFrame", function(frameData) {
if (this.isDown("W")) {
this.vy = Math.max(-5, this._vy - 2.5);
}
})
I would suggest to use the forum for discussing usages of the library and use the issues to post feature request if it's not something trivially doable with the library.
Noted, thanks. I'll close this issue then.
Hold up, wait a minute :) Does it work as you intended?
No, not really. Thanks though.
What's not working? I just tried, it should also work with normal jump behavior: new jsfiddle
It's not that it doesn't work (although with the new js fiddle, if you hold w
, you just jump normally) -- it's two things:
1) I find the pre-existing Crafty components really dense. I can't understand them (especially how to extend them), especially without looking at the source. 2) The source, and examples from you, are usually the latest (dev) versions. I have to download and rebuild the local sources, instead of using the latest production version (0.6.2 as of writing).
I'm using CraftyJS for prototyping. The perception is (rightly) "well I can wire up gravity, collision, etc. in a matter of minutes" -- but changing those behaviours (eg. can't jetpack, can't figure out how to make this work) is really a hassle.
As much as you are extremely helpful and provide working examples (something very rare in GitHub culture), I can't expect you to write all my code for me. I don't know where that leaves me, because there's no other tool that gives me this much, this fast.
Like in this case; I had to again resort to using nightlies.
(end soapbox)
Crafty has a bit of a slow (but therefor hopefully stable) release cycle. Just recently, the Motion
system was developed, and due to diligent beta testing from @neothemachine we discovered bugs in the nightly builds and (hopefully) fixed them by now (see this forum discussion).
What I want to say is: thank you for your patience and testing with nightly builds, this helps us fix things and provide more stable code for future users of the library.
I didn't understand crafty at all at first, but with time I started to understand the source code gradually. If there are any obscurities, feel free to ask!
Btw, I added this example to craftyjs/demos/devDemos/example_jetpack.html for future reference.
@mucaho Just quick, in your demo code, you use if (this._y + this._h > ground._y + this._dy)
, in my code you used if (this._y + this._h > ground._y + this._vy)
. So what's doing _dy
here?
Using this._dy
appeared to be a miniscule improvement over this._vy
. Reason is that dy
actually contains the difference of y
in the current frame, whereas vy
contains the planned difference of y
for the next frame. According to my testing there was almost no difference, so I didn't feel like it was worth mentioning / potentially confusing you with yet another alternative.
However, now that you mention it, you are better off using dy
in the general case, as vy
can be changed by the user (like it's the case in the jetpack example code) and the if condition probably won't work as expected.
When I was working on a little physics based prototype, I ended up creating a "Newtonian" component that allowed you to apply forces, and then rewriting "Gravity" to use that. I'll submit a PR for this at some point; it ends up being much more flexible, and should be useful for things like jetpacks.
Here is a pastebin of the coffeescript implementation of those components, but it required adding a "CalculateAcceleration" hook into the "Motion" component. (Also, that code almost definitely has some small bugs lurking somewhere, but the basic idea seems pretty sound.)
Is it expected that new and inexperienced users puzzle out all these details themselves?
@mucaho how do you stop on collisions?
I added walls around my screen, and an onHit
function that sets vx
and vy
to zero on collision. But it seems to cause rebound, eg. if you walk left into a wall, and let go, you start automatically going right.
You can see this in my latest code. If you walk into the left/right walls, or fly above the asteroid and then hold the down key, you rebound. This is with the fourway
component.
@ashes999 reported the bug #904 Does it work if you replace Actor.collideWith with?
collideWith: function(tag) {
this.bind("Moved", function(evt) {
if (this.hit(tag)) {
this[evt.axis] = evt.oldValue;
if (evt.axis === "y") this.vy = 0;
}
});
return this;
},
@mucaho yes, that fixes my problem. Thanks.
I have a comment about something. With gravity
, when you're standing on the ground, your velocity is still increasing (even though you are grounded). This results in bugs where, if the ground you're standing on is thin enough, your velocity eventually reaches a high even value that you punch through it.
This is usually cited as being due to the use of euler integration. One way to mitigate it which I've used in the past, although it won't help with high-enough velocities, is to break up and apply time-frame updates at a fixed, small interval (eg. 10ms). I think you're already doing this.
Anyway, without the if (evt.axis === "y") this.vy = 0;
line, your velocity continues to increase. In my sample, this means that you eventually fall through the asteroid.
Thanks for your help. Let me know if you have any questions about my comments.
With
gravity
, when you're standing on the ground, your velocity is still increasing (even though you are grounded)
Gravity
should correctly reset vertical velocity upon landing (you can log the vertical velocity when player lands on the platform above and it should show 0
).
However, the player never lands on your bottom floor. I thought you were aiming for an endless vertical jumper, so that's why I tried to preserve your code logic with if (evt.axis === "y") this.vy = 0;
.
EDIT: aha got it, you do .gravity("Asteroid")
but your walls don't contain "Asteroid" component, so they are ignored by Gravity
Gravity should correctly reset vertical velocity upon landing (you can log the vertical velocity when player lands on the platform above and it should show 0).
The way Gravity
appears to work is that it displaces you upward to the top of the object, but does not stop your velocity from increasing. I've seen two behaviours, depending on how I try to resolve the collisions:
0.0
to ~0.8
.You're right that I'm prototyping an endless vertical jumper. But, that if-statement you added doesn't affect that (actually, I can walk on the floor fine with it.) It actually prevents a bug where your y velocity eventually becomes ~150 and you blink through the floor.
You can clone my repo and verify this yourself (use the HEAD~1
version). If you want specific details (eg. when does it jitter? when does it phase through the floor? when does it hold stable but keep increasing?) I can try to reproduce those cases.
Unfortunately I can't reproduce the jittering issue. Could you make a small example where it's occurring? Regarding stability, it's on the TODO list (see last paragraph of #884).
aha @ashes999 , I think communicated a very important point poorly, I think that should solve your jittering problem
you do .gravity("Asteroid") but your walls don't contain "Asteroid" component, so they are ignored by Gravity
@mucaho I didn't get a chance to try and repro the jittering yet. Hopefully, tomorrow.
I don't use gravity
any more. It turns out that gravity is well-suited to ground only, because when you specify .gravity('tag')
, hitting that object propels you upward to the top of it. For asteroids, if you bump them from the bottom, you teleport to the top. Similarly, if you bump into a wall, you teleport to the top.
Now, I'm trying to use a simple collision instead of gravity. My latest code is here. I don't know if I can reproduce the jittering with this code, but I'll try.
I'm trying to add "jetpack"-like functionality to my player. When I add the
Gravity
component, I get the following (desirable) behaviours:What I would like to figure out, is how I can press/hold the up button and fly upward. Is it enough to bind the
EnterFrame
event and add to the player'sy
position? Is there a better way to do this?NB: if jumping gets disabled in the process, that's cool too.