mirror of
https://github.com/TheRavenwoodArts/LunaLightXMG.git
synced 2026-07-30 23:35:02 -07:00
Implemented RenderHandler class with zoom. This zoom is pretty garbage but on the right track I think.
This commit is contained in:
+44
-54
@@ -24,9 +24,8 @@ namespace LunaLightXMG
|
|||||||
private int retroWidth = 320;
|
private int retroWidth = 320;
|
||||||
private int retroHeight = 180;
|
private int retroHeight = 180;
|
||||||
|
|
||||||
// Test Render Target
|
// Test Render Target Handler
|
||||||
private RenderTarget2D renderTarget;
|
private RenderHandler renderHandler;
|
||||||
private Rectangle renderDestination;
|
|
||||||
bool resizing;
|
bool resizing;
|
||||||
|
|
||||||
// Test sprites - eventually handle in a sprite manager?
|
// Test sprites - eventually handle in a sprite manager?
|
||||||
@@ -85,9 +84,9 @@ namespace LunaLightXMG
|
|||||||
// Initialize camera
|
// Initialize camera
|
||||||
camera2D = new Camera2D(retroWidth, retroHeight);
|
camera2D = new Camera2D(retroWidth, retroHeight);
|
||||||
// camera test - set level bounds
|
// camera test - set level bounds
|
||||||
camera2D.SetLevelBounds(new Rectangle(0,0,480,270)); // default 320x180
|
camera2D.SetLevelBounds(new Rectangle(0,0,480,270)); // Testing - default 320x180
|
||||||
|
|
||||||
CalculateRenderDestination();
|
renderHandler.CalculateRenderDestination();
|
||||||
// Play music
|
// Play music
|
||||||
// PlayBackgroundMusic(sinkBeats);
|
// PlayBackgroundMusic(sinkBeats);
|
||||||
|
|
||||||
@@ -95,14 +94,17 @@ namespace LunaLightXMG
|
|||||||
platforms = PlatformGenerator.CreatePlatforms(numOfPlatforms);
|
platforms = PlatformGenerator.CreatePlatforms(numOfPlatforms);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Testing camera ------------------------
|
// Testing camera and render target handler ------------------------
|
||||||
private void TestCameraWhilePlaying()
|
private void TestCameraWhilePlaying()
|
||||||
{
|
{
|
||||||
KeyboardState keyboardState = Keyboard.GetState();
|
KeyboardState keyboardState = Keyboard.GetState();
|
||||||
var KeyI = keyboardState.IsKeyDown(Keys.I) ? true : false;
|
var KeyI = keyboardState.IsKeyDown(Keys.I);
|
||||||
var KeyO = keyboardState.IsKeyDown(Keys.O) ? true : false;
|
var KeyO = keyboardState.IsKeyDown(Keys.O);
|
||||||
var KeyK = keyboardState.IsKeyDown(Keys.K) ? true : false;
|
var KeyK = keyboardState.IsKeyDown(Keys.K);
|
||||||
var KeyL = keyboardState.IsKeyDown(Keys.L) ? true : false;
|
var KeyL = keyboardState.IsKeyDown(Keys.L);
|
||||||
|
var KeyB = keyboardState.IsKeyDown(Keys.B);
|
||||||
|
var KeyN = keyboardState.IsKeyDown(Keys.N);
|
||||||
|
var KeyM = keyboardState.IsKeyDown(Keys.M);
|
||||||
|
|
||||||
if (KeyI)
|
if (KeyI)
|
||||||
{
|
{
|
||||||
@@ -120,6 +122,18 @@ namespace LunaLightXMG
|
|||||||
{
|
{
|
||||||
camera2D.Rotation += 0.01f;
|
camera2D.Rotation += 0.01f;
|
||||||
}
|
}
|
||||||
|
if (KeyB)
|
||||||
|
{
|
||||||
|
renderHandler.ZoomIn();
|
||||||
|
}
|
||||||
|
if (KeyN)
|
||||||
|
{
|
||||||
|
renderHandler.ZoomNormalize();
|
||||||
|
}
|
||||||
|
if (KeyM)
|
||||||
|
{
|
||||||
|
renderHandler.ZoomOut();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// ---------------------------------------
|
// ---------------------------------------
|
||||||
protected override void LoadContent()
|
protected override void LoadContent()
|
||||||
@@ -137,8 +151,8 @@ namespace LunaLightXMG
|
|||||||
// Spawn 10 enemies at the start of the level
|
// Spawn 10 enemies at the start of the level
|
||||||
enemies = SpawnEnemies(numOfEnemies);
|
enemies = SpawnEnemies(numOfEnemies);
|
||||||
|
|
||||||
// Test Render Target
|
// Test Render Target Handler
|
||||||
renderTarget = new RenderTarget2D(GraphicsDevice, retroWidth, retroHeight);
|
renderHandler = new RenderHandler(GraphicsDevice, spriteBatch, retroWidth, retroHeight);
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
debugFont = Content.Load<SpriteFont>("fonts/debugFont");
|
debugFont = Content.Load<SpriteFont>("fonts/debugFont");
|
||||||
@@ -161,7 +175,8 @@ namespace LunaLightXMG
|
|||||||
foreach (var enemy in enemies) {
|
foreach (var enemy in enemies) {
|
||||||
enemy.Update(gameTime, player, platforms);
|
enemy.Update(gameTime, player, platforms);
|
||||||
}
|
}
|
||||||
|
// test render handler zoom
|
||||||
|
renderHandler.UpdateZoom();
|
||||||
// Update camera position
|
// Update camera position
|
||||||
camera2D.Follow(player.position);
|
camera2D.Follow(player.position);
|
||||||
// camera testing
|
// camera testing
|
||||||
@@ -174,18 +189,8 @@ namespace LunaLightXMG
|
|||||||
{
|
{
|
||||||
GraphicsDevice.Clear(Color.CornflowerBlue);
|
GraphicsDevice.Clear(Color.CornflowerBlue);
|
||||||
|
|
||||||
// Test Render Target - Draw sprites to the render target
|
// // Test Render Target Handler - Draw sprites to the render (target
|
||||||
GraphicsDevice.SetRenderTarget(renderTarget);
|
renderHandler.BeginRenderTarget(camera2D.GetViewMatrix());
|
||||||
|
|
||||||
// Add camera to draw batch
|
|
||||||
spriteBatch.Begin(
|
|
||||||
transformMatrix: camera2D.GetViewMatrix(),
|
|
||||||
samplerState: SamplerState.PointClamp
|
|
||||||
);
|
|
||||||
|
|
||||||
// Debug Grid
|
|
||||||
// spriteBatch.Draw(debugGrid, new Vector2(0, 0), Color.Blue);
|
|
||||||
// spriteBatch.Draw(sinkArea, new Vector2(0, 0), Color.White);
|
|
||||||
|
|
||||||
// Test draw tiles
|
// Test draw tiles
|
||||||
foreach (var platform in platforms)
|
foreach (var platform in platforms)
|
||||||
@@ -201,14 +206,8 @@ namespace LunaLightXMG
|
|||||||
enemy.Draw(spriteBatch);
|
enemy.Draw(spriteBatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
spriteBatch.End();
|
renderHandler.EndRenderTarget();
|
||||||
|
renderHandler.DrawRenderTarget();
|
||||||
|
|
||||||
// Test Render Target - Draw render target to the screen
|
|
||||||
GraphicsDevice.SetRenderTarget(null);
|
|
||||||
spriteBatch.Begin(samplerState: SamplerState.PointClamp);
|
|
||||||
spriteBatch.Draw(renderTarget, renderDestination, Color.White);
|
|
||||||
spriteBatch.End();
|
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
DrawDebugInfo();
|
DrawDebugInfo();
|
||||||
@@ -249,31 +248,11 @@ namespace LunaLightXMG
|
|||||||
if (!resizing && Window.ClientBounds.Width > 0 && Window.ClientBounds.Height > 0)
|
if (!resizing && Window.ClientBounds.Width > 0 && Window.ClientBounds.Height > 0)
|
||||||
{
|
{
|
||||||
resizing = true;
|
resizing = true;
|
||||||
CalculateRenderDestination();
|
renderHandler.CalculateRenderDestination();
|
||||||
resizing = false;
|
resizing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CalculateRenderDestination()
|
|
||||||
{
|
|
||||||
Point size = GraphicsDevice.Viewport.Bounds.Size;
|
|
||||||
|
|
||||||
// Calculate the integer scale factor
|
|
||||||
int scaleX = size.X / renderTarget.Width;
|
|
||||||
int scaleY = size.Y / renderTarget.Height;
|
|
||||||
int scale = Math.Min(scaleX, scaleY);
|
|
||||||
|
|
||||||
// Ensure the scale is at least 1
|
|
||||||
scale = Math.Max(scale, 1);
|
|
||||||
|
|
||||||
// Set renderDestination
|
|
||||||
renderDestination.Width = (int)(renderTarget.Width * scale);
|
|
||||||
renderDestination.Height = (int)(renderTarget.Height * scale);
|
|
||||||
|
|
||||||
renderDestination.X = (size.X - renderDestination.Width) / 2;
|
|
||||||
renderDestination.Y = (size.Y - renderDestination.Height) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawDebugInfo()
|
private void DrawDebugInfo()
|
||||||
{
|
{
|
||||||
spriteBatch.Begin();
|
spriteBatch.Begin();
|
||||||
@@ -286,6 +265,13 @@ namespace LunaLightXMG
|
|||||||
spriteBatch.DrawString(debugFont, $"Camera Position: {camera2D.Position}", new Vector2(10, 90), Color.White);
|
spriteBatch.DrawString(debugFont, $"Camera Position: {camera2D.Position}", new Vector2(10, 90), Color.White);
|
||||||
spriteBatch.DrawString(debugFont, $"Camera Zoom: {camera2D.Zoom}", new Vector2(10, 110), Color.White);
|
spriteBatch.DrawString(debugFont, $"Camera Zoom: {camera2D.Zoom}", new Vector2(10, 110), Color.White);
|
||||||
spriteBatch.DrawString(debugFont, $"Camera Rotation: {camera2D.Rotation}", new Vector2(10, 130), Color.White);
|
spriteBatch.DrawString(debugFont, $"Camera Rotation: {camera2D.Rotation}", new Vector2(10, 130), Color.White);
|
||||||
|
spriteBatch.DrawString(debugFont, $"Render Target Zoom: {renderHandler.ZoomLevel}", new Vector2(10, 150), Color.White);
|
||||||
|
|
||||||
|
|
||||||
|
spriteBatch.DrawString(debugFont, $"Camera Zoom Control - Zoom in: I, Zoom out: O", new Vector2(10, 170), Color.White);
|
||||||
|
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.End();
|
spriteBatch.End();
|
||||||
}
|
}
|
||||||
@@ -296,6 +282,10 @@ namespace LunaLightXMG
|
|||||||
}
|
}
|
||||||
private void ResetGame()
|
private void ResetGame()
|
||||||
{
|
{
|
||||||
|
// reset cam
|
||||||
|
camera2D.Rotation = 0;
|
||||||
|
camera2D.Zoom = 1f;
|
||||||
|
|
||||||
// Reset player position
|
// Reset player position
|
||||||
player.Reset(new Vector2(163, 0));
|
player.Reset(new Vector2(163, 0));
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace LunaLightXMG
|
||||||
|
{
|
||||||
|
public class RenderHandler
|
||||||
|
{
|
||||||
|
// fields
|
||||||
|
private GraphicsDevice graphicsDevice;
|
||||||
|
private SpriteBatch spriteBatch;
|
||||||
|
private RenderTarget2D renderTarget;
|
||||||
|
private Rectangle renderDestination;
|
||||||
|
|
||||||
|
private int retroWidth;
|
||||||
|
private int retroHeight;
|
||||||
|
private float zoomLevel = 1.0f;
|
||||||
|
private float zoomTarget = 1.0f;
|
||||||
|
private readonly float zoomMin = 0.75f;
|
||||||
|
private readonly float zoomNorm = 1.0f;
|
||||||
|
private readonly float zoomMax = 1.25f;
|
||||||
|
private readonly float zoomSpeed = 0.1f;
|
||||||
|
public float ZoomLevel {get => zoomLevel;}
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
public RenderHandler(GraphicsDevice graphicsDevice, SpriteBatch spriteBatch, int retroWidth, int retroHeight)
|
||||||
|
{
|
||||||
|
this.graphicsDevice = graphicsDevice;
|
||||||
|
this.spriteBatch = spriteBatch;
|
||||||
|
this.retroWidth = retroWidth;
|
||||||
|
this.retroHeight = retroHeight;
|
||||||
|
|
||||||
|
renderTarget = new RenderTarget2D(graphicsDevice, retroWidth, retroHeight);
|
||||||
|
|
||||||
|
CalculateRenderDestination();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ZoomIn()
|
||||||
|
{
|
||||||
|
zoomTarget = zoomMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ZoomNormalize()
|
||||||
|
{
|
||||||
|
zoomTarget = zoomNorm;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ZoomOut()
|
||||||
|
{
|
||||||
|
zoomTarget = zoomMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateZoom()
|
||||||
|
{
|
||||||
|
zoomLevel = MathHelper.Lerp(zoomLevel, zoomTarget, zoomSpeed);
|
||||||
|
zoomLevel = MathHelper.Clamp(zoomLevel, zoomMin, zoomMax);
|
||||||
|
CalculateRenderDestination();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CalculateRenderDestination()
|
||||||
|
{
|
||||||
|
Point screenSize = graphicsDevice.Viewport.Bounds.Size;
|
||||||
|
// Calculate the integer scale factor
|
||||||
|
int scaleX = screenSize.X / (int)(retroWidth * zoomLevel);
|
||||||
|
int scaleY = screenSize.Y / (int)(retroHeight * zoomLevel);
|
||||||
|
|
||||||
|
// Set renderDestination
|
||||||
|
renderDestination.Width = retroWidth * scaleX;
|
||||||
|
renderDestination.Height = retroHeight * scaleY;
|
||||||
|
renderDestination.X = (screenSize.X - renderDestination.Width) / 2;
|
||||||
|
renderDestination.Y = (screenSize.Y - renderDestination.Height) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void BeginRenderTarget(Matrix cameraMatrix)
|
||||||
|
{
|
||||||
|
graphicsDevice.SetRenderTarget(renderTarget);
|
||||||
|
graphicsDevice.Clear(Color.Black);
|
||||||
|
|
||||||
|
spriteBatch.Begin(transformMatrix: cameraMatrix, samplerState: SamplerState.PointClamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EndRenderTarget()
|
||||||
|
{
|
||||||
|
spriteBatch.End();
|
||||||
|
graphicsDevice.SetRenderTarget(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawRenderTarget()
|
||||||
|
{
|
||||||
|
spriteBatch.Begin(samplerState: SamplerState.PointClamp);
|
||||||
|
spriteBatch.Draw(renderTarget, renderDestination, Color.White);
|
||||||
|
spriteBatch.End();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
## March 17th, 2025 - JME
|
||||||
|
|
||||||
|
Abstracting the render target code to its own class will help clean up our main game class as well as create a space for fullscreen effects. The first will be zoom.
|
||||||
|
|
||||||
|
Here's what the render handler can do.
|
||||||
|
|
||||||
|
- Create and manage the Render Target
|
||||||
|
- Handle scaling and fitting to the screen - CalculateRenderDestination()
|
||||||
|
- USe a method to apply changes to zoom - use integer increments for pixel perfect scaling
|
||||||
|
- Encapsulate the render pipeline - sprite batch beginning to end for the render target
|
||||||
|
|
||||||
|
## March 18th, 2025 - JME
|
||||||
|
|
||||||
|
**Render Handler Zoom**
|
||||||
|
|
||||||
|
Trying out zoom using the render target. The render target is set by retroWidth and retroHeight (320x180).
|
||||||
|
|
||||||
|
- ZoomIn() should smoothly zoom to 75% retroWidth x retroHeight, 240x135
|
||||||
|
|
||||||
|
- ZoomOut() should smoothly zoom to 125% retroWidth x retroHeight, 400x225
|
||||||
Reference in New Issue
Block a user