Hello group members,
has anybody of you successfully extended ViewPlatformAWTBehavior
to handle KeyEvents and is willing to share hints or code?
I'm trying to implement a simple Quake style behavior, where the
mouse controls the view direction and some keys (say CURSOR UP/DOWN
and LEFT/RIGHT) move the ViewPlatform forward/reverse and left/right
(called 'strafing' in Quake) with respect to the current view
direction. Needless to say, that the horizon shall remain
horizontally, ever :-).
This works, in principal.
The problem is: since I started to respect deltaTime (via
System.currentTimeMillis() as in KeyNavigatorBehavior) my
Behavior became really worse:
most notably, instead of accelerating smoothly to the desired
maximum speed ever, it shows 3 different real behaviors randomly:
- sometimes it only moves the VP in much too small steps, not
accelerating at all, while the accelerating key is held down.
When it is released, the VP suddenly has the maximum speed
(decelerating then, as wanted, immediately).
- most times it almost accelerates just fine to the desired
speed, but in all the motion, when the framerate drops (i.e.
due to new objects coming into view) the motion TOO is affected.
Which should not be the case at all, as I'm respecting
deltaTime from the last frame and that should compensate by
moving the VP farther, when deltaTime is high. Besides, my
deltaTimes are almost ever 10, 20, 30 ... milli seconds, due
to the bad PC time resolution, possibly I should integrate
that, but then, how does the KeyNavigatorBehavior class
deal with that, I couldn't find any special code?
- sometimes the final speed seems to be about double of the
desired speed, then the movement seems to be smooth.
My Pseudo-Code is as follows:
protected synchronized void
processAWTEvents(final AWTEvent[] events)
{
motion = false;
// set motion = true, if some acc/decelerating
// or movement is in progress
if ... motion = true;
// handle all AWT events
...
processKeyEvent(event)
...
}
protected void processKeyEvent(final KeyEvent evt) {
// record key states into instance variable(s)
// and set motion = true on any recognized key event
...
}
protected synchronized void integrateTransforms() {
// Check if the transform has been changed by another behavior
targetTG.getTransform(currentTransform) ;
if (! targetTransform.equals(currentTransform)) {
resetView();
}
calcSpeed();
// modify the target transform, this simply works
...
}
private void calcSpeed() {
long now = System.currentTimeMillis();
long deltaTime = now - lastTime;
lastTime = now;
// check for too old time sample
if (deltaTime > 2000) deltaTime = 1;
// protect against 0 deltaTime, this happens sometimes
if (deltaTime < 1) deltaTime = 1;
float dt = (float)deltaTime / 1000f;
// exploit key states and then
// integrate acceleration/drag over dt
...
// integrate velocity over dt
...
// set instance members for integrateTransforms()
...
}
Any hints are VERY welcome
thanks
Georg
___ ___
| + | |__ Georg Rehfeld Woltmanstr. 12 20097 Hamburg
|_|_\ |___ [EMAIL PROTECTED] +49 (40) 23 53 27 10
===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA3D-INTEREST". For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".