StrategyRPG/Johnmagotchi/GameContent/Screens/MapScreens/BaseMapScreen.cs

432 lines
16 KiB
C#

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TibzGame.Core.Inputs;
using TibzGame.Core.ScreenManager;
using Johnmagotchi.GameContent.Objects;
using System.Text.Json;
using Johnmagotchi.GameContent.Objects.UI;
using Johnmagotchi.Core.tools;
namespace Johnmagotchi.Screen.BattleMapScreens
{
public abstract class BaseMapScreen : GameScreen
{
SpriteBatch SpriteBatch;
protected BattleMap CurrentMap;
public MapCursor MapCursor;
public UnitDisplay UnitDisplay;
protected int cursorIndexX;
protected int cursorIndexY;
protected int scrollOffsetX;
protected int scrollOffsetY;
public int CursorQuadrant;
private readonly ulong CURSOR_HOLD_FRAMES = 25;
private readonly int SCROLL_BOOST_TIME_FRAMES = 60;
private readonly int CURSOR_SCROLL_NEXT_INC_FRAMES= 5;
private readonly int SCROLL_TILES_FROM_EDGE_X = 3;
private readonly int SCROLL_TILES_FROM_EDGE_Y = 2;
private int scrollTimer ; // frames until click to next
private int scrollTotalDuration;
protected string tempSave;
public bool ScreenScrollLock = false;
private bool IsNewMap = true;
public abstract void ChildInit();
public abstract void ChildUpdate();
public abstract void ChildDraw();
public BaseMapScreen(){
this.CurrentMap = new BattleMap(24,20);
this.MapCursor = new MapCursor();
this.UnitDisplay = new UnitDisplay();
this.isDrawPriority = true;
this.isUpdatePriority = true;
saveCurrentMap();
}
public BaseMapScreen(BattleMap existingMap){
this.CurrentMap = existingMap.GetClone();
this.MapCursor = new MapCursor();
this.UnitDisplay = new UnitDisplay();
this.isDrawPriority = true;
this.isUpdatePriority = true;
this.IsNewMap = false;
}
public override void Init()
{
scrollTimer =0;
scrollTotalDuration =0;
cursorIndexX = 2;
cursorIndexY = 2;
scrollOffsetX=0;
scrollOffsetY=0;
SpriteBatch = new SpriteBatch(screenManager.GraphicsDevice);
this.MapCursor.Init(screenManager);
this.UnitDisplay.Init(screenManager);
if (this.IsNewMap)
{
this.CurrentMap.Init(screenManager);
}
else
{
this.CurrentMap.InitFromReload(ScreenManager);
}
ChildInit();
}
public override void Destroy()
{
throw new NotImplementedException();
}
public override void Draw()
{
// bool stopXScroll = false;
//bool stopYScroll = false;
if ((this.CurrentMap.width * MapTile.TILE_WIDTH_PX) < this.ScreenManager.GetScaledPixelScreenWidth()) { // center width
scrollOffsetX = (this.ScreenManager.GetScaledPixelScreenWidth() - (this.CurrentMap.width * MapTile.TILE_WIDTH_PX))/2;
// stopXScroll = true;
}
if ((this.CurrentMap.height * MapTile.TILE_HEIGHT_PX) < this.ScreenManager.GetScaledPixelScreenHeight()){ // center height
scrollOffsetY = (this.ScreenManager.GetScaledPixelScreenHeight() - (this.CurrentMap.height * MapTile.TILE_HEIGHT_PX))/2;
// stopYScroll = true;
}
this.CurrentMap.DrawMap(scrollOffsetX, scrollOffsetY);// should draw background
//draw on top of background :
//cursor
this.MapCursor.Draw( (MapTile.TILE_WIDTH_PX *cursorIndexX) + scrollOffsetX , (MapTile.TILE_HEIGHT_PX * cursorIndexY) + scrollOffsetY);
// units
this.CurrentMap.DrawUnits(scrollOffsetX, scrollOffsetY);// should draw background
// Call child draw classes
ChildDraw();
// anthing that has priorty top layer should go here
// ui overlay
UnitDisplay.Draw(CursorQuadrant);
}
public override void Update()
{
// Updates
UpdateCursorQuadrant(); // This doesnt need to be called every frame, but its easy. so.
/// Keyboard / Controller controls
if (! screenManager.inputs.isMouseMode)
{
if (screenManager.inputs.mouseInput.leftClick.isJustReleased) {
TibzLog.Debug(" Changed To Mouse Controls");
screenManager.inputs.isMouseMode = true;
}
//Check Button Presses
if (screenManager.inputs.editorInputs.navLeft.isJustPressed)
{
TickCursorLeft();
}
if (screenManager.inputs.editorInputs.navRight.isJustPressed)
{
TickCursorRight();
}
if (screenManager.inputs.editorInputs.navUp.isJustPressed)
{
TickCursorUp();
}
if (screenManager.inputs.editorInputs.navDown.isJustPressed)
{
TickCursorDown();
}
if (screenManager.inputs.editorInputs.saveButton.isJustPressed)
{
saveCurrentMap();
}
if (screenManager.inputs.editorInputs.loadButton.isJustPressed)
{
loadCurrentMap();
}
//Button Holds
if (screenManager.inputs.editorInputs.navLeft.heldTime > CURSOR_HOLD_FRAMES)
{
IncrementScrollTimers();
if (scrollTimer > CURSOR_SCROLL_NEXT_INC_FRAMES)
{
scrollTimer = 0;
TickCursorLeft();
}
}
if (screenManager.inputs.editorInputs.navRight.heldTime > CURSOR_HOLD_FRAMES)
{
IncrementScrollTimers();
if (scrollTimer > CURSOR_SCROLL_NEXT_INC_FRAMES)
{
scrollTimer = 0;
TickCursorRight();
}
}
if (screenManager.inputs.editorInputs.navUp.heldTime > CURSOR_HOLD_FRAMES)
{
IncrementScrollTimers();
if (scrollTimer > CURSOR_SCROLL_NEXT_INC_FRAMES)
{
scrollTimer = 0;
TickCursorUp();
}
}
if (screenManager.inputs.editorInputs.navDown.heldTime > CURSOR_HOLD_FRAMES)
{
IncrementScrollTimers();
if (scrollTimer > CURSOR_SCROLL_NEXT_INC_FRAMES)
{
scrollTimer = 0;
TickCursorDown();
}
}
if (ScreenManager.inputs.editorInputs.navLeft.isJustReleased || // reset scroll timers on release
ScreenManager.inputs.editorInputs.navRight.isJustReleased ||
ScreenManager.inputs.editorInputs.navUp.isJustReleased ||
ScreenManager.inputs.editorInputs.navDown.isJustReleased)
{
scrollTimer = 0;
scrollTotalDuration = 0;
}
}
else {
UpdateCursorMouse();
//if (screenManager.inputs.mouseInput.leftClick.isJustPressed)
//{
// screenManager.inputs.editorInputs.confirm.isJustPressed = true;
//}
//if (screenManager.inputs.mouseInput.rightClick.isJustPressed)
//{
// screenManager.inputs.editorInputs.cancel.isJustPressed = true;
//}
}
// update battle map
CurrentMap.Update();
// update unit display
UnitDisplay.Update( CurrentMap.getUnitAtLocation(cursorIndexX, cursorIndexY));
// End Update, call child
ChildUpdate();
}
protected virtual void TickCursorLeft()
{
if (cursorIndexX > 0) cursorIndexX --;
else cursorIndexX = 0;
// adjust screen after mouse movement
tickLeftScroll();
}
protected virtual void TickCursorRight()
{
if (cursorIndexX < CurrentMap.width -1) cursorIndexX ++; // zero indexed so -1
else cursorIndexX = CurrentMap.width -1;
// adjust screen after mouse movement
tickRightScroll();
}
protected virtual void TickCursorUp()
{
if (cursorIndexY > 0) cursorIndexY --;
else cursorIndexY = 0;
// adjust screen after mouse movement
tickUpScroll();
}
protected virtual void TickCursorDown()
{
if (cursorIndexY < CurrentMap.height -1) cursorIndexY ++; // zero indexed so -1
else cursorIndexY = CurrentMap.height -1;
// adjust screen after mouse movement
tickDownScroll();
}
private void IncrementScrollTimers()
{
scrollTimer++;
scrollTotalDuration++;
if (scrollTotalDuration > SCROLL_BOOST_TIME_FRAMES){
scrollTimer ++; // double the speed of scroll if held for over 70 frames
}
}
protected void tickLeftScroll(){
if (ScreenScrollLock){ return; }
int currentOffsetTilesX = - scrollOffsetX / MapTile.TILE_WIDTH_PX; // since the offset scrolling left is negative we need to invert this sign
int currentOffsetTilesY = scrollOffsetY / MapTile.TILE_HEIGHT_PX;
int totalWidthTiles = this.screenManager.GetScaledPixelScreenWidth() / MapTile.TILE_WIDTH_PX;
int TilesFromLeftEdge = cursorIndexX - currentOffsetTilesX;
System.Console.WriteLine("Scroll offset px: {0}", scrollOffsetX);
if ( TilesFromLeftEdge < SCROLL_TILES_FROM_EDGE_X)
{
scrollOffsetX += MapTile.TILE_WIDTH_PX; // scroll left
}
if (scrollOffsetX >= 0 ) // scroll limit
{
scrollOffsetX = 0;
}
}
protected void tickRightScroll(){
if (ScreenScrollLock){ return; }
int currentOffsetTilesX = - scrollOffsetX / MapTile.TILE_WIDTH_PX; // invert sign here
int currentOffsetTilesY = scrollOffsetY / MapTile.TILE_HEIGHT_PX;
int totalWidthTiles = this.screenManager.GetScaledPixelScreenWidth() / MapTile.TILE_WIDTH_PX;
int TilesFromLeftEdge = cursorIndexX - currentOffsetTilesX;
System.Console.WriteLine("Scroll offset px: {0}", scrollOffsetX);
System.Console.WriteLine("Scroll offset limit: {0}", -1* (CurrentMap.width * MapTile.TILE_WIDTH_PX - this.screenManager.GetScaledPixelScreenWidth()));
if ( TilesFromLeftEdge >= totalWidthTiles - SCROLL_TILES_FROM_EDGE_X)
{
scrollOffsetX -= MapTile.TILE_WIDTH_PX; // scroll right
}
if (scrollOffsetX <= -1* (CurrentMap.width * MapTile.TILE_WIDTH_PX - this.screenManager.GetScaledPixelScreenWidth()))
{
scrollOffsetX = -1* (CurrentMap.width * MapTile.TILE_WIDTH_PX - this.screenManager.GetScaledPixelScreenWidth());
}
}
protected void tickUpScroll(){
if (ScreenScrollLock){ return; }
int currentOffsetTilesY = - scrollOffsetY / MapTile.TILE_HEIGHT_PX;
int totalHeightTiles = this.screenManager.GetScaledPixelScreenHeight() / MapTile.TILE_HEIGHT_PX;
int tilesFromTop = cursorIndexY - currentOffsetTilesY;
//System.Console.WriteLine("Scroll offset px: {0}", scrollOffsetY);
if ( tilesFromTop < SCROLL_TILES_FROM_EDGE_Y){
scrollOffsetY += MapTile.TILE_HEIGHT_PX; // scroll up
}
if (scrollOffsetY >= 0 )
{
scrollOffsetY = 0;
}
}
protected void tickDownScroll(){
if (ScreenScrollLock){ return; }
int currentOffsetTilesY = - scrollOffsetY / MapTile.TILE_HEIGHT_PX;
int totalHeightTiles = this.screenManager.GetScaledPixelScreenHeight() / MapTile.TILE_HEIGHT_PX;
int tilesFromTop = cursorIndexY - currentOffsetTilesY;
// System.Console.WriteLine("Scroll offset px: {0}", scrollOffsetY);
if ( tilesFromTop > totalHeightTiles - SCROLL_TILES_FROM_EDGE_Y){
scrollOffsetY -= MapTile.TILE_HEIGHT_PX; // scroll up
}
if (scrollOffsetY <= -1* (CurrentMap.height * MapTile.TILE_HEIGHT_PX - this.screenManager.GetScaledPixelScreenHeight()))
{
scrollOffsetY = -1* (CurrentMap.height * MapTile.TILE_HEIGHT_PX - this.screenManager.GetScaledPixelScreenHeight());
}
}
public string saveCurrentMap(){
System.Console.WriteLine("Saving....");
CurrentMap.SerializeAll();
tempSave = JsonSerializer.Serialize(CurrentMap);
// System.Console.WriteLine("save json: {0}", tempSave);
return tempSave;
}
public void loadCurrentMap(){
if (tempSave.Length > 10){
System.Console.WriteLine("Loading....");
this.CurrentMap = JsonSerializer.Deserialize<BattleMap>(tempSave);
this.CurrentMap.InitFromReload(screenManager);
this.CurrentMap.deserializeMapTiles();
this.CurrentMap.DeserializeUnitData();
}
else{
System.Console.WriteLine("valid save state not found");
}
}
private void UpdateCursorQuadrant() {
if ((MapTile.TILE_HEIGHT_PX * cursorIndexY) + scrollOffsetY < ScreenManager.GetScaledPixelScreenHeight() / 2) // top
{
if ((MapTile.TILE_WIDTH_PX * cursorIndexX) + scrollOffsetX > ScreenManager.GetScaledPixelScreenWidth() / 2) // right
{
CursorQuadrant = 1;
}
else // left
{
CursorQuadrant = 2;
}
}
else //bottom
{
if ((MapTile.TILE_WIDTH_PX * cursorIndexX) + scrollOffsetX < ScreenManager.GetScaledPixelScreenWidth() / 2) // left
{
CursorQuadrant = 3;
}
else // right
{
CursorQuadrant = 4;
}
}
}
private void UpdateCursorMouse()
{
int x = screenManager.inputs.mouseInput.x;
int y = screenManager.inputs.mouseInput.y;
//TibzLog.Debug("Mouse Pos: x - "+ x + " , y - " + y );
int xSelectedTileIndex = x * ScreenManager.BASE_ZOOM_LEVEL / ( MapTile.TILE_WIDTH_PX * 2 );
int ySelectedTileIndex = y * ScreenManager.BASE_ZOOM_LEVEL / (MapTile.TILE_HEIGHT_PX * 2 );
cursorIndexX = xSelectedTileIndex;
cursorIndexY = ySelectedTileIndex;
}
}
}