Ordnung ist das halbe Leben
using Microsoft.Xna.Framework;
namespace ExampleWalkingOnMap
{
public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
public Game1()
{
this._graphics = new GraphicsDeviceManager(this);
this.Content.RootDirectory = "Content";
this.Window.Title = "Example Walking on map";
this.IsMouseVisible = true;
}
}
}
Zunächst muss die 'InputData.cs' bearbeitet werden, um die verarbeiteten Steuerinformationen weiter zutragen.
using Microsoft.Xna.Framework;
namespace ExampleWalkingOnMap.Components.Inputs
{
public class InputData
{
public Vector2 Move => new Vector2(this.MoveX, this.MoveY);
public float MoveX { get; set; }
public float MoveY { get; set; }
}
}
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System;
namespace ExampleWalkingOnMap.Components.Inputs
{
public class ComponentInputs : GameComponent
{
public InputData Inputs { get; private set; } = new InputData();
public ComponentInputs(Game game) : base(game) { }
public override void Update(GameTime gameTime)
{
this.Inputs.MoveX = 0;
this.Inputs.MoveY = 0;
KeyboardState stateKeyboard = Keyboard.GetState();
this.Inputs.MoveX += stateKeyboard.IsKeyDown(Keys.A) ? 1 : 0;
this.Inputs.MoveX -= stateKeyboard.IsKeyDown(Keys.D) ? 1 : 0;
this.Inputs.MoveY += stateKeyboard.IsKeyDown(Keys.W) ? 1 : 0;
this.Inputs.MoveY -= stateKeyboard.IsKeyDown(Keys.S) ? 1 : 0;
GamePadState stateGamePad = GamePad.GetState(PlayerIndex.One);
this.Inputs.MoveX += stateGamePad.ThumbSticks.Left.X * -1;
this.Inputs.MoveY += stateGamePad.ThumbSticks.Left.Y;
// Normalize
this.Inputs.MoveX = Math.Min(1, Math.Max(-1, this.Inputs.MoveX));
this.Inputs.MoveY = Math.Min(1, Math.Max(-1, this.Inputs.MoveY));
}
}
}
Für die Textur mit verschiedenen Untergründen wird eine Bilddatei zusammen gefasst, die die Unterschiedlichen Bodentexturen beinhaltet. Jedes Objekt kennt dann nur den Ausschnitt aus der Bilddatei. Für das Beispiel verwende ich die Texturen von https://kenney.nl/assets.
Im Projekt wurde bereits mit der Vorlage, der Ordner 'Content' angelegt. Hier wird nun die Textur abgelegt.
Wirkt leider etwas doppelt, aber dies ist notwendig, damit die Textur später im Programmcode geladen werden kann.
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace ExampleWalkingOnMap.Components.Map
{
public class GroundTile
{
private Rectangle _texturePosition;
public GroundTile(int x, int y, int width, int height)
{
this._texturePosition = new Rectangle(x, y, width, height);
}
public void Draw(Texture2D textureMapTiles, SpriteBatch spriteBatch, Vector2 offset)
{
spriteBatch.Draw(textureMapTiles,
offset,
this._texturePosition,
Color.White,
0f,
new Vector2(0, 0),
new Vector2(1, 1),
SpriteEffects.None,
0f);
}
}
}
using System;
namespace ExampleWalkingOnMap.Components.Map
{
internal class MapHelper
{
internal static GroundTile[,] CreateMap()
{
int[][] map = new int[10][];
map[0] = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2 };
map[1] = new int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 2, 2 };
map[2] = new int[10] { 1, 1, 1, 1, 1, 1, 1, 0, 2, 2 };
map[3] = new int[10] { 0, 0, 0, 0, 0, 0, 1, 0, 2, 2 };
map[4] = new int[10] { 0, 0, 0, 0, 0, 0, 1, 0, 2, 2 };
map[5] = new int[10] { 0, 0, 0, 0, 0, 0, 1, 0, 2, 2 };
map[6] = new int[10] { 0, 0, 0, 0, 0, 0, 1, 0, 2, 2 };
map[7] = new int[10] { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 };
map[8] = new int[10] { 0, 0, 0, 0, 0, 0, 1, 0, 3, 3 };
map[9] = new int[10] { 0, 0, 0, 0, 0, 0, 1, 0, 3, 0 };
GroundTile[,] groundTiles = new GroundTile[10, 10];
for (int iY = 0; iY < 10; iY++)
{
for (int iX = 0; iX < 10; iX++)
{
groundTiles[iY, iX] = GetMappingGroundTile(map[iY][iX]);
}
}
return groundTiles;
}
private static GroundTile GetMappingGroundTile(int groundTile)
{
switch (groundTile)
{
case 0:
return new GroundTile(0, 0, 64, 64);
case 1:
return new GroundTile(64, 0, 64, 64);
case 2:
return new GroundTile(0, 64, 64, 64);
case 3:
return new GroundTile(64, 64, 64, 64);
}
throw new ArgumentException("groundTile can be only 0, 1, 2 and 3");
}
}
}
using ExampleWalkingOnMap.Components.Inputs;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace ExampleWalkingOnMap.Components.Map
{
public class ComponentMap : GameComponent
{
private readonly ComponentInputs _inputs;
private GroundTile[,] _mapTiles;
private Texture2D _textureMapTiles;
private int _mapTileWidth, _mapTileHeight;
private Vector2 _screenOffset, _movePosition;
public Vector2 Position => new Vector2(this._movePosition.X + this._screenOffset.X,
this._movePosition.Y + this._screenOffset.Y);
private int _mapWidth, _mapHeight;
public ComponentMap(Game game, ComponentInputs inputs) : base(game) => this._inputs = inputs;
internal void SetScreenOffset(float screenWidth, float screenHeight)
{
var centerScreenWidth = screenWidth / 2;
var centerScreenHeight = screenHeight / 2;
this._screenOffset = new Vector2(centerScreenWidth, centerScreenHeight);
this._movePosition = new Vector2(0, 0);
}
public override void Initialize()
{
using (var stream = TitleContainer.OpenStream("Content/MapTiles.png"))
{
this._textureMapTiles = Texture2D.FromStream(this.Game.GraphicsDevice, stream);
}
this._mapTiles = MapHelper.CreateMap();
this._mapTileWidth = this._textureMapTiles.Width / 2;
this._mapTileHeight = this._textureMapTiles.Height / 2;
this._mapWidth = this._mapTileWidth * this._mapTiles.GetLength(0);
this._mapHeight = this._mapTileHeight * this._mapTiles.GetLength(1);
}
public override void Update(GameTime gameTime)
{
this._movePosition += this._inputs.Inputs.Move * 2f;
}
public void DrawMapTiles(SpriteBatch spriteBatch)
{
for (int iY = 0; iY < this._mapTiles.GetLength(0); iY++)
{
for (int iX = 0; iX < this._mapTiles.GetLength(1); iX++)
{
Vector2 textureOffset = new Vector2(iX * this._mapTileWidth, iY * this._mapTileHeight);
Vector2 offset = this.Position + textureOffset;
this._mapTiles[iY, iX].Draw(this._textureMapTiles, spriteBatch, offset);
}
}
}
}
}
using ExampleWalkingOnMap.Components.Map;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Windows.UI.ViewManagement;
namespace ExampleWalkingOnMap.Components.Render
{
public class ComponentRender : DrawableGameComponent
{
private readonly ComponentMap _componentMap;
private SpriteBatch _spriteBatch;
public ComponentRender(Game game, ComponentMap componentMap) : base(game)
{
this._componentMap = componentMap;
}
public override void Initialize()
{
this._spriteBatch = new SpriteBatch(this.GraphicsDevice);
var screenWidth = (float)ApplicationView.GetForCurrentView().VisibleBounds.Width;
var screenHeight = (float)ApplicationView.GetForCurrentView().VisibleBounds.Height;
this._componentMap.SetScreenOffset(screenWidth, screenHeight);
}
public override void Draw(GameTime gameTime)
{
this.GraphicsDevice.Clear(Color.DarkBlue);
this._spriteBatch.Begin();
this._componentMap.DrawMapTiles(this._spriteBatch);
this._spriteBatch.End();
}
}
}
using ExampleWalkingOnMap.Components.Inputs;
using ExampleWalkingOnMap.Components.Map;
using ExampleWalkingOnMap.Components.Render;
using Microsoft.Xna.Framework;
namespace ExampleWalkingOnMap
{
public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private ComponentInputs _componentInputs;
private ComponentMap _componentMap;
private ComponentRender _componentRender;
public Game1()
{
this._graphics = new GraphicsDeviceManager(this);
this.Content.RootDirectory = "Content";
this.Window.Title = "Example Walking on map";
this.IsMouseVisible = true;
this._componentInputs = new ComponentInputs(this);
this._componentInputs.UpdateOrder = 1;
this.Components.Add(this._componentInputs);
this._componentMap = new ComponentMap(this, this._componentInputs);
this._componentMap.UpdateOrder = 2;
this.Components.Add(this._componentMap);
this._componentRender = new ComponentRender(this, this._componentMap);
this._componentRender.UpdateOrder = 3;
this.Components.Add(this._componentRender);
}
}
}













