mirror of
https://github.com/TheRavenwoodArts/LunaLightXMG.git
synced 2026-07-30 22:55:03 -07:00
Implemented scren shake in the Camera2D class
This commit is contained in:
+48
-4
@@ -12,6 +12,15 @@ namespace LunaLightXMG
|
||||
private float rotation;
|
||||
private Vector2 position;
|
||||
private Rectangle levelBounds;
|
||||
private readonly float camSpeed = 0.1f;
|
||||
|
||||
// Screen Shake
|
||||
private float shakeTimeRemaining = 0f;
|
||||
private float shakeMagnitudeCurrent = 0f;
|
||||
private bool shaking = false;
|
||||
|
||||
// Util
|
||||
Utilities util;
|
||||
|
||||
// Getters and setters
|
||||
public Vector2 Position
|
||||
@@ -33,11 +42,12 @@ namespace LunaLightXMG
|
||||
// constructor
|
||||
public Camera2D(int width, int height)
|
||||
{
|
||||
this.viewport = new Viewport(0, 0, width, height);
|
||||
viewport = new Viewport(0, 0, width, height);
|
||||
levelBounds = new Rectangle(0, 0, 320, 180); // Default
|
||||
zoom = 1f;
|
||||
rotation = 0f;
|
||||
position = Vector2.Zero;
|
||||
util = new Utilities();
|
||||
}
|
||||
|
||||
public Matrix GetViewMatrix()
|
||||
@@ -56,11 +66,45 @@ namespace LunaLightXMG
|
||||
|
||||
public void Follow(Vector2 targetPostion)
|
||||
{
|
||||
// temp code
|
||||
Vector2 smoothPosition = Vector2.Lerp(position, targetPostion, 0.1f);
|
||||
position = smoothPosition;
|
||||
position += (targetPostion - position) * camSpeed;
|
||||
if (Math.Abs(position.X - targetPostion.X) < 0.1f)
|
||||
{
|
||||
position.X = targetPostion.X;
|
||||
}
|
||||
if (Math.Abs(position.Y - targetPostion.Y) < 0.1f)
|
||||
{
|
||||
position.Y = targetPostion.Y;
|
||||
}
|
||||
ClampToBounds();
|
||||
}
|
||||
|
||||
public void ScreenShake(float shakeTime, float shakeMagnitude)
|
||||
{
|
||||
shakeTimeRemaining = shakeTime;
|
||||
shakeMagnitudeCurrent = shakeMagnitude;
|
||||
shaking = true;
|
||||
}
|
||||
|
||||
public void UpdateScreenShake(GameTime gameTime)
|
||||
{
|
||||
if (!shaking) return;
|
||||
|
||||
if (shakeTimeRemaining > 0)
|
||||
{
|
||||
float shakeX = util.ChooseFromRange(-shakeMagnitudeCurrent, shakeMagnitudeCurrent);
|
||||
float shakeY = util.ChooseFromRange(-shakeMagnitudeCurrent, shakeMagnitudeCurrent);
|
||||
position.X += shakeX;
|
||||
position.Y += shakeY;
|
||||
shakeTimeRemaining -= (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
shakeMagnitudeCurrent *= 0.9f;
|
||||
}
|
||||
else
|
||||
{
|
||||
shaking = false;
|
||||
shakeTimeRemaining = 0f;
|
||||
shakeMagnitudeCurrent = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
private void ClampToBounds()
|
||||
{
|
||||
|
||||
+18
-18
@@ -27,11 +27,11 @@ namespace LunaLightXMG
|
||||
// Test Render Target Handler
|
||||
private RenderHandler renderHandler;
|
||||
bool resizing;
|
||||
|
||||
|
||||
// Test sprites - eventually handle in a sprite manager?
|
||||
private Texture2D platformTexture;
|
||||
private Texture2D sinkArea;
|
||||
|
||||
|
||||
// Test platforms
|
||||
private Platform[] platforms;
|
||||
private int numOfPlatforms;
|
||||
@@ -44,8 +44,8 @@ namespace LunaLightXMG
|
||||
private SpriteFont debugFont;
|
||||
private Texture2D debugGrid;
|
||||
|
||||
// Utility
|
||||
private static Random random;
|
||||
// Util
|
||||
Utilities util;
|
||||
|
||||
public LunaLightGame()
|
||||
{
|
||||
@@ -63,11 +63,11 @@ namespace LunaLightXMG
|
||||
playerInput = new PlayerInput();
|
||||
enemies = new List<Enemy>();
|
||||
|
||||
random = new Random(42);
|
||||
|
||||
// Init number of platforms / enemies
|
||||
numOfPlatforms = 4;
|
||||
numOfEnemies = 10;
|
||||
|
||||
util = new Utilities();
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
@@ -80,7 +80,7 @@ namespace LunaLightXMG
|
||||
playerInput.HasControl = true; // May need to find a new home for this
|
||||
|
||||
base.Initialize();
|
||||
|
||||
|
||||
// Initialize camera
|
||||
camera2D = new Camera2D(retroWidth, retroHeight);
|
||||
// camera test - set level bounds
|
||||
@@ -103,7 +103,7 @@ namespace LunaLightXMG
|
||||
var KeyB = keyboardState.IsKeyDown(Keys.B);
|
||||
var KeyN = keyboardState.IsKeyDown(Keys.N);
|
||||
var KeyM = keyboardState.IsKeyDown(Keys.M);
|
||||
|
||||
var KeyP = keyboardState.IsKeyDown(Keys.P);
|
||||
if (KeyK)
|
||||
{
|
||||
camera2D.Rotation -= 0.01f;
|
||||
@@ -124,6 +124,10 @@ namespace LunaLightXMG
|
||||
{
|
||||
renderHandler.ZoomOut();
|
||||
}
|
||||
if (KeyP)
|
||||
{
|
||||
camera2D.ScreenShake(0.5f, 5f);
|
||||
}
|
||||
}
|
||||
// ---------------------------------------
|
||||
protected override void LoadContent()
|
||||
@@ -161,7 +165,7 @@ namespace LunaLightXMG
|
||||
// Test player input and movement with abstracted player class
|
||||
playerInput.Update();
|
||||
player.Update(gameTime, playerInput, platforms);
|
||||
|
||||
|
||||
foreach (var enemy in enemies) {
|
||||
enemy.Update(gameTime, player, platforms);
|
||||
}
|
||||
@@ -169,12 +173,13 @@ namespace LunaLightXMG
|
||||
renderHandler.UpdateZoom();
|
||||
// Update camera position
|
||||
camera2D.Follow(player.position);
|
||||
camera2D.UpdateScreenShake(gameTime);
|
||||
// camera testing
|
||||
TestCameraWhilePlaying();
|
||||
|
||||
base.Update(gameTime);
|
||||
}
|
||||
|
||||
|
||||
protected override void Draw(GameTime gameTime)
|
||||
{
|
||||
GraphicsDevice.Clear(Color.CornflowerBlue);
|
||||
@@ -211,7 +216,7 @@ namespace LunaLightXMG
|
||||
for (int i = 0; i < numberOfEnemies; i++)
|
||||
{
|
||||
Vector2 spawnPosition = new Vector2(16 + i * 3, -16);
|
||||
Enemy enemy = new Enemy(spawnPosition, GetRandomValueBetween1And3());
|
||||
Enemy enemy = new(spawnPosition, util.ChooseFromRange(1,3));
|
||||
enemy.LoadContent(Content);
|
||||
enemies.Add(enemy);
|
||||
}
|
||||
@@ -258,16 +263,11 @@ namespace LunaLightXMG
|
||||
|
||||
|
||||
spriteBatch.DrawString(debugFont, $"Camera Rotation Control - Rotate left: K, Rotate right: L", new Vector2(10, 190), Color.White);
|
||||
|
||||
spriteBatch.DrawString(debugFont, $"Render Target Zoom Control - Zoom in: B, Zoom normal: N, Zoom out: M", new Vector2(10, 210), Color.White);
|
||||
|
||||
spriteBatch.DrawString(debugFont, $"Press P to test screen shake.", new Vector2(10, 230), Color.White);
|
||||
spriteBatch.End();
|
||||
}
|
||||
|
||||
public static float GetRandomValueBetween1And3()
|
||||
{
|
||||
return (float)(1 + 2 * random.NextDouble());
|
||||
}
|
||||
|
||||
private void ResetGame()
|
||||
{
|
||||
// reset cam
|
||||
|
||||
+17
-1
@@ -30,4 +30,20 @@ Solutions:
|
||||
- We could abandon zoom in the camera and control zoom by changing the render target values.
|
||||
- We should in either case only zoom at integer values to preserve pixel-perfect zoom.
|
||||
|
||||
Leaning towards abstracting the render target code to its own class and handling zoom there. Overall I think this will be better as it is what draws to the backbuffer.
|
||||
Leaning towards abstracting the render target code to its own class and handling zoom there. Overall I think this will be better as it is what draws to the backbuffer.
|
||||
|
||||
## March 19th, 2025 - JME
|
||||
|
||||
**ScreenShake**
|
||||
|
||||
I have already done this in the GML version however it has to be reimplemented to work with our current class structure. We should be able to add a ScreenShake() function to the Camera2D class that takes in shake time and shake magnitude arguments.
|
||||
|
||||
The function will work by randomly changing the cam position between the current position + magnitude and current position - magnitude. We already have a nice function written in our LunaLigthGame class that randomly chooses a number between to set numbers. **side note** It might be nice to create a utility class and move this function over there so we can use it from anywehre.
|
||||
|
||||
**Refining camera movement a bit**
|
||||
|
||||
When the player stops the camera slows to a stop. This is good except that in the last few mometns the camera gets kinda shakey beacause the Lerp() function we are using calculates to the 5th decimal and as it approaches the final postion the camera jumps from pixel to pixel slowly.
|
||||
|
||||
Rather than use Lerp() let's explicitly define our follow code and once the cam position is witin a certain threshold of target position we can snap it to the target position.
|
||||
|
||||
**Needs more refinement**
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace LunaLightXMG
|
||||
{
|
||||
public class Utilities
|
||||
{
|
||||
private Random random;
|
||||
|
||||
public Utilities(int seed = 42)
|
||||
{
|
||||
random = new Random(seed);
|
||||
}
|
||||
|
||||
public float ChooseFromRange(float num1, float num2)
|
||||
{
|
||||
return (float)(num1 + (num2 - num1) * random.NextDouble());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user