Movement is a key
Here is some information about movement system in HONK which I'll use in my another project One Spear, One Kill.
First of all, it based on this tutorial - A Comprehensive Guide To Time Dilation. Even though there is an example project, I've written my own system, which I use everywhere in the game.
Scripts
If I need to move something with acceleration or deceleration I will add in Step Event these scripts: 1. MoveObject; 2. CalculateAcceleratedVelocity; 3. CalculateDeceleratedVelocity; 4. CalculateConstantMovement;
MoveObject
It's a straightforward script, but because of using this system everywhere wherever I want, I keep it so simple. As different things require different calculations. For instance, I use both CalculateAcceleratedVelocity and CalculateDeceleratedVelocity in the player object; on the other hand, in projectiles, I use only one of these things at the same time.
It's very important to call this script before velocity calculations.
```gml //------------// // MoveObject // //------------//
// @param isConstant
var _isConstant = argument0;
if (_isConstant) { x += velocityX * global.TimeFactor; y += velocityY * global.TimeFactor; } else { x += velocityX; y += velocityY; } ```
CalculateAceleratedVelocity
This script calculates velocity while an object is accelerating.
``` //------------------------------// // CalculateAcceleratedVelocity // //------------------------------//
/// @param direction /// @param velocityCurrent /// @param velocityMax /// @param acceleration
var _targetDirection = argument0; var _velocityCurrent = argument1; var _velocityMax = argument2; var _acceleration = argument3;
//Delta X and Y calculations var positionDelta = global.TimeFactor * _velocityCurrent + (0.5 * sqr(global.TimeFactor) * _acceleration); _velocityCurrent = min(velocityCurrent + acceleration * global.TimeFactor, _velocityMax); velocityX = lengthdirx(positionDelta, _targetDirection); velocityY = lengthdiry(_positionDelta, _targetDirection);
return _velocityCurrent; ```
CalculateDeceleratedVelocity
This script calculates velocity while an object is decelerating.
``` //------------------------------// // CalculateDeceleratedVelocity // //------------------------------//
/// @param direction /// @param velocityCurrent /// @param friction
var _targetDirection = argument0; var _velocityCurrent = argument1; var _friction = argument2;
var addX = _friction * sign(velocityCurrent); var positionDelta = global.TimeFactor * _velocityCurrent + (0.5 * sqr(global.TimeFactor) * _addX); _velocityCurrent = max(velocityCurrent - friction * global.TimeFactor, 0); velocityX = lengthdirx(positionDelta, _targetDirection); velocityY = lengthdiry(_positionDelta, _targetDirection);
return _velocityCurrent; ```
CalculateConstantVelocity
In case when I need to move something with a constant velocity I use this script.
``` //---------------------------// // CalculateConstantVelocity // //---------------------------//
/// @param Velocity /// @param direction
var _velocity = argument0; var _direction = argument1;
velocityX = lengthdirx(velocity, direction); velocityY = lengthdiry(_velocity, _direction); ```
Collisions
And what about collisions? I use a classic script for checking collisions, and I place it after all movement calculations.
But be aware, I don't use this script to execute other code, e.g. destroying projectiles, dealing damage etc.
``` //----------------// // CheckCollision // //----------------//
// @param object
var _object = argument0;
// Collision X if (placemeeting(x + velocityX, y, _object)) { while (!placemeeting(x + sign(velocityX), y, _object)) { x += sign(velocityX); } velocityX = 0; }
// Collision Y if (placemeeting(x, y + velocityY, _object)) { while (!placemeeting(x, y + sign(velocityY), _object)) { y += sign(velocityY); } velocityY = 0; } ```
Thank you for reading, feel free to ask questions and give feedback.