Compare commits
8 Commits
tiles_movi
...
master
Author | SHA1 | Date |
---|---|---|
BraydonKains | 531ffbf531 | 3 years ago |
BraydonKains | ff84687bc9 | 5 years ago |
BraydonKains | d7cc841ad8 | 5 years ago |
BraydonKains | 51f5d963cd | 5 years ago |
BraydonKains | 0229f9f055 | 5 years ago |
BraydonKains | 4be05cff2d | 5 years ago |
BraydonKains | 830891a71e | 5 years ago |
BraydonKains | 15612f660a | 5 years ago |
File diff suppressed because one or more lines are too long
@ -1,19 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
|
||||||
|
|
||||||
<IsPackable>false</IsPackable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="nunit" Version="3.12.0" />
|
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0"/>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="../SeeNoEvil/SeeNoEvil.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
@ -1,18 +0,0 @@
|
|||||||
using NUnit.Framework;
|
|
||||||
|
|
||||||
namespace SeeNoEvil.Tests
|
|
||||||
{
|
|
||||||
public class Tests
|
|
||||||
{
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Test1()
|
|
||||||
{
|
|
||||||
Assert.Pass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,140 @@
|
|||||||
|
{
|
||||||
|
"name": "cat",
|
||||||
|
"image": "Master-no-background-01",
|
||||||
|
"width": 32,
|
||||||
|
"height": 32,
|
||||||
|
"animations": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "Walk Left",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 32,
|
||||||
|
"y": 64,
|
||||||
|
"timer": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"x": 64,
|
||||||
|
"y": 64,
|
||||||
|
"timer": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"x": 0,
|
||||||
|
"y": 64,
|
||||||
|
"timer": 8
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "Walk Right",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 32,
|
||||||
|
"y": 96,
|
||||||
|
"timer": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"x": 64,
|
||||||
|
"y": 96,
|
||||||
|
"timer": 8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"x": 0,
|
||||||
|
"y": 96,
|
||||||
|
"timer": 8
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"name": "Walk Up",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 32,
|
||||||
|
"y": 128,
|
||||||
|
"timer": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"x": 0,
|
||||||
|
"y": 128,
|
||||||
|
"timer": 6
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"name": "Walk Down",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 32,
|
||||||
|
"y": 160,
|
||||||
|
"timer": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"x": 0,
|
||||||
|
"y": 160,
|
||||||
|
"timer": 6
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 5,
|
||||||
|
"name": "Scared Left",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 96,
|
||||||
|
"y": 64,
|
||||||
|
"timer": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 6,
|
||||||
|
"name": "Scared Right",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 96,
|
||||||
|
"y": 96,
|
||||||
|
"timer": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 7,
|
||||||
|
"name": "Scared Up",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 64,
|
||||||
|
"y": 128,
|
||||||
|
"timer": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 8,
|
||||||
|
"name": "Scared Down",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 64,
|
||||||
|
"y": 160,
|
||||||
|
"timer": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"name": "ghost",
|
||||||
|
"image": "Master-no-background-01",
|
||||||
|
"width": 32,
|
||||||
|
"height": 32,
|
||||||
|
"animations": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": "Walk Left",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 0,
|
||||||
|
"y": 32,
|
||||||
|
"timer": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"x": 32,
|
||||||
|
"y": 32,
|
||||||
|
"timer": 6
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": "Walk Right",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 0,
|
||||||
|
"y": 0,
|
||||||
|
"timer": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"x": 32,
|
||||||
|
"y": 0,
|
||||||
|
"timer": 6
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"name": "Walk Up",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 64,
|
||||||
|
"y": 0,
|
||||||
|
"timer": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"x": 64,
|
||||||
|
"y": 32,
|
||||||
|
"timer": 6
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"name": "Walk Down",
|
||||||
|
"frames": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"x": 96,
|
||||||
|
"y": 0,
|
||||||
|
"timer": 6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"x": 96,
|
||||||
|
"y": 32,
|
||||||
|
"timer": 6
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
using System;
|
||||||
|
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 bool Idle;
|
||||||
|
public Dictionary<int, Animation> Animations {get; private set;}
|
||||||
|
private Animation CurrentAnimation;
|
||||||
|
|
||||||
|
public Frame CurrentFrame {
|
||||||
|
get {
|
||||||
|
if(Idle) return CurrentAnimation.CurrentFrame;
|
||||||
|
else return CurrentAnimation.GetFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnimationController(AnimationSetModel model) {
|
||||||
|
Name = model.Name;
|
||||||
|
Image = model.Image;
|
||||||
|
Width = model.Width;
|
||||||
|
Height = model.Height;
|
||||||
|
Animations = model.Animations.Aggregate(new Dictionary<int, Animation>(),
|
||||||
|
(animations, animation) => {
|
||||||
|
animations.Add(animation.Id, new Animation(animation));
|
||||||
|
return animations;
|
||||||
|
});
|
||||||
|
ChangeAnimation(1);
|
||||||
|
Idle = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;}
|
||||||
|
public Frame CurrentFrame;
|
||||||
|
private int TotalFrames;
|
||||||
|
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<Frame> Frames;
|
||||||
|
|
||||||
|
public Frame this[int i] {
|
||||||
|
get {
|
||||||
|
return Frames.Where(item => item.Id == i).First();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public FrameCollection(IEnumerable<Frame> frames) {
|
||||||
|
Frames = frames;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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<AnimationModel> Animations {get; set;}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct AnimationModel {
|
||||||
|
public int Id {get; set;}
|
||||||
|
public string Name {get; set;}
|
||||||
|
public IEnumerable<Frame> 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;}
|
||||||
|
}
|
||||||
|
}
|
@ -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<AnimationSetModel>(text, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace SeeNoEvil.Character {
|
||||||
|
public class Cat : Character {
|
||||||
|
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;
|
||||||
|
ChooseAnimation(Facing);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Move(Direction direction) {
|
||||||
|
if(!Moving) {
|
||||||
|
ChooseAnimation(direction);
|
||||||
|
base.Move(direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector2 GetSight() {
|
||||||
|
Vector2 sight = Position;
|
||||||
|
for(int i = 0; i <= 9; i++) {
|
||||||
|
switch(Facing) {
|
||||||
|
case Direction.Up:
|
||||||
|
sight.Y -= Height;
|
||||||
|
break;
|
||||||
|
case Direction.Down:
|
||||||
|
sight.Y += Height;
|
||||||
|
break;
|
||||||
|
case Direction.Left:
|
||||||
|
sight.X -= Width;
|
||||||
|
break;
|
||||||
|
case Direction.Right:
|
||||||
|
sight.X += Width;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!Field.TryWalk(sight)) break;
|
||||||
|
}
|
||||||
|
return sight;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChooseAnimation(Direction direction) {
|
||||||
|
switch(direction) {
|
||||||
|
case Direction.Up:
|
||||||
|
AnimationController.ChangeAnimation(3);
|
||||||
|
break;
|
||||||
|
case Direction.Down:
|
||||||
|
AnimationController.ChangeAnimation(4);
|
||||||
|
break;
|
||||||
|
case Direction.Left:
|
||||||
|
AnimationController.ChangeAnimation(1);
|
||||||
|
break;
|
||||||
|
case Direction.Right:
|
||||||
|
AnimationController.ChangeAnimation(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Scared() {
|
||||||
|
switch(Facing) {
|
||||||
|
case Direction.Up:
|
||||||
|
AnimationController.ChangeAnimation(7);
|
||||||
|
break;
|
||||||
|
case Direction.Down:
|
||||||
|
AnimationController.ChangeAnimation(8);
|
||||||
|
break;
|
||||||
|
case Direction.Left:
|
||||||
|
AnimationController.ChangeAnimation(5);
|
||||||
|
break;
|
||||||
|
case Direction.Right:
|
||||||
|
AnimationController.ChangeAnimation(6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Content;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using SeeNoEvil.Level;
|
||||||
|
|
||||||
|
namespace SeeNoEvil.Character {
|
||||||
|
public class Character {
|
||||||
|
private Vector2 Destination {get; set;}
|
||||||
|
private Vector2 Velocity {get; set;}
|
||||||
|
public Vector2 Position {get; private set;}
|
||||||
|
private Texture2D SpriteSheet;
|
||||||
|
|
||||||
|
protected Vector2 StartingPosition;
|
||||||
|
protected AnimationController AnimationController;
|
||||||
|
protected int Width;
|
||||||
|
protected int Height;
|
||||||
|
protected PlayField Field;
|
||||||
|
|
||||||
|
public Direction Facing;
|
||||||
|
public bool Moving =>
|
||||||
|
!Destination.Equals(Vector2.Zero) &&
|
||||||
|
!Velocity.Equals(Vector2.Zero) &&
|
||||||
|
!Position.Equals(Destination);
|
||||||
|
|
||||||
|
public Character(Vector2 position) {
|
||||||
|
Position = position;
|
||||||
|
StartingPosition = position;
|
||||||
|
Destination = Vector2.Zero;
|
||||||
|
Velocity = Vector2.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Load(ContentManager content, PlayField playField) {
|
||||||
|
SpriteSheet = content.Load<Texture2D>(AnimationController.Image);
|
||||||
|
Field = playField;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Do I want to move every frame?
|
||||||
|
public void Update() {
|
||||||
|
if(Moving) {
|
||||||
|
Position = Vector2.Add(Position, Velocity);
|
||||||
|
AnimationController.Idle = false;
|
||||||
|
}
|
||||||
|
else AnimationController.Idle = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Move(Direction direction) {
|
||||||
|
if(!Moving) {
|
||||||
|
int velocity = 16;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
var tryPosition = Vector2.Add(Position, new Vector2(Width*x, Height*y));
|
||||||
|
if(Field.TryWalk(tryPosition)) {
|
||||||
|
Destination = Vector2.Add(Position, new Vector2(Width*x, Height*y));
|
||||||
|
Velocity = new Vector2(x*velocity, y*velocity);
|
||||||
|
Facing = direction;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Reset() {
|
||||||
|
Position = StartingPosition;
|
||||||
|
Destination = Vector2.Zero;
|
||||||
|
Velocity = Vector2.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public enum Direction {
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
Right
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Content;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using SeeNoEvil.Level;
|
||||||
|
using SeeNoEvil.Tiled;
|
||||||
|
|
||||||
|
namespace SeeNoEvil.Character {
|
||||||
|
public class GhostController {
|
||||||
|
public List<Ghost> Ghosts {get; set;}
|
||||||
|
public GhostController(IEnumerable<ObjectCoordinate> coordinates) {
|
||||||
|
Ghosts = coordinates.Select(
|
||||||
|
coord => new Ghost(new Vector2(coord.X, coord.Y))
|
||||||
|
).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadAll(ContentManager content, PlayField playField) =>
|
||||||
|
Ghosts.ForEach(ghost => ghost.Load(content, playField));
|
||||||
|
|
||||||
|
public void DrawAll(SpriteBatch spriteBatch) =>
|
||||||
|
Ghosts.ForEach(ghost => ghost.Draw(spriteBatch));
|
||||||
|
|
||||||
|
public void UpdateAll() =>
|
||||||
|
Ghosts.ForEach(ghost => ghost.Update());
|
||||||
|
|
||||||
|
public void MoveGhosts() =>
|
||||||
|
Ghosts.ForEach(ghost => ghost.DecideMove());
|
||||||
|
|
||||||
|
public bool AreGhostsHere(Vector2 playerPosition, Vector2 playerSight, Direction direction) =>
|
||||||
|
Ghosts.Any(ghost => ghost.IsInSight(playerPosition, playerSight, direction));
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Ghost : Character {
|
||||||
|
public Ghost(Vector2 position) : base(position) {
|
||||||
|
AnimationController = new AnimationController(AnimationParser.ReadAnimationJson("SeeNoEvil/Animation/ghost.json"));
|
||||||
|
Width = AnimationController.Width;
|
||||||
|
Height = AnimationController.Height;
|
||||||
|
Facing = Direction.Down;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DecideMove() {
|
||||||
|
Array values = Enum.GetValues(typeof(Direction));
|
||||||
|
Random random = new Random();
|
||||||
|
Direction randomDirection = (Direction)values.GetValue(random.Next(values.Length));
|
||||||
|
switch(randomDirection) {
|
||||||
|
case Direction.Up:
|
||||||
|
AnimationController.ChangeAnimation(3);
|
||||||
|
break;
|
||||||
|
case Direction.Down:
|
||||||
|
AnimationController.ChangeAnimation(4);
|
||||||
|
break;
|
||||||
|
case Direction.Left:
|
||||||
|
AnimationController.ChangeAnimation(1);
|
||||||
|
break;
|
||||||
|
case Direction.Right:
|
||||||
|
AnimationController.ChangeAnimation(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Move(randomDirection);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME it's a bit better now but still
|
||||||
|
public bool IsInSight(Vector2 playerPosition, Vector2 playerSight, Direction direction) {
|
||||||
|
if(direction == Direction.Up)
|
||||||
|
return playerPosition.X == Position.X &&
|
||||||
|
(playerPosition.Y > Position.Y) && (Position.Y > playerSight.Y);
|
||||||
|
else if(direction == Direction.Down)
|
||||||
|
return playerPosition.X == Position.X &&
|
||||||
|
(playerPosition.Y < Position.Y) && (Position.Y < playerSight.Y);
|
||||||
|
else if(direction == Direction.Left)
|
||||||
|
return playerPosition.Y == Position.Y &&
|
||||||
|
(playerPosition.X > Position.X) && (Position.X > playerSight.X);
|
||||||
|
else
|
||||||
|
return playerPosition.Y == Position.Y &&
|
||||||
|
(playerPosition.X < Position.X) && (Position.X < playerSight.X);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,21 +1,27 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
namespace SeeNoEvil.Level {
|
namespace SeeNoEvil.Level {
|
||||||
public struct Camera {
|
public class Camera {
|
||||||
public int width;
|
public Matrix Transform {get; private set;}
|
||||||
public int height;
|
public Viewport Viewport {get; private set;}
|
||||||
public int x;
|
public Vector2 Centre {get; set;}
|
||||||
public int y;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public class Camera {
|
private Vector3 TranslationVector =>
|
||||||
// private Viewport m_dimension;
|
new Vector3(-Centre.X + (Viewport.Width / 2),
|
||||||
|
-Centre.Y + (Viewport.Height / 2),
|
||||||
|
1);
|
||||||
|
|
||||||
// public Camera(int x, int y) {
|
public Camera(Viewport _viewport) {
|
||||||
// m_dimension.x = x;
|
Viewport = _viewport;
|
||||||
// m_dimension.y = x;
|
//TODO This is to experiment
|
||||||
// }
|
Centre = new Vector2(Viewport.Width / 2, Viewport.Height / 2);
|
||||||
|
}
|
||||||
|
|
||||||
// public Viewport GetDimension() {
|
//FIXME Don't need velocity anymore?
|
||||||
// return m_dimension;
|
public void Update(Vector2 position) {
|
||||||
// }
|
Centre = position;
|
||||||
// }
|
Transform = Matrix.CreateTranslation(TranslationVector);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,34 +1,62 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SeeNoEvil.Tiled;
|
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
using Microsoft.Xna.Framework.Content;
|
||||||
|
|
||||||
|
using SeeNoEvil.Tiled;
|
||||||
|
|
||||||
namespace SeeNoEvil.Level {
|
namespace SeeNoEvil.Level {
|
||||||
public class TilemapLevel {
|
public class TilemapLevel {
|
||||||
private readonly string MapName;
|
private readonly string MapName;
|
||||||
private TiledMap Map;
|
private TiledMap Map;
|
||||||
|
private Dictionary<string, Texture2D> TilesetTextures;
|
||||||
|
|
||||||
public TilemapLevel(string tilemapName) {
|
public TilemapLevel(string tilemapName) {
|
||||||
MapName = tilemapName;
|
MapName = tilemapName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadMap() {
|
public void LoadMap(ContentManager content) {
|
||||||
Map = TiledParser.ReadMapJson(MapName);
|
Map = new TiledMap(TiledParser.ReadMapJson(MapName));
|
||||||
}
|
Map.LoadView();
|
||||||
|
Map.LoadObjects();
|
||||||
public IEnumerable<string> GetTilesetNames() {
|
TilesetTextures = Map.GetTilesetNames().Aggregate(new Dictionary<string, Texture2D>(),
|
||||||
return Map.GetTilesetNames();
|
(textures, contentName) => {
|
||||||
}
|
textures.Add(contentName, content.Load<Texture2D>(contentName));
|
||||||
|
return textures;
|
||||||
public void Draw(Camera viewport, SpriteBatch spritebatch, IDictionary<string, Texture2D> this_sucks) {
|
});
|
||||||
IEnumerable<TileLocation> locations = Map.DrawView(viewport);
|
}
|
||||||
locations.ToList().ForEach(tile => {
|
|
||||||
Texture2D this_one;
|
private IEnumerable<string> GetTilesetNames() => Map.GetTilesetNames();
|
||||||
if(tile.tile.gid > 0 && this_sucks.TryGetValue(tile.tile.setName, out this_one)) {
|
|
||||||
spritebatch.Draw(this_one, tile.location, tile.tile.srcRectangle, Color.White);
|
public Vector2 GetPlayerPosition() {
|
||||||
}
|
//FIXME This fuckin sucks
|
||||||
});
|
Map.Objects.TryGetValue("Cat", out List<ObjectCoordinate> catCoords);
|
||||||
}
|
ObjectCoordinate catCoord = catCoords.First();
|
||||||
|
return new Vector2(catCoord.X, catCoord.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayField GetPlayField() {
|
||||||
|
Map.View.TryGetValue("Ground", out List<TileLocation> ground);
|
||||||
|
return new PlayField(ground);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<ObjectCoordinate> GetGhostCoordinates() {
|
||||||
|
// FIXME this fuckin sucks too I think?
|
||||||
|
Map.Objects.TryGetValue("Ghosts", out List<ObjectCoordinate> ghosts);
|
||||||
|
return ghosts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(SpriteBatch spriteBatch, string layer) {
|
||||||
|
List<TileLocation> 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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
using SeeNoEvil.Tiled;
|
||||||
|
|
||||||
|
namespace SeeNoEvil.Level {
|
||||||
|
public class PlayField {
|
||||||
|
private IEnumerable<TileLocation> Tiles {get; set;}
|
||||||
|
|
||||||
|
public PlayField(IEnumerable<TileLocation> tiles) {
|
||||||
|
Tiles = tiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryWalk(Vector2 newLocation) =>
|
||||||
|
Tiles.Any(tile => tile.location.Equals(newLocation) && tile.tile.gid != 0);
|
||||||
|
|
||||||
|
private bool Between(float pos1, float pos2, float bound) =>
|
||||||
|
(bound - pos1) >= (pos2 - pos1);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
// TODO Handle flipped tiles!
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using SeeNoEvil.Level;
|
||||||
|
|
||||||
|
namespace SeeNoEvil.Tiled {
|
||||||
|
public class TileLayer {
|
||||||
|
|
||||||
|
public string Type {get; private set;}
|
||||||
|
public string Name {get; private set;}
|
||||||
|
public readonly List<DataCoordinate> DataCoordinates = new List<DataCoordinate>();
|
||||||
|
|
||||||
|
private int Width;
|
||||||
|
private int Height;
|
||||||
|
private List<uint> Data;
|
||||||
|
|
||||||
|
public TileLayer(MapLayerModel model) {
|
||||||
|
Name = model.Name;
|
||||||
|
Width = model.Width;
|
||||||
|
Height = model.Height;
|
||||||
|
Type = model.Type;
|
||||||
|
if(model.Type == "tilelayer") {
|
||||||
|
Data = model.Data.ToList();
|
||||||
|
BuildCoordinates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildCoordinates() {
|
||||||
|
int row = 0;
|
||||||
|
int column = 0;
|
||||||
|
Data.ForEach(gid => {
|
||||||
|
DataCoordinates.Add(new DataCoordinate(column, row, gid));
|
||||||
|
if(column == Width-1) {
|
||||||
|
row++;
|
||||||
|
column = 0;
|
||||||
|
} else column++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
//TODO Do all these need to be public?
|
||||||
|
namespace SeeNoEvil.Tiled {
|
||||||
|
//TODO Can probably be a struct?
|
||||||
|
public class ObjectLayer {
|
||||||
|
public IEnumerable<ObjectCoordinate> Objects {get; private set;}
|
||||||
|
public string Name {get; private set;}
|
||||||
|
public ObjectLayer(MapLayerModel model) {
|
||||||
|
Name = model.Name;
|
||||||
|
Objects = model.Objects.Select(o => new ObjectCoordinate(o.Id,
|
||||||
|
o.X,
|
||||||
|
o.Y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ObjectCoordinate {
|
||||||
|
public ObjectCoordinate(int id, float x, float y) {
|
||||||
|
X = (int)Math.Round(x / 32)*32;
|
||||||
|
Y = (int)Math.Round(y / 32)*32;
|
||||||
|
Id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int X {get; set;}
|
||||||
|
public int Y {get; set;}
|
||||||
|
public int Id {get; set;}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace SeeNoEvil.Tiled {
|
||||||
|
public class TileSet {
|
||||||
|
private string Image {get; set;}
|
||||||
|
private string Name {get; set;}
|
||||||
|
private int ImageHeight {get; set;}
|
||||||
|
private int ImageWidth {get; set;}
|
||||||
|
private int TileHeight {get; set;}
|
||||||
|
private int TileWidth {get; set;}
|
||||||
|
private int Spacing {get; set;}
|
||||||
|
private int Columns {get; set;}
|
||||||
|
private int FirstGid {get; set;}
|
||||||
|
private int TileCount {get; set;}
|
||||||
|
private Dictionary<uint, Tile> Tiles {get; set;}
|
||||||
|
private bool TilesLoaded {get; set;}
|
||||||
|
|
||||||
|
public TileSet(TileSetModel model) {
|
||||||
|
Image = model.Image;
|
||||||
|
Name = model.Name;
|
||||||
|
ImageHeight = model.ImageHeight;
|
||||||
|
ImageWidth = model.ImageWidth;
|
||||||
|
TileHeight = model.TileHeight;
|
||||||
|
TileWidth = model.TileWidth;
|
||||||
|
Spacing = model.Spacing;
|
||||||
|
Columns = model.Columns;
|
||||||
|
FirstGid = model.FirstGid;
|
||||||
|
TileCount = model.TileCount;
|
||||||
|
Tiles = new Dictionary<uint, Tile>();
|
||||||
|
TilesLoaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ContainsTile(uint gid) =>
|
||||||
|
!(gid < FirstGid || gid > (FirstGid + TileCount - 1));
|
||||||
|
|
||||||
|
public Tile GetTile(uint gid) {
|
||||||
|
if(!TilesLoaded) LoadTiles();
|
||||||
|
Tile result;
|
||||||
|
Tiles.TryGetValue(gid, out result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetContentName() {
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadTiles() {
|
||||||
|
Tiles = new Dictionary<uint, Tile>();
|
||||||
|
int row = 0;
|
||||||
|
int rowPx = 0;
|
||||||
|
int column = 0;
|
||||||
|
int columnPx = 0;
|
||||||
|
for(int i = 0; i < TileCount; i++) {
|
||||||
|
Rectangle rectangle = new Rectangle(
|
||||||
|
columnPx,
|
||||||
|
rowPx,
|
||||||
|
TileWidth,
|
||||||
|
TileHeight
|
||||||
|
);
|
||||||
|
uint gid = (uint)(i + FirstGid);
|
||||||
|
Tiles.Add(gid, new Tile(gid, rectangle, Name));
|
||||||
|
if(column == Columns-1) {
|
||||||
|
row++;
|
||||||
|
rowPx += Spacing + TileHeight;
|
||||||
|
column = 0;
|
||||||
|
columnPx = 0;
|
||||||
|
} else {
|
||||||
|
column++;
|
||||||
|
columnPx += Spacing + TileWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TilesLoaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SeeNoEvil.Tiled {
|
||||||
|
public struct TiledModel {
|
||||||
|
public bool Infinite {get; set;}
|
||||||
|
public IEnumerable<MapLayerModel> Layers {get; set;}
|
||||||
|
public IEnumerable<TileSetModel> TileSets {get; set;}
|
||||||
|
public int TileHeight {get; set;}
|
||||||
|
public int TileWidth {get; set;}
|
||||||
|
public int Height {get; set;}
|
||||||
|
public int Width {get; set;}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct TileSetModel {
|
||||||
|
public string Image {get; set;}
|
||||||
|
public string Name {get; set;}
|
||||||
|
public int ImageHeight {get; set;}
|
||||||
|
public int ImageWidth {get; set;}
|
||||||
|
public int TileHeight {get; set;}
|
||||||
|
public int TileWidth {get; set;}
|
||||||
|
public int Spacing {get; set;}
|
||||||
|
public int Columns {get; set;}
|
||||||
|
public int FirstGid {get; set;}
|
||||||
|
public int TileCount {get; set;}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct MapLayerModel {
|
||||||
|
public string Name {get; set;}
|
||||||
|
public int Width {get; set;}
|
||||||
|
public int Height {get; set;}
|
||||||
|
public IEnumerable<uint> Data {get; set;}
|
||||||
|
public string Type {get; set;}
|
||||||
|
public IEnumerable<TiledObjectModel> Objects {get; set;}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct TiledObjectModel {
|
||||||
|
public int Id {get; set;}
|
||||||
|
public float X {get; set;}
|
||||||
|
public float Y {get; set;}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace SeeNoEvil.Tiled {
|
||||||
|
public struct Tile {
|
||||||
|
public Tile(long _gid, Rectangle _srcRectangle, string _setName) {
|
||||||
|
gid = (uint)_gid;
|
||||||
|
srcRectangle = _srcRectangle;
|
||||||
|
setName = _setName;
|
||||||
|
}
|
||||||
|
public uint gid;
|
||||||
|
public Rectangle srcRectangle;
|
||||||
|
public string setName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct TileLocation {
|
||||||
|
public TileLocation(Tile tile, Vector2 location) {
|
||||||
|
this.tile = tile;
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tile tile;
|
||||||
|
public Vector2 location;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct DataCoordinate {
|
||||||
|
public DataCoordinate(int _x, int _y, uint _gid) {
|
||||||
|
x = _x;
|
||||||
|
y = _y;
|
||||||
|
gid = _gid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int x;
|
||||||
|
public int y;
|
||||||
|
public uint gid;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue