Code:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace VGame
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
const int MAXX = 512, MAXY = 256;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Random aleatoire = new Random();
Texture2D[] textures = new Texture2D[5];
Texture2D[] mobs = new Texture2D[2];
Texture2D[] items = new Texture2D[4];
Texture2D blank, bouton;
SpriteFont _font;
int[,] terrain = new int[MAXX, MAXY];
int[,] arrièreplan = new int[MAXX, MAXY];
int x, y;
int[] ceinture = new int[10];
int[] nombre = new int[10];
int outilActifGauche, outilActifDroite;
int hauteurSaut;
bool peutSauter, peutAgir;
bool modeFantome;
TimeSpan attenteAction, tempsAction;
TimeSpan attenteMouvement, tempsMouvement;
TimeSpan attenteChute, tempsChute;
MouseState ms;
int xs, ys;
int xf, yf;
public Game1(){
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
int[,] densite = new int[MAXX, MAXY];
const int propagationAir = 20, propagationRoche = 40;
textures[0] = Content.Load<Texture2D>("textures/terre");
textures[1] = Content.Load<Texture2D>("textures/terre avec herbe");
textures[2] = Content.Load<Texture2D>("textures/pierre");
textures[3] = Content.Load<Texture2D>("textures/pierretaillée");
textures[4] = Content.Load<Texture2D>("textures/blocs d'or");
mobs[0] = Content.Load<Texture2D>("mob/perso");
mobs[1] = Content.Load<Texture2D>("mob/fantome de brume");
items[0] = Content.Load<Texture2D>("curseur");
items[1] = Content.Load<Texture2D>("items/pioche de bois");
items[2] = Content.Load<Texture2D>("textures/terre");
items[3] = Content.Load<Texture2D>("textures/pierre");
blank = Content.Load<Texture2D>("vierge");
bouton = Content.Load<Texture2D>("bouton");
_font = Content.Load<SpriteFont>("VFont");
// du ciel partout
for (int i = 0; i < MAXX; i += 1)
for (int j = 0; j < 50; j += 1)
{
terrain[i, j] = -1;
arrièreplan[i, j] = 0;
}
// collines
for (int debut = 0, fin, hauteur; debut < MAXX; debut = fin)
{
fin = debut + aleatoire.Next(5, 25);
if (fin > MAXX) fin = MAXX;
hauteur = (int)MathHelper.Min(aleatoire.Next(0, 30),aleatoire.Next(0, 15));
for (int i = debut; i < fin; i += 1)
for (int j = 50; j > 50-hauteur; j -= 1)
{
terrain[i, j] = 0;
arrièreplan[i, j] = 1;
}
}
// terre
for (int i = 0; i < MAXX; i += 1)
for (int j = 50; j < MAXY; j += 1)
{
terrain[i, j] = 0;
arrièreplan[i, j] = 1;
}
// ajout de roche
for (int i = 0; i < MAXX; i += 1)
for (int j = 0; j < MAXY / 3; j += 1)
if ((terrain[i, j] == 0) && (aleatoire.Next(20) == 0)) terrain[i, j] = 2;
for (int i = 0; i < MAXX; i += 1)
for (int j = (MAXY / 3); j < 2 * (MAXY / 3); j += 1)
if ((terrain[i, j] == 0) && (aleatoire.Next(10) == 0)) terrain[i, j] = 2;
for (int i = 0; i < MAXX; i += 1)
for (int j = 2 * (MAXY / 3); j < MAXY; j += 1)
if ((terrain[i, j] == 0) && (aleatoire.Next(5) == 0)) terrain[i, j] = 2;
// ajout de poches d'air
for (int debut = aleatoire.Next(5), fin, haut, bas; debut < MAXX; debut = fin + aleatoire.Next(5))
{
fin = debut + aleatoire.Next(5, 25);
if (fin > MAXX) fin = MAXX;
haut = (int)MathHelper.Min(aleatoire.Next(40, MAXY), aleatoire.Next(40, MAXY));
bas = haut + aleatoire.Next(3, 8);
if (bas > MAXY) bas = MAXY;
for (int i = debut; i < fin; i += 1)
for (int j = haut; j < bas ; j += 1)
terrain[i, j] = -1;
}
// propagation
for (int rep = 0; rep < 16; rep += 1)
{
for (int i = 1; i < MAXX - 1; i += 1)
for (int j = 1; j < MAXY - 1; j += 1)
{
if (terrain[i, j] == -1)
{
if (aleatoire.Next(propagationAir) == 0) terrain[i - 1, j] = -1;
if (aleatoire.Next(propagationAir) == 0) terrain[i + 1, j] = -1;
if (aleatoire.Next(propagationAir) == 0) terrain[i, j - 1] = -1;
if (aleatoire.Next(propagationAir) == 0) terrain[i, j + 1] = -1;
}
if (terrain[i, j] == 2)
{
if (aleatoire.Next(propagationRoche) == 0) terrain[i - 1, j] = 2;
if (aleatoire.Next(propagationRoche) == 0) terrain[i + 1, j] = 2;
if (aleatoire.Next(propagationRoche) == 0) terrain[i, j - 1] = 2;
if (aleatoire.Next(propagationRoche) == 0) terrain[i, j + 1] = 2;
}
}
}
// lisse les contours
for (int i = 1; i < MAXX - 1; i += 1)
for (int j = 1; j < MAXY - 1; j += 1)
if ((terrain[i - 1, j] == terrain[i, j - 1]) && (terrain[i - 1, j] == terrain[i, j + 1]))
terrain[i, j] = terrain[i - 1, j];
else if ((terrain[i + 1, j] == terrain[i, j - 1]) && (terrain[i + 1, j] == terrain[i, j + 1]))
terrain[i, j] = terrain[i + 1, j];
else if ((terrain[i, j - 1] == terrain[i - 1, j]) && (terrain[i, j - 1] == terrain[i + 1, j]))
terrain[i, j] = terrain[i, j - 1];
else if ((terrain[i, j + 1] == terrain[i - 1, j]) && (terrain[i, j + 1] == terrain[i + 1, j]))
terrain[i, j] = terrain[i, j + 1];
// enlève les blocs isolés
for (int i = 1; i < MAXX - 1; i += 1)
for (int j = 1; j < MAXY - 1; j += 1)
if ((terrain[i - 1, j] == terrain[i,j+1])
&& (terrain[i - 1, j] == terrain[i + 1, j])
&& (terrain[i - 1, j] == terrain[i, j - 1] ))
terrain[i, j] = terrain[i - 1, j];
// on retire l'arrière-plan en trop
Boolean continuer;
for (int i = 0; i < MAXX; i += 1)
{
continuer = true;
for (int j = 0; (j < MAXY) && continuer; j += 1)
{
if (terrain[i, j] != -1)
continuer = false;
else
arrièreplan[i, j] = 0;
}
}
for (int i = 1; i < MAXX - 1; i += 1)
{
for (int j = 1; j < MAXY; j += 1)
{
if (((arrièreplan[i-1, j] == 0) || (arrièreplan[i+1, j] == 0)) && (terrain[i,j] == -1))
arrièreplan[i, j] = 0;
}
}
// on pose le bonhomme, et on regarde où il tombe
x = 256;
y = 0;
continuer = true;
for (int j = 0; (j < MAXY) && continuer; j += 1)
if ((terrain[x, j] != -1) || (terrain[x - 1, j] != -1))
{
y = j;
continuer = false;
}
if (terrain[x, y] == -1) terrain[x, y] = 1;
if (terrain[x - 1, y] == -1) terrain[x - 1, y] = 1;
modeFantome = false;
hauteurSaut = 0;
peutSauter = true;
// Pose l'herbe
for (int i = 0; i < MAXX; i += 1)
{
Boolean herbe = false;
for (int j = 0; j < MAXY; j += 1)
if ((terrain[i, j] != -1) && !herbe)
{
if (terrain[i, j] == 0) terrain[i, j] = 1;
herbe = true;
}
}
for (int i = 0; i < MAXX; i += 1)
{
for (int j = 49; j < MAXY; j += 1)
if (terrain[i, j] == 1)
{
if ((i != 0) && (terrain[i - 1, j] == 0) && (terrain[i - 1, j - 1] == -1)) terrain[i - 1, j] = 1;
if ((i != (MAXX - 1)) && (terrain[i + 1, j] == 0) && (terrain[i + 1, j - 1] == -1)) terrain[i + 1, j] = 1;
}
}
ceinture[0] = 1;
for (int i = 1; i < 10; i += 1)
{
ceinture[i] = -1;
nombre[i] = 0;
}
outilActifGauche = 0;
outilActifDroite = -1;
attenteAction = TimeSpan.Zero;
tempsAction = TimeSpan.FromSeconds(0.25);
attenteMouvement = TimeSpan.Zero;
tempsMouvement = TimeSpan.FromSeconds(0.1);
attenteChute = TimeSpan.Zero;
tempsChute = TimeSpan.FromSeconds(0.05);
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
if (attenteAction > TimeSpan.Zero) attenteAction -= gameTime.ElapsedGameTime;
if (attenteAction < TimeSpan.Zero) attenteAction = TimeSpan.Zero;
if (attenteMouvement > TimeSpan.Zero) attenteMouvement -= gameTime.ElapsedGameTime;
if (attenteMouvement < TimeSpan.Zero) attenteMouvement = TimeSpan.Zero;
if (attenteChute > TimeSpan.Zero) attenteChute -= gameTime.ElapsedGameTime;
if (attenteChute < TimeSpan.Zero) attenteChute = TimeSpan.Zero;
ms = Mouse.GetState();
xs = ms.X / 16;
ys = ms.Y / 16;
xf = xs + x - 25;
yf = ys + y - 16;
if (Keyboard.GetState().IsKeyDown(Keys.Tab)) modeFantome = true;
if (Keyboard.GetState().IsKeyUp(Keys.Tab)) modeFantome = false;
// si on relâche la touche espace, on ne peut plus sauter à moins de toucher le sol
if (Keyboard.GetState().IsKeyUp(Keys.Space))
{
peutSauter = false;
}
if ((terrain[x, y] != -1) || (terrain[x - 1, y] != -1))
{
peutSauter = true;
hauteurSaut = 0;
}
if (!modeFantome)
{
if ((Keyboard.GetState().IsKeyDown(Keys.Q)) && (x > 26)
&& (terrain[x-2, y-1] == -1) && (terrain[x-2, y-2] == -1) && (terrain[x-2, y-3] == -1)
&& (attenteMouvement == TimeSpan.Zero)) { x -= 1; attenteMouvement += tempsMouvement; }
if ((Keyboard.GetState().IsKeyDown(Keys.D)) && (x < MAXX - 26)
&& (terrain[x + 1, y - 1] == -1) && (terrain[x + 1, y - 2] == -1) && (terrain[x + 1, y - 3] == -1)
&& (attenteMouvement == TimeSpan.Zero)) { x += 1; attenteMouvement += tempsMouvement; }
if ((Keyboard.GetState().IsKeyDown(Keys.Space)) && (hauteurSaut < 7) && (peutSauter) && (y > 17)
&& (attenteChute == TimeSpan.Zero))
{
if ((terrain[x, y - 4] == -1) && (terrain[x - 1, y - 4] == -1))
{
y -= 1;
attenteChute += tempsChute;
hauteurSaut += 1;
if (hauteurSaut == 7) peutSauter = false;
}
else peutSauter = false;
}
else if ((terrain[x, y] == -1) && (terrain[x - 1, y] == -1) && (y < MAXY - 17) && (!peutSauter)
&& (attenteChute == TimeSpan.Zero)) { y += 1; attenteChute += tempsChute; }
}
else
{
if ((Keyboard.GetState().IsKeyDown(Keys.Q)) && (x > 26)) x -= 1;
if ((Keyboard.GetState().IsKeyDown(Keys.D)) && (x < MAXX - 26)) x += 1;
if ((Keyboard.GetState().IsKeyDown(Keys.Z)) && (y > 17)) y -= 1;
if ((Keyboard.GetState().IsKeyDown(Keys.S)) && (y < MAXY - 17)) y += 1;
}
if (Keyboard.GetState().IsKeyDown(Keys.D1)) outilActifGauche = 0;
else if (Keyboard.GetState().IsKeyDown(Keys.D2)) outilActifGauche = 1;
else if (Keyboard.GetState().IsKeyDown(Keys.D3)) outilActifGauche = 2;
else if (Keyboard.GetState().IsKeyDown(Keys.D4)) outilActifGauche = 3;
else if (Keyboard.GetState().IsKeyDown(Keys.D5)) outilActifGauche = 4;
else if (Keyboard.GetState().IsKeyDown(Keys.D6)) outilActifGauche = 5;
else if (Keyboard.GetState().IsKeyDown(Keys.D7)) outilActifGauche = 6;
else if (Keyboard.GetState().IsKeyDown(Keys.D8)) outilActifGauche = 7;
else if (Keyboard.GetState().IsKeyDown(Keys.D9)) outilActifGauche = 8;
else if (Keyboard.GetState().IsKeyDown(Keys.D0)) outilActifGauche = 9;
// Action quand on clique ...
if ((ms.LeftButton == ButtonState.Pressed) && (peutAgir == true) && ((x - 5 < xf) && (xf < x + 4) && (y - 7 < yf) && (yf < y + 3)) && (attenteAction == TimeSpan.Zero))
{
if (ceinture[outilActifGauche] == 1)
{
int àajouter = -1;
if (terrain[xf, yf] == 0) { terrain[xf, yf] = -1; attenteAction += tempsAction; àajouter = 2; }
else if (terrain[xf, yf] == 1) { terrain[xf, yf] = 0; attenteAction += tempsAction; }
else if (terrain[xf, yf] == 2) { terrain[xf, yf] = 3; attenteAction += tempsAction; }
else if (terrain[xf, yf] == 3) { terrain[xf, yf] = -1; attenteAction += tempsAction; àajouter = 3; }
if (àajouter != -1)
{
int ou = -1;
for (int i = 0; i < 10; i += 1)
if ((ceinture[i] == àajouter) && (nombre[i] < 99)) ou = i;
if (ou == -1)
for (int i = 9; i >= 0; i -= 1)
if (ceinture[i] == -1) ou = i;
if (ou != -1)
{
ceinture[ou] = àajouter;
nombre[ou] += 1;
}
}
}
else if (ceinture[outilActifGauche] == 2)
{
if ((terrain[xf, yf] == -1) && ((terrain[xf - 1, yf] != -1) || (terrain[xf + 1, yf] != -1) || (terrain[xf, yf - 1] != -1) || (terrain[xf, yf + 1] != -1)))
{
terrain[xf, yf] = 0;
nombre[outilActifGauche] -= 1;
if (nombre[outilActifGauche] == 0)
{
ceinture[outilActifGauche] = -1;
outilActifGauche = -1;
for (int i = 9; i >= 0; i -= 1)
if (ceinture[i] == 2) outilActifGauche = i;
if (outilActifGauche == -1) outilActifGauche = 0;
}
}
}
else if (ceinture[outilActifGauche] == 3)
{
if ((terrain[xf, yf] == -1) && ((terrain[xf - 1, yf] != -1) || (terrain[xf + 1, yf] != -1) || (terrain[xf, yf - 1] != -1) || (terrain[xf, yf + 1] != -1)))
{
terrain[xf, yf] = 2;
nombre[outilActifGauche] -= 1;
if (nombre[outilActifGauche] == 0)
{
ceinture[outilActifGauche] = -1;
outilActifGauche = -1;
for (int i = 9; i >= 0; i -= 1)
if (ceinture[i] == 3) outilActifGauche = i;
if (outilActifGauche == -1) outilActifGauche = 0;
}
}
}
}
if (ms.LeftButton == ButtonState.Released)
peutAgir = true;
else
peutAgir = false;
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
// fond bleu ciel
GraphicsDevice.Clear(Color.LightBlue);
spriteBatch.Begin();
// on dessine le terrain
for (int i = 0; i < 50; i += 1)
for (int j = 0; j < 32; j += 1)
{
if ((x + i - 25 > 0) && (x + i - 25 < MAXX) && (y + j - 16 > 0) && (y + j - 16 < MAXY))
if (terrain[x + i - 25, y + j - 16] != -1)
spriteBatch.Draw(textures[terrain[x + i - 25, y + j - 16]], new Vector2(16 * i, 16 * j), Color.White);
else if (arrièreplan[x + i - 25, y + j - 16] == 1)
spriteBatch.Draw(textures[0], new Vector2(16 * i, 16 * j), Color.DarkGray);
}
// on dessine le bonhomme (ou un fantôme)
if (!modeFantome) spriteBatch.Draw(mobs[0], new Vector2(16 * 24, 16 * 13), Color.White);
else spriteBatch.Draw(mobs[1], new Vector2(16 * 24, 16 * 13), Color.White);
// barre d'outils de la ceinture
for (int i = 0; i < 10; i += 1)
{
if (i == outilActifGauche)
spriteBatch.Draw(bouton, new Vector2(8 + i * 48, 8), Color.DarkGray);
else
spriteBatch.Draw(bouton, new Vector2(8 + i * 48, 8), Color.White);
if (ceinture[i] != -1)
{
spriteBatch.Draw(items[ceinture[i]], new Vector2(16 + i * 48, 16), Color.White);
if (nombre[i] > 9)
spriteBatch.DrawString(_font, nombre[i].ToString(), new Vector2(22 + i * 48, 22), Color.Black);
else if (nombre[i] > 1)
spriteBatch.DrawString(_font, nombre[i].ToString(), new Vector2(28 + i * 48, 22), Color.Black);
}
}
// curseur (ou outil si assez proche du perso)
if ((x - 5 < xf) && (xf < x + 4) && (y - 7 < yf) && (yf < y + 3))
{
if (peutAgir == true)
spriteBatch.Draw(items[ceinture[outilActifGauche]], new Vector2(ms.X, ms.Y), Color.White);
else
spriteBatch.Draw(items[ceinture[outilActifGauche]], new Vector2(ms.X, ms.Y), Color.Gray);
}
else
spriteBatch.Draw(items[0], new Vector2(ms.X, ms.Y), Color.White);
spriteBatch.End();
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}
}
Actuellement, le scrolling se fait par à-coup d'une "brique de base" (16 pixels !). Ma prochaine étape consiste à lisser ça.