mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-10-01 15:46:17 -04:00
Added initial pieces of the map engine.
This commit is contained in:
parent
d3a718d8f6
commit
3a0cbe4b8e
20
OpenDiablo2.Common/Interfaces/IGameState.cs
Normal file
20
OpenDiablo2.Common/Interfaces/IGameState.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Models;
|
||||
|
||||
namespace OpenDiablo2.Common.Interfaces
|
||||
{
|
||||
public interface IGameState
|
||||
{
|
||||
MPQDS1 MapData { get; }
|
||||
int Act { get; }
|
||||
string MapName { get; }
|
||||
Palette CurrentPalette { get; }
|
||||
|
||||
void Initialize(string text, eHero value);
|
||||
}
|
||||
}
|
18
OpenDiablo2.Common/Interfaces/IMapEngine.cs
Normal file
18
OpenDiablo2.Common/Interfaces/IMapEngine.cs
Normal file
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OpenDiablo2.Common.Models;
|
||||
|
||||
namespace OpenDiablo2.Common.Interfaces
|
||||
{
|
||||
public interface IMapEngine
|
||||
{
|
||||
PointF CameraLocation { get; set; }
|
||||
void Update(long ms);
|
||||
void Render();
|
||||
void NotifyMapChanged();
|
||||
}
|
||||
}
|
@ -77,8 +77,10 @@
|
||||
<Compile Include="Interfaces\IEngineDataManager.cs" />
|
||||
<Compile Include="Interfaces\IFont.cs" />
|
||||
<Compile Include="Interfaces\IGameEngine.cs" />
|
||||
<Compile Include="Interfaces\IGameState.cs" />
|
||||
<Compile Include="Interfaces\IKeyboardInfoProvider.cs" />
|
||||
<Compile Include="Interfaces\ILabel.cs" />
|
||||
<Compile Include="Interfaces\IMapEngine.cs" />
|
||||
<Compile Include="Interfaces\IMPQProvider.cs" />
|
||||
<Compile Include="Interfaces\IMusicProvider.cs" />
|
||||
<Compile Include="Interfaces\IPaletteProvider.cs" />
|
||||
|
@ -1,6 +1,7 @@
|
||||
using Autofac;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Core.GameState_;
|
||||
using OpenDiablo2.Core.Map_Engine;
|
||||
using OpenDiablo2.Core.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -24,8 +25,9 @@ namespace OpenDiablo2.Core
|
||||
builder.RegisterType<TextDictionary>().As<ITextDictionary>().SingleInstance();
|
||||
builder.RegisterType<Button>().AsSelf().InstancePerDependency(); // TODO: Never register as Self() if we aren't in common...
|
||||
builder.RegisterType<TextBox>().AsSelf().InstancePerDependency(); // TODO: Never register as Self() if we aren't in common...
|
||||
builder.RegisterType<GameState>().AsSelf().SingleInstance(); // TODO: Never register as Self() if we aren't in common...
|
||||
builder.RegisterType<GameState>().As<IGameState>().SingleInstance();
|
||||
builder.RegisterType<EngineDataManager>().As<IEngineDataManager>().SingleInstance();
|
||||
builder.RegisterType<MapEngine>().As<IMapEngine>().SingleInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,23 +10,29 @@ using OpenDiablo2.Common.Models;
|
||||
|
||||
namespace OpenDiablo2.Core.GameState_
|
||||
{
|
||||
public sealed class GameState
|
||||
public sealed class GameState : IGameState
|
||||
{
|
||||
private readonly ISceneManager sceneManager;
|
||||
private readonly IResourceManager resourceManager;
|
||||
private readonly IPaletteProvider paletteProvider;
|
||||
private readonly Func<IMapEngine> getMapEngine;
|
||||
|
||||
public MPQDS1 MapData { get; set; }
|
||||
public bool MapDirty { get; set; }
|
||||
public MPQDS1 MapData { get; private set; }
|
||||
public int Act { get; private set; }
|
||||
public string MapName { get; set; }
|
||||
public string MapName { get; private set; }
|
||||
public Palette CurrentPalette => paletteProvider.PaletteTable[$"ACT{Act}"];
|
||||
|
||||
public GameState(ISceneManager sceneManager, IResourceManager resourceManager, IPaletteProvider paletteProvider)
|
||||
public GameState(
|
||||
ISceneManager sceneManager,
|
||||
IResourceManager resourceManager,
|
||||
IPaletteProvider paletteProvider,
|
||||
Func<IMapEngine> getMapEngine
|
||||
)
|
||||
{
|
||||
this.sceneManager = sceneManager;
|
||||
this.resourceManager = resourceManager;
|
||||
this.paletteProvider = paletteProvider;
|
||||
this.getMapEngine = getMapEngine;
|
||||
}
|
||||
|
||||
public void Initialize(string characterName, eHero hero)
|
||||
@ -39,8 +45,8 @@ namespace OpenDiablo2.Core.GameState_
|
||||
{
|
||||
MapName = mapName;
|
||||
Act = act;
|
||||
MapDirty = true;
|
||||
MapData = resourceManager.GetMPQDS1(mapName, -1, act);
|
||||
getMapEngine().NotifyMapChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
126
OpenDiablo2.Core/Map Engine/MapEngine.cs
Normal file
126
OpenDiablo2.Core/Map Engine/MapEngine.cs
Normal file
@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using OpenDiablo2.Common;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
|
||||
namespace OpenDiablo2.Core.Map_Engine
|
||||
{
|
||||
public sealed class MapEngine : IMapEngine
|
||||
{
|
||||
private readonly IGameState gameState;
|
||||
private readonly IRenderWindow renderWindow;
|
||||
private readonly IResourceManager resourceManager;
|
||||
|
||||
private PointF cameraLocation = new PointF();
|
||||
public PointF CameraLocation
|
||||
{
|
||||
get => cameraLocation;
|
||||
set
|
||||
{
|
||||
if (cameraLocation == value)
|
||||
return;
|
||||
|
||||
cameraLocation = value;
|
||||
/*
|
||||
cellOffsetX = CameraLocation.X / cellSizeX;
|
||||
cellOffsetY = CameraLocation.Y / cellSizeY;
|
||||
pixelOffsetX = CameraLocation.X % cellSizeX;
|
||||
pixelOffsetY = CameraLocation.Y % cellSizeY;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
private ISprite loadingSprite;
|
||||
private ISprite[] tempMapCell;
|
||||
|
||||
private int cellOffsetX, cellOffsetY, pixelOffsetX, pixelOffsetY;
|
||||
|
||||
private const int
|
||||
cellSizeX = 160,
|
||||
cellSizeY = 80,
|
||||
renderCellsX = (800 / cellSizeX) + 1,
|
||||
renderCellsY = (600 / cellSizeY) + 1;
|
||||
|
||||
public MapEngine(
|
||||
IGameState gameState,
|
||||
IRenderWindow renderWindow,
|
||||
IResourceManager resourceManager
|
||||
)
|
||||
{
|
||||
this.gameState = gameState;
|
||||
this.renderWindow = renderWindow;
|
||||
this.resourceManager = resourceManager;
|
||||
|
||||
loadingSprite = renderWindow.LoadSprite(ResourcePaths.LoadingScreen, Palettes.Loading, new Point(300, 400));
|
||||
}
|
||||
|
||||
public void NotifyMapChanged()
|
||||
{
|
||||
PurgeAllMapData();
|
||||
LoadNewMapData();
|
||||
}
|
||||
|
||||
private void LoadNewMapData()
|
||||
{
|
||||
var cellsToLoad = gameState.MapData.Width * gameState.MapData.Height;
|
||||
tempMapCell = new ISprite[cellsToLoad];
|
||||
|
||||
for (var cell = 0; cell < cellsToLoad; cell++)
|
||||
{
|
||||
renderWindow.Clear();
|
||||
loadingSprite.Frame = (int)(loadingSprite.TotalFrames * ((float)cell / (float)cellsToLoad));
|
||||
renderWindow.Draw(loadingSprite);
|
||||
renderWindow.Sync();
|
||||
|
||||
tempMapCell[cell] = renderWindow.GenerateMapCell(
|
||||
gameState.MapData,
|
||||
cell % gameState.MapData.Width,
|
||||
cell / gameState.MapData.Width,
|
||||
Common.Enums.eRenderCellType.Floor,
|
||||
gameState.CurrentPalette
|
||||
);
|
||||
}
|
||||
|
||||
//CameraLocation = new Point(((gameState.MapData.Width * cellSizeX) / 2) - 400, ((gameState.MapData.Height * cellSizeY) / 2) - 300);
|
||||
}
|
||||
|
||||
public void Render()
|
||||
{
|
||||
var cOffX = (int)((cameraLocation.X - cameraLocation.Y) * (cellSizeX / 2));
|
||||
var cOffY = (int)((cameraLocation.X + cameraLocation.Y) * (cellSizeY / 2));
|
||||
|
||||
for (int y = 0; y < gameState.MapData.Width; y++)
|
||||
for (int x = 0; x < gameState.MapData.Height; x++)
|
||||
{
|
||||
RenderFloorCell(
|
||||
(x + cellOffsetX),
|
||||
(y + cellOffsetY),
|
||||
((x - y) * 80) - cOffX,
|
||||
((x + y) * 40) - cOffY
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public void RenderFloorCell(int x, int y, int xp, int yp)
|
||||
{
|
||||
if (x < 0 || y < 0 || x >= gameState.MapData.Width || y >= gameState.MapData.Height)
|
||||
return;
|
||||
|
||||
renderWindow.Draw(tempMapCell[x + (y * gameState.MapData.Width)], new Point(xp, yp));
|
||||
}
|
||||
|
||||
public void Update(long ms)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void PurgeAllMapData()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -76,6 +76,7 @@
|
||||
<Compile Include="EngineDataManager.cs" />
|
||||
<Compile Include="GameEngine.cs" />
|
||||
<Compile Include="GameState\GameState.cs" />
|
||||
<Compile Include="Map Engine\MapEngine.cs" />
|
||||
<Compile Include="MPQProvider.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ResourceManager.cs" />
|
||||
|
@ -82,6 +82,7 @@ namespace OpenDiablo2.SDL2_
|
||||
FrameSize = new Size(Pow2((int)source.Frames.Max(x => x.Width)), Pow2((int)source.Frames.Max(x => x.Height)));
|
||||
}
|
||||
|
||||
|
||||
public unsafe SDL2Sprite(IntPtr renderer, Palette palette, MPQDS1 mapData, int x, int y, eRenderCellType cellType)
|
||||
{
|
||||
this.renderer = renderer;
|
||||
@ -136,16 +137,11 @@ namespace OpenDiablo2.SDL2_
|
||||
|
||||
foreach(var block in tile.Blocks)
|
||||
{
|
||||
var px = block.PositionX;
|
||||
var py = block.PositionY;
|
||||
|
||||
//var px = 0;
|
||||
//var py = 0;
|
||||
for (int yy = 0; yy < 32; yy++)
|
||||
{
|
||||
for (int xx = 0; xx < 32; xx++)
|
||||
{
|
||||
var index = px + xx + ((py + yy) * (pitch / 4));
|
||||
var index = block.PositionX + xx + ((block.PositionY + yy) * (pitch / 4));
|
||||
if (index > (FrameSize.Width * FrameSize.Height))
|
||||
continue;
|
||||
if (index < 0)
|
||||
@ -162,7 +158,7 @@ namespace OpenDiablo2.SDL2_
|
||||
SDL.SDL_UnlockTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal Point GetRenderPoint()
|
||||
{
|
||||
return source == null
|
||||
|
@ -8,7 +8,6 @@ using OpenDiablo2.Common;
|
||||
using OpenDiablo2.Common.Attributes;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Core.GameState_;
|
||||
|
||||
namespace OpenDiablo2.Scenes
|
||||
{
|
||||
@ -17,17 +16,27 @@ namespace OpenDiablo2.Scenes
|
||||
{
|
||||
private readonly IRenderWindow renderWindow;
|
||||
private readonly IResourceManager resourceManager;
|
||||
private GameState gameState;
|
||||
private readonly IMapEngine mapEngine;
|
||||
private readonly IGameState gameState;
|
||||
private readonly IKeyboardInfoProvider keyboardInfoProvider;
|
||||
|
||||
private ISprite[] testSprite;
|
||||
//private ISprite[] testSprite;
|
||||
|
||||
private ISprite panelSprite, healthManaSprite, gameGlobeOverlapSprite;
|
||||
|
||||
public Game(IRenderWindow renderWindow, IResourceManager resourceManager, GameState gameState)
|
||||
public Game(
|
||||
IRenderWindow renderWindow,
|
||||
IResourceManager resourceManager,
|
||||
IMapEngine mapEngine,
|
||||
IGameState gameState,
|
||||
IKeyboardInfoProvider keyboardInfoProvider
|
||||
)
|
||||
{
|
||||
this.renderWindow = renderWindow;
|
||||
this.resourceManager = resourceManager;
|
||||
this.mapEngine = mapEngine;
|
||||
this.gameState = gameState;
|
||||
this.keyboardInfoProvider = keyboardInfoProvider;
|
||||
|
||||
panelSprite = renderWindow.LoadSprite(ResourcePaths.GamePanels, Palettes.Act1);
|
||||
healthManaSprite = renderWindow.LoadSprite(ResourcePaths.HealthMana, Palettes.Act1);
|
||||
@ -36,12 +45,14 @@ namespace OpenDiablo2.Scenes
|
||||
|
||||
public void Render()
|
||||
{
|
||||
/*
|
||||
if (gameState.MapDirty)
|
||||
RedrawMap();
|
||||
|
||||
for (int i = 0; i < gameState.MapData.Width * gameState.MapData.Height; i++)
|
||||
renderWindow.Draw(testSprite[i]);
|
||||
|
||||
*/
|
||||
mapEngine.Render();
|
||||
DrawPanel();
|
||||
|
||||
}
|
||||
@ -68,14 +79,45 @@ namespace OpenDiablo2.Scenes
|
||||
|
||||
public void Update(long ms)
|
||||
{
|
||||
var seconds = (float)ms / 1000f;
|
||||
var xMod = 0f;
|
||||
var yMod = 0f;
|
||||
|
||||
if (keyboardInfoProvider.KeyIsPressed(80 /*left*/))
|
||||
{
|
||||
xMod = -8f * seconds;
|
||||
yMod = 8f * seconds;
|
||||
}
|
||||
|
||||
if (keyboardInfoProvider.KeyIsPressed(79 /*right*/))
|
||||
{
|
||||
xMod = 8f * seconds;
|
||||
yMod = -8f * seconds;
|
||||
}
|
||||
|
||||
if (keyboardInfoProvider.KeyIsPressed(81 /*down*/))
|
||||
{
|
||||
yMod = 10f * seconds;
|
||||
xMod = 10f * seconds;
|
||||
}
|
||||
|
||||
if (keyboardInfoProvider.KeyIsPressed(82 /*up*/))
|
||||
{
|
||||
yMod = -10f * seconds;
|
||||
xMod = -10f * seconds;
|
||||
}
|
||||
|
||||
if (xMod != 0f || yMod != 0f)
|
||||
mapEngine.CameraLocation = new PointF(mapEngine.CameraLocation.X + xMod, mapEngine.CameraLocation.Y + yMod);
|
||||
|
||||
mapEngine.Update(ms);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
private void RedrawMap()
|
||||
{
|
||||
gameState.MapDirty = false;
|
||||
@ -92,6 +134,6 @@ namespace OpenDiablo2.Scenes
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ using OpenDiablo2.Common;
|
||||
using OpenDiablo2.Common.Attributes;
|
||||
using OpenDiablo2.Common.Enums;
|
||||
using OpenDiablo2.Common.Interfaces;
|
||||
using OpenDiablo2.Core.GameState_;
|
||||
using OpenDiablo2.Core.UI;
|
||||
|
||||
namespace OpenDiablo2.Scenes
|
||||
@ -45,7 +44,7 @@ namespace OpenDiablo2.Scenes
|
||||
private readonly ISceneManager sceneManager;
|
||||
private readonly ITextDictionary textDictionary;
|
||||
private readonly IKeyboardInfoProvider keyboardInfoProvider;
|
||||
private readonly GameState gameState;
|
||||
private readonly IGameState gameState;
|
||||
|
||||
private bool showEntryUi = false;
|
||||
private eHero? selectedHero = null;
|
||||
@ -68,7 +67,7 @@ namespace OpenDiablo2.Scenes
|
||||
Func<TextBox> createTextBox,
|
||||
ITextDictionary textDictionary,
|
||||
IKeyboardInfoProvider keyboardInfoProvider,
|
||||
GameState gameState
|
||||
IGameState gameState
|
||||
)
|
||||
{
|
||||
this.renderWindow = renderWindow;
|
||||
|
Loading…
Reference in New Issue
Block a user