diff --git a/Maps/test.json b/Maps/test.json index 61e6530..f89b813 100644 --- a/Maps/test.json +++ b/Maps/test.json @@ -2,10 +2,22 @@ "infinite":false, "layers":[ { - "data":[1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "data":[10, 14, 14, 14, 2684354570, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2684354573, 14, 14, 14, 1610612749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2684354573, 14, 14, 14, 1610612749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2684354573, 14, 14, 14, 1610612749, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2684354578, 13, 13, 13, 1610612752, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "height":12, "id":1, - "name":"Tile Layer 1", + "name":"Ground", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":24, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":12, + "id":2, + "name":"Wall", "opacity":1, "type":"tilelayer", "visible":true, @@ -13,7 +25,7 @@ "x":0, "y":0 }], - "nextlayerid":2, + "nextlayerid":3, "nextobjectid":1, "orientation":"orthogonal", "renderorder":"left-down", @@ -23,7 +35,7 @@ { "columns":3, "firstgid":1, - "image":"pond.png", + "image":"..\/..\/MonogameTest\/Maps\/pondv2.bmp", "imageheight":97, "imagewidth":97, "margin":0, @@ -32,6 +44,19 @@ "tilecount":9, "tileheight":32, "tilewidth":32 + }, + { + "columns":3, + "firstgid":10, + "image":"..\/..\/Tilemaps\/grass.png", + "imageheight":96, + "imagewidth":96, + "margin":0, + "name":"grass", + "spacing":0, + "tilecount":9, + "tileheight":32, + "tilewidth":32 }], "tilewidth":32, "type":"map", diff --git a/SeeNoEvil/Animation/cat.json b/SeeNoEvil/Animation/cat.json new file mode 100644 index 0000000..b01fe69 --- /dev/null +++ b/SeeNoEvil/Animation/cat.json @@ -0,0 +1,69 @@ +{ + "name": "cat", + "image": "catsandghosts", + "width": 32, + "height": 32, + "animations": [ + { + "id": 1, + "name": "Idle", + "frames": [ + { + "id": 1, + "x": 0, + "y": 32, + "timer": 0 + } + ] + }, + { + "id": 2, + "name": "Walk X", + "frames": [ + { + "id": 1, + "x": 64, + "y": 32, + "timer": 3 + }, + { + "id": 2, + "x": 32, + "y": 32, + "timer": 3 + }, + { + "id": 3, + "x": 0, + "y": 32, + "timer": 3 + } + ] + }, + { + "id": 3, + "name": "Walk Y", + "frames": [ + { + "id": 1, + "x": 32, + "y": 64, + "timer": 3 + }, + { + "id": 2, + "x": 64, + "y": 64, + "timer": 3 + } + + ] + }, + { + "id": 4, + "name": "Scared", + "frames": [ + ] + } + ] +} \ No newline at end of file diff --git a/SeeNoEvil/Character/AnimationController/AnimationController.cs b/SeeNoEvil/Character/AnimationController/AnimationController.cs new file mode 100644 index 0000000..6f2df63 --- /dev/null +++ b/SeeNoEvil/Character/AnimationController/AnimationController.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using System.Linq; + +namespace SeeNoEvil.Character { + public class AnimationController { + public string Name {get; private set;} + public string Image {get; private set;} + public int Width {get; private set;} + public int Height {get; private set;} + public Dictionary Animations {get; private set;} + private Animation CurrentAnimation; + public Frame CurrentFrame => + CurrentAnimation.GetFrame(); + + public AnimationController(AnimationSetModel model) { + Name = model.Name; + Image = model.Image; + Width = model.Width; + Height = model.Height; + Animations = model.Animations.Aggregate(new Dictionary(), + (animations, animation) => { + animations.Add(animation.Id, new Animation(animation)); + return animations; + }); + ChangeAnimation(1); + } + + public void ChangeAnimation(int animationId) { + if(Animations.TryGetValue(animationId, out CurrentAnimation)) + CurrentAnimation.Reset(); + } + } + + public class Animation { + public int Id {get; set;} + public string Name {get; set;} + public FrameCollection Frames {get; set;} + private int TotalFrames; + private Frame CurrentFrame; + private int CurrentFrameId; + + public Animation(AnimationModel model) { + Id = model.Id; + Name = model.Name; + Frames = new FrameCollection(model.Frames); + TotalFrames = model.Frames.Count(); + } + + public void Reset() { + CurrentFrameId = 1; + CurrentFrame = Frames[CurrentFrameId]; + } + + // TODO Is this super fuckin ugly? Seems like it + public Frame GetFrame() { + Frame result = CurrentFrame; + if(CurrentFrame.Timer == 1) { + CurrentFrameId = CurrentFrameId == TotalFrames ? 1 : CurrentFrameId + 1; + CurrentFrame = Frames[CurrentFrameId]; + } else if(CurrentFrame.Timer > 1) CurrentFrame.Timer--; + return result; + } + } + + public class FrameCollection { + private IEnumerable Frames; + + public Frame this[int i] { + get { + return Frames.Where(item => item.Id == i).First(); + } + } + + public FrameCollection(IEnumerable frames) { + Frames = frames; + } + } +} \ No newline at end of file diff --git a/SeeNoEvil/Character/AnimationController/AnimationModels.cs b/SeeNoEvil/Character/AnimationController/AnimationModels.cs new file mode 100644 index 0000000..9148252 --- /dev/null +++ b/SeeNoEvil/Character/AnimationController/AnimationModels.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; + +namespace SeeNoEvil.Character { + public struct AnimationSetModel { + public string Name {get; set;} + public string Image {get; set;} + public int Width {get; set;} + public int Height {get; set;} + public IEnumerable Animations {get; set;} + } + + public struct AnimationModel { + public int Id {get; set;} + public string Name {get; set;} + public IEnumerable Frames{get; set;} + } + + public struct Frame { + public int Id {get; set;} + public int X {get; set;} + public int Y {get; set;} + public int Timer {get; set;} + } +} \ No newline at end of file diff --git a/SeeNoEvil/Character/AnimationController/AnimationParser.cs b/SeeNoEvil/Character/AnimationController/AnimationParser.cs new file mode 100644 index 0000000..4b73030 --- /dev/null +++ b/SeeNoEvil/Character/AnimationController/AnimationParser.cs @@ -0,0 +1,15 @@ +using System.IO; +using System.Text.Json; + +namespace SeeNoEvil.Character { + public static class AnimationParser { + public static AnimationSetModel ReadAnimationJson(string fileName) { + StreamReader streamReader = File.OpenText(fileName); + string text = streamReader.ReadToEnd(); + var options = new JsonSerializerOptions { + PropertyNameCaseInsensitive = true, + }; + return JsonSerializer.Deserialize(text, options); + } + } +} \ No newline at end of file diff --git a/SeeNoEvil/Character/Cat.cs b/SeeNoEvil/Character/Cat.cs new file mode 100644 index 0000000..662801d --- /dev/null +++ b/SeeNoEvil/Character/Cat.cs @@ -0,0 +1,39 @@ +using Microsoft.Xna.Framework; + +namespace SeeNoEvil.Character { + public enum Direction { + Up, + Down, + Left, + Right + } + public class Cat : Character { + private Direction Facing; + public Cat(Vector2 position, Direction facing) : base(position) { + AnimationController = new AnimationController(AnimationParser.ReadAnimationJson("SeeNoEvil/Animation/cat.json")); + Width = AnimationController.Width; + Height = AnimationController.Height; + Facing = facing; + } + + public void Move(Direction direction) { + int x = 0, y = 0; + switch(direction) { + case Direction.Up: + y = -1; + break; + case Direction.Down: + y = 1; + break; + case Direction.Left: + x = -1; + break; + case Direction.Right: + x = 1; + break; + } + Destination = Vector2.Add(Position, new Vector2(Width*x, Height*y)); + Velocity = new Vector2(x, y); + } + } +} \ No newline at end of file diff --git a/SeeNoEvil/Character/Character.cs b/SeeNoEvil/Character/Character.cs new file mode 100644 index 0000000..91e06a0 --- /dev/null +++ b/SeeNoEvil/Character/Character.cs @@ -0,0 +1,46 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; + +namespace SeeNoEvil.Character { + public class Character { + protected Vector2 Destination {get; set;} + protected Vector2 Velocity {get; set;} + protected Vector2 Position {get; private set;} + protected bool Transform => + !Destination.Equals(Vector2.Zero) && + !Velocity.Equals(Vector2.Zero) && + !Position.Equals(Destination); + + protected AnimationController AnimationController; + protected Texture2D SpriteSheet; + protected int Width; + protected int Height; + + public Character(Vector2 position) { + Position = position; + Destination = Vector2.Zero; + Velocity = Vector2.Zero; + } + + public void Load(ContentManager content) { + SpriteSheet = content.Load(AnimationController.Image); + } + + // TODO Do I want to move every frame? + public void Update() { + if(Transform) + Position = Vector2.Add(Position, Velocity); + } + + public void Draw(SpriteBatch spriteBatch) { + Frame currentFrame = AnimationController.CurrentFrame; + Rectangle srcRectangle = new Rectangle(currentFrame.X, + currentFrame.Y, + AnimationController.Width, + AnimationController.Height); + spriteBatch.Draw(SpriteSheet, Position, srcRectangle, Color.White); + // spriteBatch.Draw(SpriteSheet, Position, Color.White); + } + } +} \ No newline at end of file diff --git a/SeeNoEvil/Level/Level.cs b/SeeNoEvil/Level/Level.cs index 305ea68..e056f2e 100644 --- a/SeeNoEvil/Level/Level.cs +++ b/SeeNoEvil/Level/Level.cs @@ -9,33 +9,33 @@ namespace SeeNoEvil.Level { public class TilemapLevel { private readonly string MapName; private TiledMap Map; - private Dictionary tilesetTextures; + private Dictionary TilesetTextures; public TilemapLevel(string tilemapName) { MapName = tilemapName; } - public void LoadMap(ContentManager Content) { + public void LoadMap(ContentManager content) { Map = new TiledMap(TiledParser.ReadMapJson(MapName)); Map.LoadView(); - tilesetTextures = Map.GetTilesetNames().Aggregate(new Dictionary(), - (content, contentName) => { - content.Add(contentName, Content.Load(contentName)); - return content; + TilesetTextures = Map.GetTilesetNames().Aggregate(new Dictionary(), + (textures, contentName) => { + textures.Add(contentName, content.Load(contentName)); + return textures; }); } - public IEnumerable GetTilesetNames() { + private IEnumerable GetTilesetNames() { return Map.GetTilesetNames(); } - public void Draw(SpriteBatch spritebatch, string layer) { + public void Draw(SpriteBatch spriteBatch, string layer) { List locations; if(Map.View.TryGetValue(layer, out locations)) locations.ForEach(tile => { Texture2D layerTexture; - if(tile.tile.gid > 0 && tilesetTextures.TryGetValue(tile.tile.setName, out layerTexture)) { - spritebatch.Draw(layerTexture, tile.location, tile.tile.srcRectangle, Color.White); + if(tile.tile.gid > 0 && TilesetTextures.TryGetValue(tile.tile.setName, out layerTexture)) { + spriteBatch.Draw(layerTexture, tile.location, tile.tile.srcRectangle, Color.White); } }); } diff --git a/SeeNoEvil/SeeNoEvil.cs b/SeeNoEvil/SeeNoEvil.cs index 16bffc4..bd57f49 100644 --- a/SeeNoEvil/SeeNoEvil.cs +++ b/SeeNoEvil/SeeNoEvil.cs @@ -7,6 +7,7 @@ using Microsoft.Xna.Framework.Input; using SeeNoEvil.Tiled; using SeeNoEvil.Level; +using SeeNoEvil.Character; namespace SeeNoEvil { @@ -16,6 +17,7 @@ namespace SeeNoEvil SpriteBatch spriteBatch; TilemapLevel level; Camera camera; + Cat cat; public SeeNoEvilGame() { @@ -29,6 +31,7 @@ namespace SeeNoEvil // TODO: Add your initialization logic here level = new TilemapLevel("./Maps/MagicLandCsv.json"); // level = new TilemapLevel("./Maps/test.json"); + cat = new Cat(Vector2.Zero, Direction.Right); base.Initialize(); } @@ -37,6 +40,7 @@ namespace SeeNoEvil { spriteBatch = new SpriteBatch(GraphicsDevice); level.LoadMap(Content); + cat.Load(Content); camera = new Camera(GraphicsDevice.Viewport); } @@ -46,28 +50,38 @@ namespace SeeNoEvil Exit(); int xVelocity = 0, yVelocity = 0; + // if(Keyboard.GetState().IsKeyDown(Keys.Down)) + // yVelocity = 1; + // if(Keyboard.GetState().IsKeyDown(Keys.Up)) + // yVelocity = -1; + // if(Keyboard.GetState().IsKeyDown(Keys.Left)) + // xVelocity = -1; + // if(Keyboard.GetState().IsKeyDown(Keys.Right)) + // xVelocity = 1; + camera.Update(Vector2.Zero, new Vector2(xVelocity, yVelocity)); + if(Keyboard.GetState().IsKeyDown(Keys.Down)) - yVelocity = 1; + cat.Move(Direction.Down); if(Keyboard.GetState().IsKeyDown(Keys.Up)) - yVelocity = -1; + cat.Move(Direction.Up); if(Keyboard.GetState().IsKeyDown(Keys.Left)) - xVelocity = -1; + cat.Move(Direction.Left); if(Keyboard.GetState().IsKeyDown(Keys.Right)) - xVelocity = 1; - camera.Update(Vector2.Zero, new Vector2(xVelocity, yVelocity)); + cat.Move(Direction.Right); + cat.Update(); base.Update(gameTime); } protected override void Draw(GameTime gameTime) { - GraphicsDevice.Clear(Color.Black); + GraphicsDevice.Clear(Color.CornflowerBlue); spriteBatch.Begin( transformMatrix: camera.Transform ); - level.Draw(spriteBatch, "background"); - // level.Draw(spriteBatch, "Tile Layer 1"); + // level.Draw(spriteBatch, "background"); + cat.Draw(spriteBatch); spriteBatch.End(); base.Draw(gameTime); diff --git a/SeeNoEvil/Tiled/MapLayer.cs b/SeeNoEvil/Tiled/MapLayer.cs index dcebdb5..1597043 100644 --- a/SeeNoEvil/Tiled/MapLayer.cs +++ b/SeeNoEvil/Tiled/MapLayer.cs @@ -1,3 +1,4 @@ +// TODO Handle flipped tiles! using System.Collections.Generic; using System.Linq; using SeeNoEvil.Level; @@ -35,23 +36,5 @@ namespace SeeNoEvil.Tiled { } else column++; }); } - - // TODO Remember to delete this if it's garbo - // public IEnumerable GetVisibleTiles(Camera viewport, int tileHeight, int tileWidth) { - // if(!BuiltCoordinates) BuildCoordinates(); - - // int startColumn = viewport.x / tileWidth; - // int endColumn = startColumn + (viewport.width / tileWidth); - // int startRow = viewport.y / tileHeight; - // int endRow = startRow + (viewport.height / tileHeight); - - // return DataCoordinates.Where(coord => - // startRow <= coord.y && - // endRow >= coord.y && - // startColumn <= coord.x && - // endColumn >= coord.x - // ); - // } - } } diff --git a/SeeNoEvil/Tiled/TiledModels.cs b/SeeNoEvil/Tiled/TiledModels.cs index ceffe24..dcf223e 100644 --- a/SeeNoEvil/Tiled/TiledModels.cs +++ b/SeeNoEvil/Tiled/TiledModels.cs @@ -1,9 +1,7 @@ using System.Collections.Generic; namespace SeeNoEvil.Tiled { - public class TiledModel { - public TiledModel() {} - + public struct TiledModel { public bool Infinite {get; set;} public IEnumerable Layers {get; set;} public IEnumerable TileSets {get; set;} @@ -13,9 +11,7 @@ namespace SeeNoEvil.Tiled { public int Width {get; set;} } - public class TileSetModel { - public TileSetModel() {} - + public struct TileSetModel { public string Image {get; set;} public string Name {get; set;} public int ImageHeight {get; set;} @@ -29,9 +25,7 @@ namespace SeeNoEvil.Tiled { } - public class MapLayerModel { - public MapLayerModel() { } - + public struct MapLayerModel { public string Name {get; set;} public int Width {get; set;} public int Height {get; set;}