using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework.Input; using VBXSE; namespace LD31 { public static partial class Main { //====ENUMS==== private enum GameState { Playing, AskingForDirection, Quitting, Dead } private enum Season { Summer, Winter } //====CONSTANTS=== //Game private const int TURNS_OF_SUMMER = 400; private const int TURNS_OF_WINTER = 400; private const float GAMEPLAY_MAX_HUNGER = 100f; //World private const int WORLD_SIZE_X = 34; private const int WORLD_SIZE_Y = 22; //====VARIABLES=== //------Public--- //Technical public static Random random = new Random(); public static Game1 game1 = null; //------Private--- //Game private static Creature player = null; private static Object heldItem = null; private static List creatures = new List(); private static float hunger = GAMEPLAY_MAX_HUNGER; private static float hungerReductionPerTurn = 0.0f; private static int turn = 1; private static Season currentSeason = Season.Winter; private static int seasonTurnsLeft = TURNS_OF_SUMMER; private static int year = 0; private static float hungerAccelerationPerYear = 0.5f; //World private static Tile[,] tiles = new Tile[WORLD_SIZE_X, WORLD_SIZE_Y]; private static Object[,] objects = new Object[WORLD_SIZE_X, WORLD_SIZE_Y]; private static Microsoft.Xna.Framework.Color color_summer = new Microsoft.Xna.Framework.Color(0, 0, 0); private static Microsoft.Xna.Framework.Color color_winter = new Microsoft.Xna.Framework.Color(180, 180, 180); //Technical private static KeyboardState keyBoardStateOld = Keyboard.GetState(); private static KeyboardState keyBoardStateNew = Keyboard.GetState(); private static GameState gameState = GameState.Playing; //=====INIT AND UPDATE==== public static void Initialize(Game1 game1) { Main.game1 = game1; game1.Window.Title = "Quiet Life"; //Load scripts LoadScripts(); //Create UI InitializeGraphics(); //Initialize audio InitializeAudio(); //Generate world GenerateWorld(); //Create player player = new Creature(); player.sprite = CreateAnimatedSprite(new string[] { "player1", "player2" }, "player_dead"); //Find fitting position bool fitting = false; while (!fitting) { player.x = random.Next(WORLD_SIZE_X); player.y = random.Next(WORLD_SIZE_Y); if (!CheckAllSolid(player.x, player.y, player)) fitting = true; } player.FixPosition(); //Summer, year 1 ToggleSeason(); //Further init UpdateUI(); } public static void Update(float seconds) { keyBoardStateOld = keyBoardStateNew; keyBoardStateNew = Keyboard.GetState(); bool turnEnded = false; //-------------Playing---------------- if (gameState == GameState.Playing) { //Movement int movementX = 0; int movementY = 0; //Diagonals if (KeyPressed(Keys.NumPad7) || KeyPressed(Keys.D7) || KeyPressed(Keys.Home)) { movementX = -1; movementY = -1; } //NW else if (KeyPressed(Keys.NumPad9) || KeyPressed(Keys.D9) || KeyPressed(Keys.PageUp)) { movementX = 1; movementY = -1; } //NE else if (KeyPressed(Keys.NumPad3) || KeyPressed(Keys.D3) || KeyPressed(Keys.PageDown)) { movementX = 1; movementY = 1; } //SE else if (KeyPressed(Keys.NumPad1) || KeyPressed(Keys.D1) || KeyPressed(Keys.End)) { movementX = -1; movementY = 1; } //SW //Horizontal and vertical else if (KeyPressed(Keys.Left) || KeyPressed(Keys.D4) || KeyPressed(Keys.NumPad4) || KeyPressed(Keys.A)) { movementX = -1; } //W else if (KeyPressed(Keys.Right) || KeyPressed(Keys.D6) || KeyPressed(Keys.NumPad6) || KeyPressed(Keys.D)) { movementX = 1; } //E else if (KeyPressed(Keys.Up) || KeyPressed(Keys.D8) || KeyPressed(Keys.NumPad8) || KeyPressed(Keys.W)) { movementY = -1; } //N else if (KeyPressed(Keys.Down) || KeyPressed(Keys.D2) || KeyPressed(Keys.D5) || KeyPressed(Keys.NumPad2) || KeyPressed(Keys.NumPad5) || KeyPressed(Keys.S)) { movementY = 1; } //S if (movementX != 0 || movementY != 0) { if (MoveCreatureRelative(player, movementX, movementY)) turnEnded = true; } //Pick up/drop if (!turnEnded) { if (KeyPressed(Keys.X) || KeyPressed(Keys.Space)) { if (heldItem != null) { if (DropItem()) turnEnded = true; } if (!turnEnded) { if (PickUpItem()) turnEnded = true; } } } //Use if (!turnEnded) { if (KeyPressed(Keys.Z) || ( /* { */ KeyPressed(Keys.Enter) /* } */ && /* { */ (!(keyBoardStateNew.IsKeyDown(Keys.LeftAlt) || keyBoardStateNew.IsKeyDown(Keys.RightAlt))) /* } */ )) { if (Use()) turnEnded = true; } } if (KeyPressed(Keys.Escape)) { ToggleQuitScreen(true); gameState = GameState.Quitting; } } //-------------------------------------------- else if (gameState == GameState.AskingForDirection) { //Movement int relativeX = 0; int relativeY = 0; //Diagonals if (KeyPressed(Keys.NumPad7) || KeyPressed(Keys.D7) || KeyPressed(Keys.Home)) { relativeX = -1; relativeY = -1; } //NW else if (KeyPressed(Keys.NumPad9) || KeyPressed(Keys.D9) || KeyPressed(Keys.PageUp)) { relativeX = 1; relativeY = -1; } //NE else if (KeyPressed(Keys.NumPad3) || KeyPressed(Keys.D3) || KeyPressed(Keys.PageDown)) { relativeX = 1; relativeY = 1; } //SE else if (KeyPressed(Keys.NumPad1) || KeyPressed(Keys.D1) || KeyPressed(Keys.End)) { relativeX = -1; relativeY = 1; } //SW //Horizontal and vertical else if (KeyPressed(Keys.Left) || KeyPressed(Keys.D4) || KeyPressed(Keys.NumPad4) || KeyPressed(Keys.A)) { relativeX = -1; } //W else if (KeyPressed(Keys.Right) || KeyPressed(Keys.D6) || KeyPressed(Keys.NumPad6) || KeyPressed(Keys.D)) { relativeX = 1; } //E else if (KeyPressed(Keys.Up) || KeyPressed(Keys.D8) || KeyPressed(Keys.NumPad8) || KeyPressed(Keys.W)) { relativeY = -1; } //N else if (KeyPressed(Keys.Down) || KeyPressed(Keys.D2) || KeyPressed(Keys.D5) || KeyPressed(Keys.NumPad2) || KeyPressed(Keys.NumPad5) || KeyPressed(Keys.S)) { relativeY = 1; } //S if (relativeX != 0 || relativeY != 0) { gameState = GameState.Playing; //Set now in case usage changes game state ToggleDirections(false); if (UseDirection(player.x + relativeX, player.y + relativeY)) turnEnded = true; } } //----------------------------------------------- else if (gameState == GameState.Quitting || gameState == GameState.Dead) { if (KeyPressed(Keys.Y)) game1.Exit(); else if (KeyPressed(Keys.N) && gameState == GameState.Quitting) { gameState = GameState.Playing; ToggleQuitScreen(false); } } if (KeyPressed(Keys.F) || ((KeyPressed(Keys.Enter) && (keyBoardStateNew.IsKeyDown(Keys.LeftAlt) || keyBoardStateNew.IsKeyDown(Keys.RightAlt))))) { SpriteEngine.ToggleFullscreen(); } //End turn if (turnEnded) { HandleTurn(); } } //=======PRIVATE METHODS====== //-----Technical-------- private static bool KeyPressed(Keys key) { if (keyBoardStateOld.IsKeyDown(key) && keyBoardStateNew.IsKeyUp(key)) return true; return false; } //UI methods are in Main_Graphics.cs //----Gameplay---- //World generation is in Main_WorldGeneration.cs //Item usage is in Main_UseItem.cs private static bool MoveCreatureRelative(Creature creature, int relativeX, int relativeY) { int targetX = creature.x + relativeX; int targetY = creature.y + relativeY; return MoveCreature(creature, targetX, targetY); } private static bool MoveCreature(Creature creature, int targetX, int targetY) { //Edge check if (targetX < 0 || targetX >= WORLD_SIZE_X || targetY < 0 || targetY >= WORLD_SIZE_Y) { return false; //Can't walk off edge } //Solid check if (!creature.HasProperty("flying")) { if (CheckAllSolid(targetX, targetY, creature)) return false; } else { if (CheckTileAndObjectSolid(targetX, targetY, creature)) return false; } creature.x = targetX; creature.y = targetY; creature.FixPosition(); return true; } private static bool CheckAllSolid(int x, int y, TileObjectOrCreature exception) { if (CheckCreatureSolid(x, y, exception)) return true; if (CheckTileAndObjectSolid(x, y, exception)) return true; return false; } private static bool CheckCreatureSolid(int x, int y, TileObjectOrCreature exception) { //Other creature check for (int ii = 0; ii < creatures.Count; ii++) { Creature other = creatures[ii]; //Don't collide with self if (other != exception) { if (other.x == x && other.y == y) return true; } } //Player check if (player != null) { if (x == player.x && y == player.y) { if (player != exception) { return true; } } } return false; } private static bool CheckTileAndObjectSolid(int x, int y, TileObjectOrCreature exception) { //Solid object check Object theObject = objects[x, y]; if (theObject != null) { if (theObject.HasProperty("solid")) return true; } //Solid tile check if (tiles[x, y].HasProperty("solid")) return true; return false; } //Returns true if item is picked up private static bool PickUpItem(bool fake = false) { Object originalItem = null; if (heldItem != null) { originalItem = heldItem; } Object theObject = objects[player.x, player.y]; if (theObject == null) return false; //No item to pick up if (theObject.HasProperty("cantpickup")) return false; //Can't pick up object //Pick up! if (!fake) { PlaySound("pickup"); heldItem = theObject; SpriteEngine.EraseGObject(theObject.sprite); objects[player.x, player.y] = null; if (originalItem != null) { SpawnObject(originalItem.name, player.x, player.y); } } //Success! return true; } //Returns true if item is dropped private static bool DropItem() { int px = player.x; int py = player.y; if (heldItem == null) return false; //Nothing to drop if (objects[px, py] != null) return false; //Already an object at position //Drop item! PlaySound("drop"); objects[px, py] = heldItem; heldItem.sprite = CreateSprite(heldItem.spriteName); SetSpritePosition(heldItem.sprite, px, py); heldItem = null; //Success! return true; } //Returns true if object is spawned private static bool SpawnObject(string name, int x, int y) { if (objects[x, y] != null) return false; //Can't spawn on top of something else Object newObject = new Object(name); objects[x, y] = newObject; SetSpritePosition(newObject.sprite, x, y); return true; } //Returns true if object is destroyed private static bool DestroyObject(int x, int y) { if (objects[x, y] == null) return false; //Can't destroy what isn't there SpriteEngine.EraseGObject(objects[x, y].sprite); objects[x, y] = null; return true; } //Returns true if item is added private static bool CreateHeldItem(string name) { if (heldItem != null) return false; heldItem = new Object(name, false); return true; } //Returns true if item is destroyed private static bool DestroyHeldItem() { heldItem = null; return true; } private static void CreateTile(int x, int y, string tileName) { Tile tile = new Tile(tileName); SetSpritePosition(tile.sprite, x, y); tile.sprite.depth = 10; ChangeTile(x, y, tile); } private static void ChangeTile(int x, int y, Tile newTile) { if (tiles[x, y] != null) { SpriteEngine.EraseGObject(tiles[x, y].sprite); } tiles[x, y] = newTile; } private static void SpawnCreature(string creatureName, int x, int y) { Creature creature = new Creature(creatureName); creature.sprite = Main.CreateAnimatedSprite(creature.spriteNames); creature.x = x; creature.y = y; creature.FixPosition(); creatures.Add(creature); } private static void DeleteCreature(Creature creature) { creatures.Remove(creature); SpriteEngine.EraseGObject(creature.sprite); } private static void AskForDirection() { gameState = GameState.AskingForDirection; ToggleDirections(true); } private static void RestoreHungerBar(int amount) { hunger += amount; if (hunger > GAMEPLAY_MAX_HUNGER) hunger = GAMEPLAY_MAX_HUNGER; } private static void ToggleSeason() { if (currentSeason == Season.Summer) { currentSeason = Season.Winter; seasonTurnsLeft = TURNS_OF_WINTER; game1.backgroundColor = color_winter; } else if (currentSeason == Season.Winter) { currentSeason = Season.Summer; seasonTurnsLeft = TURNS_OF_SUMMER; game1.backgroundColor = color_summer; year++; hungerReductionPerTurn += hungerAccelerationPerYear; } } private static void HandleTurn() { turn++; //Check for update scripts //On creatures for (int i = 0; i < creatures.Count; i++) { Creature creature = creatures[i]; if (creature.updateScript != null) { HandleScript(creature.updateScript, creature, null, creature.x, creature.y); //See Main_UseItem.cs } } //On objects for (int iy = 0; iy < WORLD_SIZE_Y; iy++) { for (int ix = 0; ix < WORLD_SIZE_X; ix++) { Object theObject = objects[ix, iy]; if (theObject != null) { if (theObject.updateScript != null) { HandleScript(theObject.updateScript, theObject, null, ix, iy); //See Main_UseItem.cs } } } } //Including held object if (heldItem != null) { if (heldItem.updateScript != null) { HandleScript(heldItem.updateScript, heldItem, null, player.x, player.y); //See Main_UseItem.cs } } //Become hungry/starve hunger -= hungerReductionPerTurn; if (hunger <= 0) Die(); //Check season/year seasonTurnsLeft--; if (seasonTurnsLeft < 0) { ToggleSeason(); } //Update UI UpdateUI(); } private static void Die() { ToggleGameOver(true); gameState = GameState.Dead; } } }