1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-20 22:25:24 +00:00

Added initial pieces of the map engine.

This commit is contained in:
Tim Sarbin 2018-11-24 22:34:16 -05:00
parent d3a718d8f6
commit 3a0cbe4b8e
10 changed files with 236 additions and 24 deletions

View 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);
}
}

View 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();
}
}

View File

@ -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" />

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View 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()
{
}
}
}

View File

@ -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" />

View File

@ -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

View File

@ -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
}
}
}
}*/
}
}

View File

@ -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;