1
Beginners' Technical Questions / Re: Question on an obscure character movement/turning scheme.
« on: Today at 01:43 »
You'll have to ditch the Keyboard movement module. As soon as you want smooth movement that changes speed without stopping in between, player.Walk() goes out the window.
Try this:
Tested and should work as-is. (Just put it in a fresh script.)
Try this:
Code: Adventure Game Studio
- int rotate_left = eKeyLeftArrow;
- int rotate_right = eKeyRightArrow;
- int move_forward = eKeyUpArrow;
- int move_back = eKeySpace;
- float forward_speed = 3.0;
- float backward_impulse = 5.0;
- int back_blocked_frames = 80; // kick back only possible every x frames
- float laziness = 0.05; // acceleration coefficient
- // direction of forward movement
- float dx, dy = 1.0; // default: down
- float px, py;
- void on_event(EventType event, int data) {
- if (event == eEventEnterRoomBeforeFadein) {
- px = IntToFloat(player.x);
- py = IntToFloat(player.y);
- }
- }
- void on_key_press(eKeyCode k) {
- String loops = "061735240";
- int current_dir = loops.IndexOf(String.Format("%d", player.Loop));
- int old_dir = current_dir;
- if (k == rotate_left) current_dir--; if (current_dir == -1) current_dir = 7;
- if (k == rotate_right) current_dir++;
- if (current_dir != old_dir) {
- player.Loop = loops.Chars[current_dir] - 48;
- float angle = IntToFloat(current_dir + 2) * Maths.Pi / 4.0;
- dx = Maths.Cos(angle);
- dy = Maths.Sin(angle);
- }
- }
- float speed, target_speed;
- int back_locked;
- void repeatedly_execute() {
- if (back_locked) back_locked--; // count down if locked
- if (IsKeyPressed(move_forward) && !IsKeyPressed(move_back)) target_speed = forward_speed;
- else if (IsKeyPressed(move_back) && !IsKeyPressed(move_forward)) {
- if (back_locked == 0) {
- speed = -backward_impulse;
- target_speed = 0.0;
- back_locked = back_blocked_frames; // 2 seconds
- }
- }
- else target_speed = 0.0;
- // change current speed
- speed += (target_speed - speed) * laziness;
- float xa = dx * speed, ya = dy * speed; // movement vector
- // move player
- int tpx = FloatToInt(px + xa, eRoundNearest) - GetViewportX();
- int tpy = FloatToInt(py + ya, eRoundNearest) - GetViewportY();
- if (GetWalkableAreaAt(tpx, tpy)) {
- px += xa;
- py += ya;
- player.x = FloatToInt(px, eRoundNearest);
- player.y = FloatToInt(py, eRoundNearest);
- }
- else speed = 0.0;
- }
Tested and should work as-is. (Just put it in a fresh script.)
