Maus zur Weltposition MonospielC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Maus zur Weltposition Monospiel

Post by Anonymous »

Ich habe einige Probleme, diesen Code zum Laufen zu bringen. Ich habe einen Debug-Bildschirm, in dem ich den Player und die Mausposition sehen kann, aber wenn sie nicht übereinstimmen, obwohl sich der Cursor über dem Player befindet.
Hier ist der relevante Code:

Code: Select all

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using TheCore.Entities.Characters;
using TheCore.Entities.Components.Core;
using TheCore.Utils.Geometry;

namespace TheCore.World;

public class Camera
{
private readonly float _cameraHeight = 720f;

// Virtual camera size
private readonly float _cameraWidth = 1280f;
private Vector2 _mapSize;
private Player _player;
private int _tileSize;
private Viewport _viewport;

private Vector2 _targetPosition;
private float _followSpeed = 8f;

public Vector2 Position;

public Camera() {
Transform = Matrix.Identity;
}

public Vector2 ClampedPosition { get; private set; }

public Matrix Transform { get; private set; }

public void SetTarget(Player player) {
_player = player;
}

/// 
///     Provides the camera with map size so it never moves outside the map
/// 
public void SetMapAndTiles(Vector2 mapSize, int tileSize) {
_mapSize = mapSize;
_tileSize = tileSize;
}

public void Update() {
_viewport = Globals.CoreServices.WindowManager.ScaledViewport;
_targetPosition = _player.GetComponent().Position;

float delta = Globals.DeltaTime;

Position = Vector2.Lerp(
Position,
_targetPosition,
1f - MathF.Exp(-_followSpeed * delta));

CalculateTransform();
}

/// 
///     Creates the final world-to-screen transformation matrix
/// 
private void CalculateTransform() {
// Scales the camera base size based on the scaled viewport
var scaleX = _viewport.Width / _cameraWidth;
var scaleY = _viewport.Height / _cameraHeight;
var scale = Math.Min(scaleX, scaleY);

// Clamp camera center inside the map boundaries
var posX = Math.Clamp(Position.X, _cameraWidth / 2, _mapSize.X * _tileSize - _cameraWidth / 2);
var posY = Math.Clamp(Position.Y, _cameraHeight / 2, _mapSize.Y * _tileSize - _cameraHeight / 2);

ClampedPosition = new Vector2(posX, posY);

Transform =
Matrix.CreateTranslation(new Vector3(-posX, -posY, 0f)) *
Matrix.CreateTranslation(new Vector3(_cameraWidth / 2f, _cameraHeight / 2f, 0f)) *
Matrix.CreateScale(scale, scale, 1f);
}

public RectangleF GetWorldViewBounds() {
return new RectangleF(
ClampedPosition.X - _cameraWidth / 2f,
ClampedPosition.Y - _cameraHeight / 2f,
_cameraWidth,
_cameraHeight
);
}

public Vector2 RenderToWorld(Vector2 renderPos) {
Matrix inverseTransform = Matrix.Invert(Transform);
Vector2 mouseInWorld = Vector2.Transform(renderPos, inverseTransform);

return mouseInWorld;

/*Vector2 renderCenter = new Vector2(
Globals.CoreServices.WindowManager.RenderWidth / 2f,
Globals.CoreServices.WindowManager.RenderHeight / 2f
);

return ClampedPosition + (renderPos - renderCenter);*/
}
}

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;

namespace TheCore.Services {
public class WindowManager {
private readonly Game _game;
private readonly GraphicsDeviceManager _graphics;

// Base resolution
public int RenderWidth = 1920;
public int RenderHeight = 1080;
//
public RenderTarget2D RenderTarget {get; set;}

//
private int _windowWidth;
private int _windowHeight;

// The resolution will be scaled on these values given the window size of the player
private int _scaledWidth;
private int _scaledHeight;
public bool IsFullsize = false;

public GraphicsDevice GraphicsDevice => _graphics.GraphicsDevice;

public Viewport ScaledViewport { get; private set;  }

// This matrix is important for the spritebatches to scale everything
public Matrix ScaledMatrix
{
get
{
float scaleX = (float)_scaledWidth / RenderWidth;
float scaleY = (float)_scaledHeight / RenderHeight;
float scale = Math.Min(scaleX, scaleY);

return Matrix.CreateScale(scale, scale, 1f);
}
}

public WindowManager(Game game, GraphicsDeviceManager graphics) {
_game = game;
_graphics = graphics;
_graphics.HardwareModeSwitch = false;

game.IsFixedTimeStep = false;

_graphics.SynchronizeWithVerticalRetrace = true;

SetupWindow();
}

/// 
///     Setups the window when the game starts
/// 
private void SetupWindow() {
//
_windowWidth = RenderWidth;
_windowHeight = RenderHeight;

_game.Window.AllowUserResizing = true;
_game.Window.ClientSizeChanged += OnWindowResize;
_graphics.IsFullScreen = IsFullsize;

UpdateScaledViewport();
CreateRenderTarget();
}

/// 
/// Calls the viewport update function if player resizes the window
/// 
private void OnWindowResize(object sender, EventArgs e) {
UpdateScaledViewport();
}

/// 
/// Updates the visible viewport based on the window size of the player
/// 
private void UpdateScaledViewport()
{
int windowW = _graphics.GraphicsDevice.PresentationParameters.BackBufferWidth;
int windowH = _graphics.GraphicsDevice.PresentationParameters.BackBufferHeight;

float targetAspect = (float)RenderWidth / RenderHeight;
float windowAspect = (float)windowW / windowH;

int vpWidth, vpHeight, vpX, vpY;

if (windowAspect > targetAspect)
{
// Window higher --> backgroundcolour visible left/right
vpHeight = windowH;
vpWidth = (int)(vpHeight * targetAspect);
vpX = (windowW - vpWidth) / 2;
vpY = 0;
}
else
{
// Window higher --> backgroundcolour visible up/down
vpWidth = windowW;
vpHeight = (int)(vpWidth / targetAspect);
vpX = 0;
vpY = (windowH - vpHeight) / 2;
}

ScaledViewport = new Viewport(vpX, vpY, vpWidth, vpHeight);
_graphics.GraphicsDevice.Viewport = ScaledViewport;

_scaledWidth = vpWidth;
_scaledHeight = vpHeight;
}

public void ChangeFullsize() {
IsFullsize = !IsFullsize;
_graphics.IsFullScreen = IsFullsize;
_graphics.ApplyChanges();
}

public void SetFullScreen(bool enable) {
if (enable == IsFullsize) return;
IsFullsize = enable;
_graphics.IsFullScreen = enable;
if (!enable) {
_graphics.PreferredBackBufferWidth = _windowWidth;
_graphics.PreferredBackBufferHeight = _windowHeight;         }
if (enable)
{
_windowWidth= _graphics.PreferredBackBufferWidth;
_windowHeight= _graphics.PreferredBackBufferHeight;
}
_graphics.ApplyChanges();
UpdateScaledViewport();
}

public void SetResolution(int index) {
var resolutions = new (int width, int height)[] { (1280, 720), (1600, 900), (1920, 1080) };

index = MathHelper.Clamp(index, 0, resolutions.Length - 1);

var res = resolutions[index];
RenderWidth = res.width;
RenderHeight = res.height;
CreateRenderTarget();
UpdateScaledViewport();
}
private void CreateRenderTarget()
{
if(RenderTarget != null)
{
RenderTarget.Dispose();
RenderTarget = null;
}
RenderTarget = new RenderTarget2D(_graphics.GraphicsDevice, RenderWidth, RenderHeight);
}

// To transform mouseclicks
public Vector2 MouseWindowToRender(Vector2 mouseWindow) {
float x = (mouseWindow.X - ScaledViewport.X)
* RenderWidth / ScaledViewport.Width;

float y = (mouseWindow.Y - ScaledViewport.Y)
* RenderHeight / ScaledViewport.Height;

return new Vector2(x, y);
}

public void f11FullScreen()
{
SetFullScreen(!IsFullsize);
}
}
}
Mein Input Manager:

Code: Select all

var rawMouse = currMouseState.Position.ToVector2();
var gameMouse = Globals.CoreServices.WindowManager.MouseWindowToRender(rawMouse);
return new InputState(gameMouse, activeActions);
Mit der gameMouse bewerbe ich mich dann

Code: Select all

worldManager.Camera.RenderToWorld(gameMouse);
aber diese Position scheint nicht richtig zu sein.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post