basic scrolling world!
GitOrigin-RevId: 6c08535f1ace172f9f08479ced5e9dc8b0663102
This commit is contained in:
parent
873d35dcfb
commit
22db0ee696
@ -1,10 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
|
||||
namespace Jumpy {
|
||||
class Camera {
|
||||
public const int Width = 1920 / 6;
|
||||
public const int Height = 1080 / 6;
|
||||
private Rectangle bbox = new Rectangle(0, 0, 1920 / 6, 1080 / 6);
|
||||
|
||||
public int Width { get => bbox.Width; }
|
||||
public int Height { get => bbox.Height; }
|
||||
public int Left { get => bbox.Left; }
|
||||
|
||||
public void Update(GameTime time, Point player) {
|
||||
int diff = player.X - bbox.Center.X;
|
||||
// TODO: use the actual center of the player's bbox.
|
||||
if (Math.Abs(diff) > 16) {
|
||||
bbox.Offset((int) (diff * 0.1), 0);
|
||||
}
|
||||
if (bbox.Left < 0) {
|
||||
bbox.Offset(-bbox.Left, 0);
|
||||
}
|
||||
Debug.Toast($"p: {player.X} c: {bbox.Center.X}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,11 @@ namespace Jumpy {
|
||||
public static bool Enabled;
|
||||
static List<DebugRect> rects = new List<DebugRect>();
|
||||
static Texture2D whiteTexture;
|
||||
static string toast = null;
|
||||
|
||||
public static void Toast(string s) {
|
||||
toast = s;
|
||||
}
|
||||
|
||||
public static void WriteLine(string s) {
|
||||
System.Diagnostics.Debug.WriteLine(s);
|
||||
@ -40,12 +45,22 @@ namespace Jumpy {
|
||||
rects.Add(new DebugRect(rect, color));
|
||||
}
|
||||
|
||||
public static void Draw(SpriteBatch spriteBatch) {
|
||||
public static void DrawToast(SpriteBatch spriteBatch, SpriteFont font) {
|
||||
// TODO: this use of toast isn't thread-safe.
|
||||
if (toast == null) {
|
||||
return;
|
||||
}
|
||||
spriteBatch.DrawString(font, toast, new Vector2(10, 10), Color.YellowGreen);
|
||||
toast = null;
|
||||
}
|
||||
|
||||
public static void Draw(SpriteBatch spriteBatch, Camera camera) {
|
||||
if (!Enabled) {
|
||||
return;
|
||||
}
|
||||
foreach (var debugRect in rects) {
|
||||
var rect = debugRect.rect;
|
||||
rect.Offset(-camera.Left, 0);
|
||||
var color = debugRect.color;
|
||||
// top side
|
||||
spriteBatch.Draw(
|
||||
|
@ -29,6 +29,7 @@ namespace Jumpy {
|
||||
|
||||
Player player;
|
||||
World world;
|
||||
Camera camera = new Camera();
|
||||
|
||||
public JumpyGame() {
|
||||
graphics = new GraphicsDeviceManager(this);
|
||||
@ -46,7 +47,7 @@ namespace Jumpy {
|
||||
|
||||
for (int i = 0; i < renderTargets.Length; i++) {
|
||||
renderTargets[i] = new RenderTarget2D(
|
||||
GraphicsDevice, Camera.Width, Camera.Height, false /* mipmap */,
|
||||
GraphicsDevice, camera.Width, camera.Height, false /* mipmap */,
|
||||
GraphicsDevice.PresentationParameters.BackBufferFormat, DepthFormat.Depth24);
|
||||
}
|
||||
|
||||
@ -95,6 +96,8 @@ namespace Jumpy {
|
||||
List<Rectangle> collisionTargets = world.CollisionTargets();
|
||||
player.Update(gameTime, gamePad, collisionTargets);
|
||||
|
||||
camera.Update(gameTime, player.Position);
|
||||
|
||||
base.Update(gameTime);
|
||||
}
|
||||
|
||||
@ -109,23 +112,25 @@ namespace Jumpy {
|
||||
renderTargetIdx = (renderTargetIdx + 1) % renderTargets.Length;
|
||||
GraphicsDevice.SetRenderTarget(renderTarget);
|
||||
GraphicsDevice.Clear(Color.CornflowerBlue);
|
||||
spriteBatch.Begin();
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.LinearWrap, null, null);
|
||||
|
||||
// Draw background.
|
||||
Rectangle bgSource = new Rectangle(
|
||||
0, grasslandBg1.Height - Camera.Height, Camera.Width, Camera.Height);
|
||||
Rectangle bgTarget = new Rectangle(0, 0, Camera.Width, Camera.Height);
|
||||
(int) (camera.Left * 0.25), grasslandBg1.Height - camera.Height, camera.Width, camera.Height);
|
||||
Rectangle bgTarget = new Rectangle(0, 0, camera.Width, camera.Height);
|
||||
spriteBatch.Draw(grasslandBg2, bgTarget, bgSource, Color.White);
|
||||
bgSource = new Rectangle(
|
||||
(int) (camera.Left * 0.5), grasslandBg1.Height - camera.Height, camera.Width, camera.Height);
|
||||
spriteBatch.Draw(grasslandBg1, bgTarget, bgSource, Color.White);
|
||||
|
||||
// Draw player.
|
||||
player.Draw(gameTime, spriteBatch);
|
||||
player.Draw(spriteBatch, camera, gameTime);
|
||||
|
||||
// Draw foreground tiles.
|
||||
world.Draw(spriteBatch);
|
||||
world.Draw(spriteBatch, camera);
|
||||
|
||||
// Draw debug rects.
|
||||
Debug.Draw(spriteBatch);
|
||||
Debug.Draw(spriteBatch, camera);
|
||||
|
||||
// Aaaaand we're done.
|
||||
spriteBatch.End();
|
||||
@ -143,9 +148,11 @@ namespace Jumpy {
|
||||
if (Debug.Enabled) {
|
||||
string fpsText = $"{GraphicsDevice.Viewport.Width}x{GraphicsDevice.Viewport.Height}, " +
|
||||
$"{fpsCounter.Fps} FPS";
|
||||
spriteBatch.DrawString(font, fpsText, new Vector2(10, 10), Color.White);
|
||||
spriteBatch.DrawString(font, fpsText, new Vector2(10, 40), Color.YellowGreen);
|
||||
}
|
||||
|
||||
Debug.DrawToast(spriteBatch, font);
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
base.Draw(gameTime);
|
||||
|
@ -17,7 +17,7 @@ namespace Jumpy {
|
||||
private const int jumpSpeed = 600;
|
||||
private const int gravity = 2400;
|
||||
|
||||
private Point position = new Point(Camera.Width / 2, 10);
|
||||
private Point position = new Point(64, 16);
|
||||
private Facing facing = Facing.Right;
|
||||
private Pose pose = Pose.Standing;
|
||||
private AirState airState = AirState.Ground;
|
||||
@ -29,6 +29,8 @@ namespace Jumpy {
|
||||
this.texture = texture;
|
||||
}
|
||||
|
||||
public Point Position { get { return position; } }
|
||||
|
||||
private Rectangle Bbox(Point position) {
|
||||
return new Rectangle(position.X - spriteWidth, position.Y - 7, spriteWidth * 2, 26);
|
||||
}
|
||||
@ -150,7 +152,8 @@ namespace Jumpy {
|
||||
pose = Pose.Jumping;
|
||||
}
|
||||
|
||||
position.X = Math.Min(Math.Max(position.X, 0 + spriteWidth), Camera.Width - spriteWidth);
|
||||
// TODO: also bound player position by the right edge of the World?
|
||||
position.X = Math.Max(position.X, 0 + spriteWidth);
|
||||
}
|
||||
|
||||
private int spritePosition(Pose pose, GameTime time) {
|
||||
@ -187,14 +190,14 @@ namespace Jumpy {
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(GameTime time, SpriteBatch spriteBatch) {
|
||||
public void Draw(SpriteBatch spriteBatch, Camera camera, GameTime time) {
|
||||
// TODO: don't create so many "new" things that could be cached / precomputed.
|
||||
int index = spritePosition(pose, time);
|
||||
Rectangle textureSource = new Rectangle(index * spriteSize, 0, spriteSize, spriteSize);
|
||||
Vector2 spriteCenter = new Vector2(spriteSize / 2, spriteSize / 2);
|
||||
SpriteEffects effect = facing == Facing.Right ?
|
||||
SpriteEffects.FlipHorizontally : SpriteEffects.None;
|
||||
Vector2 drawPos = new Vector2(position.X, position.Y);
|
||||
Vector2 drawPos = new Vector2(position.X - camera.Left, position.Y);
|
||||
spriteBatch.Draw(texture, drawPos, textureSource, Color.White, 0f, spriteCenter,
|
||||
Vector2.One, effect, 0f);
|
||||
}
|
||||
|
@ -27,33 +27,34 @@ namespace Jumpy {
|
||||
public Rectangle Position { get { return position; } }
|
||||
public Terrain Terrain { get { return terrain; } }
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch) {
|
||||
public void Draw(SpriteBatch spriteBatch, Camera camera) {
|
||||
int size = World.TileSize;
|
||||
Vector2 drawPos = new Vector2(position.Left - camera.Left, position.Top);
|
||||
switch (terrain) {
|
||||
case Terrain.Grass: {
|
||||
// TODO: hold these rectangles statically instead of making them anew constantly.
|
||||
Rectangle source = new Rectangle(3 * size, 0 * size, size, size);
|
||||
spriteBatch.Draw(texture, position, source, Color.White);
|
||||
spriteBatch.Draw(texture, drawPos, source, Color.White);
|
||||
break;
|
||||
}
|
||||
case Terrain.GrassL: {
|
||||
Rectangle source = new Rectangle(2 * size, 0 * size, size, size);
|
||||
spriteBatch.Draw(texture, position, source, Color.White);
|
||||
spriteBatch.Draw(texture, drawPos, source, Color.White);
|
||||
break;
|
||||
}
|
||||
case Terrain.GrassR: {
|
||||
Rectangle source = new Rectangle(4 * size, 0 * size, size, size);
|
||||
spriteBatch.Draw(texture, position, source, Color.White);
|
||||
spriteBatch.Draw(texture, drawPos, source, Color.White);
|
||||
break;
|
||||
}
|
||||
case Terrain.Rock: {
|
||||
Rectangle source = new Rectangle(3 * size, 1 * size, size, size);
|
||||
spriteBatch.Draw(texture, position, source, Color.White);
|
||||
spriteBatch.Draw(texture, drawPos, source, Color.White);
|
||||
break;
|
||||
}
|
||||
case Terrain.Water: {
|
||||
Rectangle source = new Rectangle(9 * size, 2 * size, size, size);
|
||||
spriteBatch.Draw(texture, position, source, Color.White);
|
||||
spriteBatch.Draw(texture, drawPos, source, Color.White);
|
||||
break;
|
||||
}
|
||||
case Terrain.Empty:
|
||||
@ -74,18 +75,18 @@ namespace Jumpy {
|
||||
public int Height { get; }
|
||||
|
||||
string[] worldDesc = new string[] {
|
||||
" ",
|
||||
" ",
|
||||
" ",
|
||||
" <=> ",
|
||||
" ",
|
||||
" ",
|
||||
" <=> <=> ",
|
||||
" = ",
|
||||
" ",
|
||||
" ",
|
||||
"=============> <===",
|
||||
"..............~~~~~." };
|
||||
" .",
|
||||
" .",
|
||||
" .",
|
||||
" <=> === .",
|
||||
" .",
|
||||
" .",
|
||||
" <=> <=> ======== == .",
|
||||
" = == .",
|
||||
" == .",
|
||||
" .",
|
||||
"=============> <==================================================================.",
|
||||
"..............~~~~~................................................................." };
|
||||
|
||||
public World(Texture2D texture) {
|
||||
// TODO: better error handling for if the string[] isn't rectangular.
|
||||
@ -122,10 +123,10 @@ namespace Jumpy {
|
||||
}
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch) {
|
||||
public void Draw(SpriteBatch spriteBatch, Camera camera) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
for (int i = 0; i < width; i++) {
|
||||
tiles[i, j].Draw(spriteBatch);
|
||||
tiles[i, j].Draw(spriteBatch, camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user