Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using Godot;
- using Godot.Collections;
- using System;
- public enum ScrollType { SCROLL, AUTO_SCROLL }
- public enum LimitDir { LEFT = 0, RIGHT = 1, UP = 2, DOWN = 3 }
- public partial class Camera : Node2D
- {
- private ScrollType _type;
- [Export]
- public ScrollType Type
- {
- get => _type;
- set
- {
- _type = value;
- NotifyPropertyListChanged();
- }
- }
- private Viewport _cameraView;
- private Area2D _staticRegion;
- // Not pixel perfect
- private Vector2 _zoom;
- private Vector2I _viewportSize;
- private Vector2I _halfViewport;
- private int[] Limits = new int[4];
- private Area2D _focusArea;
- private Area2D _deathFrame; // Camera went too fast and player ded!
- // AUTO SCROLL PROPERTIES:
- private float _maxAutoScrollSpeed = 900; // Just a random arbitrary value, there's no rhyme or reason outside of it's a nice divisible by 3 number
- private float _autoScrollSpeed = 150;
- private Vector2 _autoScrollDir = Vector2.Right; // We scroll right by default
- [Export]
- public float AutoScrollSpeed
- {
- get => _autoScrollSpeed;
- set
- {
- _autoScrollSpeed = value;
- }
- }
- [Export]
- public Vector2 AutoScrollDir
- {
- get => _autoScrollDir;
- set
- {
- _autoScrollDir = value;
- }
- }
- [Export]
- public Vector2 Zoom
- {
- get
- {
- return _zoom;
- }
- set
- {
- _zoom = SetZoom(value);
- }
- }
- // Note, this will be called in Level.CS's loop. We assume this is a type of level that affects it's camera
- // This can be used for timed scrolling, this contains it's own speed because camera could speed up or slow down!
- public void AutoScroll(double delta, Vector2 Direction, float autoScrollSpeed)
- {
- var newOrigin = _cameraView.CanvasTransform;
- newOrigin.Origin = newOrigin.Origin.Lerp(newOrigin.Origin + Direction, (float)delta * autoScrollSpeed);
- _cameraView.CanvasTransform = newOrigin;
- }
- public void SmoothZoom(Vector2 offset, double delta, float zoomSpeed) => Zoom = Zoom.Lerp(Zoom + offset, (float)delta * zoomSpeed);
- public override void _Ready()
- {
- base._Ready();
- ProcessPriority = -1;
- _cameraView = GetViewport();
- _viewportSize = (Vector2I)_cameraView.GetVisibleRect().Size.Round();
- _halfViewport = _viewportSize / 2;
- }
- public void Snap(Vector2 desiredPosition)
- {
- var newOrigin = _cameraView.CanvasTransform;
- newOrigin.Origin = desiredPosition;
- _cameraView.CanvasTransform = newOrigin;
- }
- public void SetFocus(Area2D focus)
- {
- _focusArea = focus;
- var transform = Transform2D.Identity;
- transform.Origin = -_focusArea.Transform.Origin + (_viewportSize / 2);
- _cameraView.CanvasTransform = transform;
- }
- // Sets bounds of scrollable area based on Tilemap size and used rect
- public void SetBounds(TileMapLayer map)
- {
- var bounds = map.GetUsedRect();
- var tileSize = map.TileSet.TileSize;
- Limits[(int)LimitDir.LEFT] = bounds.Position.X * tileSize.X - _halfViewport.X;
- Limits[(int)LimitDir.RIGHT] = bounds.End.X * tileSize.X + _halfViewport.X;
- Limits[(int)LimitDir.UP] = bounds.Position.Y * tileSize.Y - _halfViewport.Y; // Y is reversed in 2D. Whyyyyyyyyyyy
- Limits[(int)LimitDir.DOWN] = bounds.End.Y * tileSize.Y + _halfViewport.Y;
- }
- public Vector2 SetZoom(Vector2 zoom)
- {
- var newTransform = _cameraView.CanvasTransform;
- GD.Print(zoom);
- newTransform.X *= zoom.X * 0.5f;
- newTransform.Y *= zoom.Y * 0.5f;
- _cameraView.CanvasTransform = newTransform;
- return zoom;
- }
- public void Scroll()
- {
- //ToDo: Detect if isScrolling Based on set static area or drag bounds!!
- var newOrigin = _cameraView.CanvasTransform;
- // Note that focusArea in this case is an Area2D, could make it a Node2D as well
- Vector2I targetPosition = (Vector2I)_focusArea.GlobalPosition.Round();
- newOrigin.Origin = -targetPosition + _halfViewport;
- // Limits are tile map limits to keep the camera in bounds
- // Currently having a small issue where the camera can't reach end of level.
- int minX = Limits[(int)LimitDir.LEFT] - _halfViewport.X;
- int maxX = Limits[(int)LimitDir.RIGHT] + _halfViewport.X;
- int minY = Limits[(int)LimitDir.UP] - _halfViewport.Y;
- int maxY = Limits[(int)LimitDir.DOWN] + _halfViewport.Y;
- // Clamp Camera to Map Limits / boundaries
- newOrigin.Origin = new Vector2(Math.Clamp((int)newOrigin.Origin.X, minX, maxX), Math.Clamp((int)newOrigin.Origin.Y, minY, maxY));
- _cameraView.CanvasTransform = newOrigin;
- }
- // For short camera pan's and transitions
- public void Pan(Vector2 Direction, float panSpeed, double delta, int time) // Not sure if time is needed
- {
- GlobalPosition = GlobalPosition.Lerp(GlobalPosition + Direction, (float)delta * panSpeed);
- }
- public override void _Process(double delta)
- {
- base._Process(delta);
- switch (_type)
- {
- case ScrollType.SCROLL:
- Scroll();
- break;
- case ScrollType.AUTO_SCROLL:
- AutoScroll(delta, _autoScrollDir, _autoScrollSpeed);
- break;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment