Player now takes damage from spikes.
GitOrigin-RevId: e9096316218f2590aac74ce1055a0829f71bdff8
This commit is contained in:
parent
a431ad094b
commit
f4581ecaf8
@ -83,10 +83,15 @@ namespace SemiColinGames {
|
|||||||
public readonly struct AABB {
|
public readonly struct AABB {
|
||||||
public readonly Vector2 Position; // centroid
|
public readonly Vector2 Position; // centroid
|
||||||
public readonly Vector2 HalfSize;
|
public readonly Vector2 HalfSize;
|
||||||
|
public readonly Terrain Terrain;
|
||||||
|
|
||||||
public AABB(Vector2 position, Vector2 halfSize) {
|
public AABB(Vector2 position, Vector2 halfSize) : this(position, halfSize, Terrain.Empty) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AABB(Vector2 position, Vector2 halfSize, Terrain terrain) {
|
||||||
Position = position;
|
Position = position;
|
||||||
HalfSize = halfSize;
|
HalfSize = halfSize;
|
||||||
|
Terrain = terrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public float Top {
|
public float Top {
|
||||||
|
@ -34,12 +34,13 @@ namespace SemiColinGames {
|
|||||||
private const int swordSwingMax = 6;
|
private const int swordSwingMax = 6;
|
||||||
private float ySpeed = 0;
|
private float ySpeed = 0;
|
||||||
private double jumpTime = 0;
|
private double jumpTime = 0;
|
||||||
|
private float invincibilityTime = 0;
|
||||||
|
|
||||||
public Player() {
|
public Player() {
|
||||||
Health = MaxHealth;
|
Health = MaxHealth;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int MaxHealth { get; private set; } = 5;
|
public int MaxHealth { get; private set; } = 3;
|
||||||
|
|
||||||
public int Health { get; private set; }
|
public int Health { get; private set; }
|
||||||
|
|
||||||
@ -56,6 +57,8 @@ namespace SemiColinGames {
|
|||||||
return BoxOffset(position, 0);
|
return BoxOffset(position, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invincibilityTime -= modelTime;
|
||||||
|
|
||||||
Vector2 movement = HandleInput(modelTime, input);
|
Vector2 movement = HandleInput(modelTime, input);
|
||||||
|
|
||||||
// Broad test: remove all collision targets nowhere near the player.
|
// Broad test: remove all collision targets nowhere near the player.
|
||||||
@ -71,11 +74,12 @@ namespace SemiColinGames {
|
|||||||
new Vector2(halfSize.X + Math.Abs(movement.X) + 1, halfSize.Y + Math.Abs(movement.Y) + 1));
|
new Vector2(halfSize.X + Math.Abs(movement.X) + 1, halfSize.Y + Math.Abs(movement.Y) + 1));
|
||||||
foreach (var box in collisionTargets) {
|
foreach (var box in collisionTargets) {
|
||||||
if (box.Intersect(largeBox) != null) {
|
if (box.Intersect(largeBox) != null) {
|
||||||
Debug.AddRect(box, Color.Green);
|
// Debug.AddRect(box, Color.Green);
|
||||||
candidates.Add(box);
|
candidates.Add(box);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool harmedByCollision = false;
|
||||||
Point[] movePoints = Line.Rasterize(0, 0, (int) movement.X, (int) movement.Y);
|
Point[] movePoints = Line.Rasterize(0, 0, (int) movement.X, (int) movement.Y);
|
||||||
for (int i = 1; i < movePoints.Length; i++) {
|
for (int i = 1; i < movePoints.Length; i++) {
|
||||||
int dx = movePoints[i].X - movePoints[i - 1].X;
|
int dx = movePoints[i].X - movePoints[i - 1].X;
|
||||||
@ -86,8 +90,12 @@ namespace SemiColinGames {
|
|||||||
bool reject = false;
|
bool reject = false;
|
||||||
foreach (var box in candidates) {
|
foreach (var box in candidates) {
|
||||||
if (box.Intersect(player) != null) {
|
if (box.Intersect(player) != null) {
|
||||||
|
Debug.AddRect(box, Color.Cyan);
|
||||||
reject = true;
|
reject = true;
|
||||||
break;
|
if (box.Terrain.IsHarmful) {
|
||||||
|
Debug.AddRect(box, Color.Red);
|
||||||
|
harmedByCollision = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!reject) {
|
if (!reject) {
|
||||||
@ -100,8 +108,12 @@ namespace SemiColinGames {
|
|||||||
bool reject = false;
|
bool reject = false;
|
||||||
foreach (var box in candidates) {
|
foreach (var box in candidates) {
|
||||||
if (box.Intersect(player) != null) {
|
if (box.Intersect(player) != null) {
|
||||||
|
Debug.AddRect(box, Color.Cyan);
|
||||||
reject = true;
|
reject = true;
|
||||||
break;
|
if (box.Terrain.IsHarmful) {
|
||||||
|
Debug.AddRect(box, Color.Red);
|
||||||
|
harmedByCollision = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!reject) {
|
if (!reject) {
|
||||||
@ -114,8 +126,12 @@ namespace SemiColinGames {
|
|||||||
AABB groundIntersect = BoxOffset(position, 1);
|
AABB groundIntersect = BoxOffset(position, 1);
|
||||||
foreach (var box in candidates) {
|
foreach (var box in candidates) {
|
||||||
if (groundIntersect.Intersect(box) != null) {
|
if (groundIntersect.Intersect(box) != null) {
|
||||||
|
Debug.AddRect(box, Color.Cyan);
|
||||||
standingOnGround = true;
|
standingOnGround = true;
|
||||||
break;
|
if (box.Terrain.IsHarmful) {
|
||||||
|
Debug.AddRect(box, Color.Red);
|
||||||
|
harmedByCollision = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,6 +149,11 @@ namespace SemiColinGames {
|
|||||||
Debug.AddRect(Box(position), Color.Orange);
|
Debug.AddRect(Box(position), Color.Orange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (harmedByCollision && invincibilityTime <= 0) {
|
||||||
|
Health -= 1;
|
||||||
|
invincibilityTime = 0.6f;
|
||||||
|
}
|
||||||
|
|
||||||
if (movement.X > 0) {
|
if (movement.X > 0) {
|
||||||
Facing = 1;
|
Facing = 1;
|
||||||
} else if (movement.X < 0) {
|
} else if (movement.X < 0) {
|
||||||
@ -242,7 +263,11 @@ namespace SemiColinGames {
|
|||||||
Vector2 spriteCenter = new Vector2(spriteWidth / 2, spriteHeight / 2 + spriteCenterYOffset);
|
Vector2 spriteCenter = new Vector2(spriteWidth / 2, spriteHeight / 2 + spriteCenterYOffset);
|
||||||
SpriteEffects effect = Facing == 1 ?
|
SpriteEffects effect = Facing == 1 ?
|
||||||
SpriteEffects.FlipHorizontally : SpriteEffects.None;
|
SpriteEffects.FlipHorizontally : SpriteEffects.None;
|
||||||
spriteBatch.Draw(Textures.Player.Get, position.ToVector2(), textureSource, Color.White, 0f,
|
Color color = Color.White;
|
||||||
|
if (invincibilityTime > 0 && invincibilityTime % 0.2f > 0.1f) {
|
||||||
|
color = new Color(0.5f, 0.5f, 0.5f, 0.5f);
|
||||||
|
}
|
||||||
|
spriteBatch.Draw(Textures.Player.Get, position.ToVector2(), textureSource, color, 0f,
|
||||||
spriteCenter, Vector2.One, effect, 0f);
|
spriteCenter, Vector2.One, effect, 0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ namespace SemiColinGames {
|
|||||||
// attempt to draw the scene. This is a workaround for the fact that otherwise the first few
|
// attempt to draw the scene. This is a workaround for the fact that otherwise the first few
|
||||||
// frames can be really slow to draw.
|
// frames can be really slow to draw.
|
||||||
int framesToSuppress;
|
int framesToSuppress;
|
||||||
int levelIdx = 0;
|
int levelIdx = -1;
|
||||||
|
|
||||||
Scene scene;
|
Scene scene;
|
||||||
Player player;
|
Player player;
|
||||||
@ -73,10 +73,10 @@ namespace SemiColinGames {
|
|||||||
framesToSuppress = 2;
|
framesToSuppress = 2;
|
||||||
camera = new Camera();
|
camera = new Camera();
|
||||||
player = new Player();
|
player = new Player();
|
||||||
|
levelIdx++;
|
||||||
world = new World(Levels.ALL_LEVELS[levelIdx % Levels.ALL_LEVELS.Length]);
|
world = new World(Levels.ALL_LEVELS[levelIdx % Levels.ALL_LEVELS.Length]);
|
||||||
scene?.Dispose();
|
scene?.Dispose();
|
||||||
scene = new Scene(GraphicsDevice, camera);
|
scene = new Scene(GraphicsDevice, camera);
|
||||||
levelIdx++;
|
|
||||||
|
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
GC.WaitForPendingFinalizers();
|
GC.WaitForPendingFinalizers();
|
||||||
@ -122,6 +122,10 @@ namespace SemiColinGames {
|
|||||||
player.Update(modelTime, input, world.CollisionTargets);
|
player.Update(modelTime, input, world.CollisionTargets);
|
||||||
linesOfSight.Update(player, world.CollisionTargets);
|
linesOfSight.Update(player, world.CollisionTargets);
|
||||||
camera.Update(player.Position, world.Width);
|
camera.Update(player.Position, world.Width);
|
||||||
|
if (player.Health <= 0) {
|
||||||
|
world = new World(Levels.ALL_LEVELS[levelIdx % Levels.ALL_LEVELS.Length]);
|
||||||
|
player = new Player();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Update(gameTime);
|
base.Update(gameTime);
|
||||||
|
@ -5,7 +5,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace SemiColinGames {
|
namespace SemiColinGames {
|
||||||
|
|
||||||
class TextureRef {
|
public class TextureRef {
|
||||||
private static readonly List<TextureRef> allTextures = new List<TextureRef>();
|
private static readonly List<TextureRef> allTextures = new List<TextureRef>();
|
||||||
|
|
||||||
public static void LoadAll(ContentManager content) {
|
public static void LoadAll(ContentManager content) {
|
||||||
@ -28,7 +28,7 @@ namespace SemiColinGames {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Textures {
|
public static class Textures {
|
||||||
|
|
||||||
public static SpriteFont DebugFont;
|
public static SpriteFont DebugFont;
|
||||||
public static SpriteFont BannerFont;
|
public static SpriteFont BannerFont;
|
||||||
|
@ -6,7 +6,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace SemiColinGames {
|
namespace SemiColinGames {
|
||||||
|
|
||||||
class Terrain {
|
public class Terrain {
|
||||||
|
|
||||||
public static Terrain FromSymbol(char symbol) {
|
public static Terrain FromSymbol(char symbol) {
|
||||||
if (mapping.ContainsKey(symbol)) {
|
if (mapping.ContainsKey(symbol)) {
|
||||||
@ -18,6 +18,7 @@ namespace SemiColinGames {
|
|||||||
|
|
||||||
private readonly static Dictionary<char, Terrain> mapping = new Dictionary<char, Terrain>();
|
private readonly static Dictionary<char, Terrain> mapping = new Dictionary<char, Terrain>();
|
||||||
|
|
||||||
|
public static Terrain Empty = new Terrain('\0', false, Textures.Grassland, 0, 0);
|
||||||
public static Terrain Grass = new Terrain('=', true, Textures.Grassland, 3, 0);
|
public static Terrain Grass = new Terrain('=', true, Textures.Grassland, 3, 0);
|
||||||
public static Terrain GrassL = new Terrain('<', true, Textures.Grassland, 2, 0);
|
public static Terrain GrassL = new Terrain('<', true, Textures.Grassland, 2, 0);
|
||||||
public static Terrain GrassR = new Terrain('>', true, Textures.Grassland, 4, 0);
|
public static Terrain GrassR = new Terrain('>', true, Textures.Grassland, 4, 0);
|
||||||
@ -49,6 +50,7 @@ namespace SemiColinGames {
|
|||||||
public static Terrain Mushroom = new Terrain('t', false, Textures.Grassland, 17, 2);
|
public static Terrain Mushroom = new Terrain('t', false, Textures.Grassland, 17, 2);
|
||||||
|
|
||||||
public bool IsObstacle { get; private set; }
|
public bool IsObstacle { get; private set; }
|
||||||
|
public bool IsHarmful { get; private set; } = false;
|
||||||
public TextureRef Texture { get; private set; }
|
public TextureRef Texture { get; private set; }
|
||||||
public Rectangle TextureSource { get; private set; }
|
public Rectangle TextureSource { get; private set; }
|
||||||
|
|
||||||
@ -58,6 +60,10 @@ namespace SemiColinGames {
|
|||||||
}
|
}
|
||||||
mapping[symbol] = this;
|
mapping[symbol] = this;
|
||||||
IsObstacle = isObstacle;
|
IsObstacle = isObstacle;
|
||||||
|
// TODO: don't hard-code just the one spike.
|
||||||
|
if (symbol == '^') {
|
||||||
|
IsHarmful = true;
|
||||||
|
}
|
||||||
Texture = texture;
|
Texture = texture;
|
||||||
int size = World.TileSize;
|
int size = World.TileSize;
|
||||||
TextureSource = new Rectangle(x * size, y * size, size, size);
|
TextureSource = new Rectangle(x * size, y * size, size, size);
|
||||||
@ -138,7 +144,7 @@ namespace SemiColinGames {
|
|||||||
for (int i = 0; i < tiles.Length; i++) {
|
for (int i = 0; i < tiles.Length; i++) {
|
||||||
Vector2 center = new Vector2(
|
Vector2 center = new Vector2(
|
||||||
tiles[i].Position.Left + halfSize.X, tiles[i].Position.Top + halfSize.Y);
|
tiles[i].Position.Left + halfSize.X, tiles[i].Position.Top + halfSize.Y);
|
||||||
CollisionTargets[i + 1] = new AABB(center, halfSize);
|
CollisionTargets[i + 1] = new AABB(center, halfSize, tiles[i].Terrain);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a final synthetic collisionTarget on the right side of the world.
|
// Add a final synthetic collisionTarget on the right side of the world.
|
||||||
|
Loading…
Reference in New Issue
Block a user