123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- using Godot;
- #if REAL_T_IS_DOUBLE
- using real_t = System.Double;
- #else
- using real_t = System.Single;
- #endif
- [Tool]
- public partial class PlayerSprite : Sprite2D
- {
- private static Texture2D _stand = ResourceLoader.Load<Texture2D>("res://assets/player/textures/stand.png");
- private static Texture2D _jump = ResourceLoader.Load<Texture2D>("res://assets/player/textures/jump.png");
- private static Texture2D _run = ResourceLoader.Load<Texture2D>("res://assets/player/textures/run.png");
- private const int FRAMERATE = 15;
- private int _direction;
- private float _progress;
- private Node25D _parent;
- private PlayerMath25D _parentMath;
- public override void _Ready()
- {
- _parent = GetParent<Node25D>();
- _parentMath = _parent.GetChild<PlayerMath25D>(0);
- }
- public override void _Process(real_t delta)
- {
- if (Engine.EditorHint)
- {
- return; // Don't run this in the editor.
- }
- SpriteBasis();
- bool movement = CheckMovement(); // Always run to get direction, but don't always use return bool.
- // Test-only move and collide, check if the player is on the ground.
- var k = _parentMath.MoveAndCollide(Vector3.Down * 10 * delta, true, true, true);
- if (k != null)
- {
- if (movement)
- {
- // TODO: https://github.com/godotengine/godot/issues/28748
- Hframes = 6;
- Texture = _run;
- if (Input.IsActionPressed("movement_modifier"))
- {
- delta /= 2;
- }
- _progress = (_progress + FRAMERATE * delta) % 6;
- Frame = _direction * 6 + (int)_progress;
- }
- else
- {
- Hframes = 1;
- Texture = _stand;
- _progress = 0;
- Frame = _direction;
- }
- }
- else
- {
- Hframes = 2;
- Texture = _jump;
- _progress = 0;
- int jumping = _parentMath.verticalSpeed < 0 ? 1 : 0;
- Frame = _direction * 2 + jumping;
- }
- }
- public void SetViewMode(int viewModeIndex)
- {
- Transform2D t = Transform;
- switch (viewModeIndex)
- {
- case 0:
- t.x = new Vector2(1, 0);
- t.y = new Vector2(0, 0.75f);
- break;
- case 1:
- t.x = new Vector2(1, 0);
- t.y = new Vector2(0, 1);
- break;
- case 2:
- t.x = new Vector2(1, 0);
- t.y = new Vector2(0, 0.5f);
- break;
- case 3:
- t.x = new Vector2(1, 0);
- t.y = new Vector2(0, 1);
- break;
- case 4:
- t.x = new Vector2(1, 0);
- t.y = new Vector2(0.75f, 0.75f);
- break;
- case 5:
- t.x = new Vector2(1, 0.25f);
- t.y = new Vector2(0, 1);
- break;
- }
- Transform = t;
- }
- /// <summary>
- /// Change the basis of the sprite to try and make it fit multiple view modes.
- /// </summary>
- private void SpriteBasis()
- {
- if (!Engine.EditorHint)
- {
- if (Input.IsActionPressed("forty_five_mode"))
- {
- SetViewMode(0);
- }
- else if (Input.IsActionPressed("isometric_mode"))
- {
- SetViewMode(1);
- }
- else if (Input.IsActionPressed("top_down_mode"))
- {
- SetViewMode(2);
- }
- else if (Input.IsActionPressed("front_side_mode"))
- {
- SetViewMode(3);
- }
- else if (Input.IsActionPressed("oblique_y_mode"))
- {
- SetViewMode(4);
- }
- else if (Input.IsActionPressed("oblique_z_mode"))
- {
- SetViewMode(5);
- }
- }
- }
- // There might be a more efficient way to do this, but I can't think of it.
- private bool CheckMovement()
- {
- // Gather player input and store movement to these int variables. Note: These indeed have to be integers.
- int x = 0;
- int z = 0;
- if (Input.IsActionPressed("move_right"))
- {
- x++;
- }
- if (Input.IsActionPressed("move_left"))
- {
- x--;
- }
- if (Input.IsActionPressed("move_forward"))
- {
- z--;
- }
- if (Input.IsActionPressed("move_back"))
- {
- z++;
- }
- // Check for isometric controls and add more to movement accordingly.
- // For efficiency, only check the X axis since this X axis value isn't used anywhere else.
- if (!_parentMath.isometricControls && _parent.Basis25D.x.IsEqualApprox(Basis25D.Isometric.x * Node25D.SCALE))
- {
- if (Input.IsActionPressed("move_right"))
- {
- z++;
- }
- if (Input.IsActionPressed("move_left"))
- {
- z--;
- }
- if (Input.IsActionPressed("move_forward"))
- {
- x++;
- }
- if (Input.IsActionPressed("move_back"))
- {
- x--;
- }
- }
- // Set the direction based on which inputs were pressed.
- if (x == 0)
- {
- if (z == 0)
- {
- return false; // No movement
- }
- else if (z > 0)
- {
- _direction = 0;
- }
- else
- {
- _direction = 4;
- }
- }
- else if (x > 0)
- {
- if (z == 0)
- {
- _direction = 2;
- FlipH = true;
- }
- else if (z > 0)
- {
- _direction = 1;
- FlipH = true;
- }
- else
- {
- _direction = 3;
- FlipH = true;
- }
- }
- else
- {
- if (z == 0)
- {
- _direction = 2;
- FlipH = false;
- }
- else if (z > 0)
- {
- _direction = 1;
- FlipH = false;
- }
- else
- {
- _direction = 3;
- FlipH = false;
- }
- }
- return true; // There is movement
- }
- }
|