Detta är en samlingsartikel för serien ”MonoGame för nybörjare”. I huvudsak bygger den på de Youtube-klipp som listas. Du finner också den grafik/content som används i serien här som nedladdningsbar zip-fil samt lite källkod ifall du missat något.
Grafik och Content
Monogame gfx/content
Ladda ned
534,67 KB
Del 1
Del 2
Del 3
Del 4
Del 5
Källkod
MonoGame för nybörjare - Efter del 5
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace MyGame
{
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private Texture2D normalTexture;
private Texture2D jumpingTexture;
private Texture2D crouchTexture;
private Texture2D fireballTexture;
private Texture2D currentTexture;
private Texture2D backgroundTexture;
private Texture2D layer1Texture;
private Texture2D layer2Texture;
private Texture2D layer3Texture;
private ParallaxTexture layer1;
private ParallaxTexture layer2;
private ParallaxTexture layer3;
private SpriteFont font;
private List<Vector2> fireballs;
private int fireballTimer = 120;
private Random rnd;
private Vector2 position;
private Vector2 speed;
private bool isJumping;
private bool isCrouching;
private bool hit;
private bool isPlaying;
private double score = 0;
private const int STARTY = 400;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
position = new Vector2(300, STARTY);
fireballs = new List<Vector2>();
rnd = new Random();
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
normalTexture = Content.Load<Texture2D>("normal");
jumpingTexture = Content.Load<Texture2D>("jump");
crouchTexture = Content.Load<Texture2D>("crouch");
fireballTexture = Content.Load<Texture2D>("fireball");
backgroundTexture = Content.Load<Texture2D>("background");
layer1Texture = Content.Load<Texture2D>("layer1");
layer2Texture = Content.Load<Texture2D>("layer2");
layer3Texture = Content.Load<Texture2D>("layer3");
layer1 = new ParallaxTexture(layer1Texture, 370);
layer2 = new ParallaxTexture(layer2Texture, 300);
layer3 = new ParallaxTexture(layer3Texture, 200);
font = Content.Load<SpriteFont>("font");
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed
|| Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
var state = Keyboard.GetState();
if (state.IsKeyDown(Keys.Enter) && !isPlaying)
{
Reset();
isPlaying = true;
}
if (!isPlaying)
return;
// parallax layers
layer1.OffsetX += 1.5f;
layer2.OffsetX += 1.0f;
layer3.OffsetX += 0.5f;
score += gameTime.ElapsedGameTime.TotalSeconds;
position += speed;
if (position.Y > STARTY)
{
position = new Vector2(position.X, STARTY);
speed = Vector2.Zero;
isJumping = false;
}
speed += new Vector2(0, 0.2f);
if (state.IsKeyDown(Keys.W) && !isJumping)
{
speed = new Vector2(0, -5.0f);
isJumping = true;
}
if (state.IsKeyDown(Keys.S) && !isJumping)
{
isCrouching = true;
}
else
{
isCrouching = false;
}
//fireballs!!
fireballTimer--;
if (fireballTimer <= 0)
{
fireballTimer = 120;
if (rnd.Next(2) == 0)
{
fireballs.Add(new Vector2(800, STARTY));
}
else
{
fireballs.Add(new Vector2(800, STARTY + 40));
}
}
for (int i = 0; i < fireballs.Count; i++)
{
fireballs[i] = fireballs[i] + new Vector2(-2, 0);
}
//collision
if (isJumping)
{
currentTexture = jumpingTexture;
}
else if (isCrouching)
{
currentTexture = crouchTexture;
}
else
{
currentTexture = normalTexture;
}
Rectangle playerBox = new Rectangle((int)position.X, (int)position.Y,
currentTexture.Width, currentTexture.Height);
hit = false;
foreach (var fireball in fireballs)
{
Rectangle fireballBox = new Rectangle((int)fireball.X, (int)fireball.Y,
fireballTexture.Width, fireballTexture.Height);
//Överlappar vi?
var kollision = Intersection(playerBox, fireballBox);
if (kollision.Width > 0 && kollision.Height > 0)
{
Rectangle r1 = Normalize(playerBox, kollision);
Rectangle r2 = Normalize(fireballBox, kollision);
hit = TestCollision(currentTexture, r1, fireballTexture, r2);
if (hit)
{
isPlaying = false;
}
}
}
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
//GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(backgroundTexture, Vector2.Zero, Color.White);
layer3.Draw(spriteBatch);
layer2.Draw(spriteBatch);
layer1.Draw(spriteBatch);
if (isPlaying)
{
spriteBatch.DrawString(font, ((int) score).ToString(),
new Vector2(10, 20), Color.White);
if (hit)
{
spriteBatch.DrawString(font, "HIT!!", new Vector2(10, 40), Color.White);
}
spriteBatch.Draw(currentTexture, position, Color.White);
foreach (var fireball in fireballs)
{
spriteBatch.Draw(fireballTexture, fireball, Color.White);
}
}
else
{
spriteBatch.DrawString(font, "Press ENTER to start!",
new Vector2(340, 200), Color.White);
}
spriteBatch.End();
base.Draw(gameTime);
}
private void Reset()
{
fireballs.Clear();
fireballTimer = 120;
score = 0;
}
public static Rectangle Normalize(Rectangle reference, Rectangle overlap)
{
//Räkna ut en rektangel som kan användas relativt till referensrektangeln
return new Rectangle(
overlap.X - reference.X,
overlap.Y - reference.Y,
overlap.Width,
overlap.Height);
}
public static bool TestCollision(Texture2D t1, Rectangle r1, Texture2D t2, Rectangle r2)
{
//Beräkna hur många pixlar som finns i området som ska undersökas
int pixelCount = r1.Width * r1.Height;
uint[] texture1Pixels = new uint[pixelCount];
uint[] texture2Pixels = new uint[pixelCount];
//Kopiera ut pixlarna från båda områdena
t1.GetData(0, r1, texture1Pixels, 0, pixelCount);
t2.GetData(0, r2, texture2Pixels, 0, pixelCount);
//Jämför om vi har några pixlar som överlappar varandra i områdena
for (int i = 0; i < pixelCount; ++i)
{
if (((texture1Pixels[i] & 0xff000000) > 0) && ((texture2Pixels[i] & 0xff000000) > 0))
{
return true;
}
}
return false;
}
public static Rectangle Intersection(Rectangle r1, Rectangle r2)
{
int x1 = Math.Max(r1.Left, r2.Left);
int y1 = Math.Max(r1.Top, r2.Top);
int x2 = Math.Min(r1.Right, r2.Right);
int y2 = Math.Min(r1.Bottom, r2.Bottom);
if ((x2 >= x1) && (y2 >= y1))
{
return new Rectangle(x1, y1, x2 - x1, y2 - y1);
}
return Rectangle.Empty;
}
}
}
ParallaxTexture.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace MyGame
{
class ParallaxTexture
{
private Texture2D _texture;
private int _positionY;
public float OffsetX { get; set; }
public ParallaxTexture(Texture2D Texture, int PositionY)
{
_positionY = PositionY;
_texture = Texture;
}
public void Draw(SpriteBatch spriteBatch)
{
int width = spriteBatch.GraphicsDevice.Adapter.CurrentDisplayMode.Width;
int textureStartX = (int)(OffsetX % _texture.Width);
int textureWidth = _texture.Width - textureStartX;
int startX = 0;
while (startX < width)
{
spriteBatch.Draw(_texture, new Vector2(startX, _positionY),
new Rectangle(textureStartX, 0, textureWidth, _texture.Height), Color.White);
startX += textureWidth;
textureStartX = 0;
textureWidth = _texture.Width;
}
}
}
}
Senaste kommentarer