|
|
using Microsoft.Xna.Framework;
|
|
|
using Microsoft.Xna.Framework.Audio;
|
|
|
using Microsoft.Xna.Framework.Input;
|
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
using Microsoft.Xna.Framework.Media;
|
|
|
|
|
|
using System;
|
|
|
using System.IO;
|
|
|
using SpriteFontPlus;
|
|
|
using isometricparkfna;
|
|
|
|
|
|
struct Entity
|
|
|
{
|
|
|
public Vector2 loc;
|
|
|
public Vector2 velocity;
|
|
|
|
|
|
private Rectangle _boundingBox;
|
|
|
|
|
|
public Rectangle BoundingBox
|
|
|
{
|
|
|
|
|
|
get
|
|
|
{
|
|
|
Rectangle calculatedRectangle = _boundingBox;
|
|
|
calculatedRectangle.Location += new Point((int)loc.X, (int)loc.Y);
|
|
|
return calculatedRectangle;
|
|
|
}
|
|
|
set { _boundingBox = value; }
|
|
|
}
|
|
|
|
|
|
public Entity(Vector2 loc, Vector2 velocity)
|
|
|
{
|
|
|
this.loc = loc;
|
|
|
this.velocity = velocity;
|
|
|
this._boundingBox = Rectangle.Empty;
|
|
|
}
|
|
|
|
|
|
public Entity(Vector2 loc, Vector2 velocity, Rectangle boundingBox)
|
|
|
{
|
|
|
this.loc = loc;
|
|
|
this.velocity = velocity;
|
|
|
this._boundingBox = boundingBox;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static class Camera
|
|
|
{
|
|
|
static public Vector2 Location = Vector2.Zero;
|
|
|
}
|
|
|
|
|
|
class FNAGame : Game
|
|
|
{
|
|
|
private KeyboardState keyboardPrev = new KeyboardState();
|
|
|
|
|
|
private SpriteBatch batch;
|
|
|
private Texture2D texture;
|
|
|
private Texture2D paddle;
|
|
|
private Texture2D ball;
|
|
|
private SoundEffect sound;
|
|
|
private Song music;
|
|
|
private SpriteFont font;
|
|
|
|
|
|
int frameRate = 0;
|
|
|
int frameCounter = 0;
|
|
|
TimeSpan elapsedTime = TimeSpan.Zero;
|
|
|
|
|
|
private const int width = 1280;
|
|
|
private const int height = 640;
|
|
|
|
|
|
|
|
|
private Entity paddleEntity = new Entity(Vector2.Zero, Vector2.Zero,
|
|
|
new Rectangle(36, 0, 20, 100));
|
|
|
private Entity ballEntity = new Entity(new Vector2(height, 360),
|
|
|
new Vector2(2.0f, 2.0f),
|
|
|
new Rectangle(36, 36, 20, 20));
|
|
|
private Entity aiPaddleEntity = new Entity(new Vector2(width - 100, 0), Vector2.Zero,
|
|
|
new Rectangle(36, 0, 20, 100));
|
|
|
|
|
|
private const float friction = 0.1f;
|
|
|
private const float inputVelocityDelta = friction + 0.1f;
|
|
|
|
|
|
|
|
|
private int playerScore = 0;
|
|
|
private int aiScore = 0;
|
|
|
|
|
|
//new tile stuff
|
|
|
TileMap myMap = new TileMap();
|
|
|
int squaresAcross = 25;
|
|
|
int squaresDown = 25;
|
|
|
int baseOffsetX = -14;
|
|
|
int baseOffsetY = -14;
|
|
|
|
|
|
|
|
|
private static void Main(string[] args)
|
|
|
{
|
|
|
using FNAGame g = new FNAGame();
|
|
|
g.Run();
|
|
|
}
|
|
|
|
|
|
public static bool Between(float val, float x, float y)
|
|
|
{
|
|
|
return ((x < val && val < y) || (y < val && val < x));
|
|
|
|
|
|
}
|
|
|
|
|
|
public Entity Move(ref Entity orig, bool score)
|
|
|
{
|
|
|
orig.loc += orig.velocity;
|
|
|
|
|
|
if (orig.loc.Y <= 0 && orig.velocity.Y < 0)
|
|
|
{
|
|
|
orig.velocity.Y *= -1;
|
|
|
orig.loc.Y = 0;
|
|
|
}
|
|
|
else if (orig.loc.Y >= (height) && orig.velocity.Y > 0)
|
|
|
{
|
|
|
orig.velocity.Y *= -1;
|
|
|
orig.loc.Y = (720 - 100);
|
|
|
}
|
|
|
|
|
|
if (orig.loc.X <= 0 && orig.velocity.X < 0)
|
|
|
{
|
|
|
orig.velocity.X *= -1;
|
|
|
orig.loc.X = 0;
|
|
|
|
|
|
if (score)
|
|
|
{
|
|
|
playerScore += 1;
|
|
|
}
|
|
|
}
|
|
|
else if (orig.loc.X >= width && orig.velocity.X > 0)
|
|
|
{
|
|
|
orig.velocity.X *= -1;
|
|
|
orig.loc.X = width;
|
|
|
|
|
|
if (score)
|
|
|
{
|
|
|
aiScore += 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return orig;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private FNAGame()
|
|
|
{
|
|
|
GraphicsDeviceManager gdm = new GraphicsDeviceManager(this)
|
|
|
{
|
|
|
|
|
|
// Typically you would load a config here...
|
|
|
PreferredBackBufferWidth = width,
|
|
|
PreferredBackBufferHeight = 720,
|
|
|
IsFullScreen = false,
|
|
|
SynchronizeWithVerticalRetrace = true
|
|
|
};
|
|
|
//gdm.SynchronizeWithVerticalRetrace = false;
|
|
|
IsFixedTimeStep = false;
|
|
|
|
|
|
Content.RootDirectory = "Content";
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
protected override void Initialize()
|
|
|
{
|
|
|
/* This is a nice place to start up the engine, after
|
|
|
* loading configuration stuff in the constructor
|
|
|
*/
|
|
|
|
|
|
base.Initialize();
|
|
|
}
|
|
|
|
|
|
protected override void LoadContent()
|
|
|
{
|
|
|
// Load textures, sounds, and so on in here...
|
|
|
// Create the batch...
|
|
|
batch = new SpriteBatch(GraphicsDevice);
|
|
|
|
|
|
// ... then load a texture from ./Content/FNATexture.png
|
|
|
texture = Content.Load<Texture2D>("FNATexture");
|
|
|
paddle = Content.Load<Texture2D>("paddle");
|
|
|
ball = Content.Load<Texture2D>("ball");
|
|
|
sound = Content.Load<SoundEffect>("FNASound");
|
|
|
music = Content.Load<Song>("IfImWrong");
|
|
|
Tile.TileSetTexture = Content.Load<Texture2D>(@"part4_tileset");
|
|
|
|
|
|
|
|
|
Line.initialize(GraphicsDevice);
|
|
|
|
|
|
|
|
|
|
|
|
var fontBakeResult = TtfFontBaker.Bake(File.OpenRead(@"Content/DroidSans.ttf"),
|
|
|
25,
|
|
|
1024,
|
|
|
1024,
|
|
|
new[]
|
|
|
{
|
|
|
CharacterRange.BasicLatin,
|
|
|
CharacterRange.Latin1Supplement,
|
|
|
CharacterRange.LatinExtendedA,
|
|
|
CharacterRange.Cyrillic
|
|
|
}
|
|
|
);
|
|
|
|
|
|
font = fontBakeResult.CreateSpriteFont(GraphicsDevice);
|
|
|
//DynamicSpriteFont font = DynamicSpriteFont.FromTtf(File.ReadAllBytes(@"Content/DroidSans.ttf"), 20);
|
|
|
|
|
|
}
|
|
|
|
|
|
protected override void UnloadContent()
|
|
|
{
|
|
|
// Clean up after yourself!
|
|
|
batch.Dispose();
|
|
|
texture.Dispose();
|
|
|
sound.Dispose();
|
|
|
music.Dispose();
|
|
|
}
|
|
|
|
|
|
|
|
|
protected float Decrement(float value, float delta)
|
|
|
{
|
|
|
float magnitude = Math.Abs(value);
|
|
|
|
|
|
//If distance from zero is less than our delta,
|
|
|
//go to zero to prevent overshooting:
|
|
|
if (magnitude < delta)
|
|
|
{
|
|
|
return 0.0f;
|
|
|
}
|
|
|
else if (value > 0)
|
|
|
{
|
|
|
return value - delta;
|
|
|
}
|
|
|
else if (value < 0)
|
|
|
{
|
|
|
return value + delta;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return 0.0f;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
protected override void Update(GameTime gameTime)
|
|
|
{
|
|
|
|
|
|
float volume = 1.0f;
|
|
|
float pitch = 0.0f;
|
|
|
float pan = 0.0f;
|
|
|
|
|
|
// Run game logic in here. Do NOT render anything here!
|
|
|
KeyboardState keyboardCur = Keyboard.GetState();
|
|
|
if (keyboardCur.IsKeyDown(Keys.Q) && keyboardPrev.IsKeyUp(Keys.Q))
|
|
|
{
|
|
|
System.Console.WriteLine("Quitting");
|
|
|
Environment.Exit(0);
|
|
|
}
|
|
|
|
|
|
|
|
|
if (keyboardCur.IsKeyDown(Keys.Space) && keyboardPrev.IsKeyUp(Keys.Space))
|
|
|
{
|
|
|
sound.Play(volume, pitch, pan);
|
|
|
}
|
|
|
//if (keyboardCur.IsKeyDown(Keys.P) && keyboardPrev.IsKeyUp(Keys.P))
|
|
|
// {
|
|
|
// this.player_state = !this.player_state;
|
|
|
// }
|
|
|
|
|
|
//if (player_state )
|
|
|
//{
|
|
|
// MediaPlayer.Play(music);
|
|
|
//}
|
|
|
|
|
|
|
|
|
elapsedTime += gameTime.ElapsedGameTime;
|
|
|
|
|
|
if (elapsedTime > TimeSpan.FromSeconds(1))
|
|
|
{
|
|
|
elapsedTime -= TimeSpan.FromSeconds(1);
|
|
|
frameRate = frameCounter;
|
|
|
frameCounter = 0;
|
|
|
}
|
|
|
|
|
|
base.Update(gameTime);
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
protected override void Draw(GameTime gameTime)
|
|
|
{
|
|
|
// Render stuff in here. Do NOT run game logic in here!
|
|
|
|
|
|
frameCounter++;
|
|
|
|
|
|
string fps = string.Format("fps: {0}", frameRate);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GraphicsDevice.Clear(Color.CornflowerBlue);
|
|
|
batch.Begin();
|
|
|
|
|
|
Line.drawLine(batch, new Vector2(0, 1), new Vector2(1, 50), Color.Black);
|
|
|
Line.drawLine(batch, new Vector2(0, 50), new Vector2(1, 100), Color.White);
|
|
|
Line.drawLine(batch, new Vector2(500, 500), new Vector2(500, 1000), Color.White);
|
|
|
|
|
|
|
|
|
//New tile stuff
|
|
|
Vector2 firstSquare = new Vector2(Camera.Location.X / 32,
|
|
|
Camera.Location.Y / 32);
|
|
|
int firstX = (int)firstSquare.X;
|
|
|
int firstY = (int)firstSquare.Y;
|
|
|
|
|
|
Vector2 squareOffset = new Vector2(Camera.Location.X % 32,
|
|
|
Camera.Location.Y % 32);
|
|
|
|
|
|
int offsetX = (int)squareOffset.X;
|
|
|
int offsetY = (int)squareOffset.Y;
|
|
|
|
|
|
|
|
|
for (int y = 0; y < this.squaresDown; y++)
|
|
|
{
|
|
|
int rowOffset = 0;
|
|
|
if ((firstY + y) % 2 == 1)
|
|
|
rowOffset = Tile.OddRowXOffset;
|
|
|
|
|
|
for (int x = 0; x < this.squaresAcross; x++)
|
|
|
{
|
|
|
batch.Draw(
|
|
|
Tile.TileSetTexture,
|
|
|
new Rectangle(
|
|
|
(x * Tile.TileStepX) - offsetX + rowOffset + baseOffsetX,
|
|
|
(y * Tile.TileStepY) - offsetY + baseOffsetY,
|
|
|
Tile.TileWidth, Tile.TileHeight),
|
|
|
Tile.GetSourceRectangle(1),
|
|
|
Color.White);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//Gridlines
|
|
|
//Lines going down and to the right:
|
|
|
for (int x = (-this.squaresAcross); x < this.squaresAcross; x++)
|
|
|
{
|
|
|
int rowOffset = 0;
|
|
|
|
|
|
float startX = (x * Tile.TileStepX) + baseOffsetX - (Tile.TileStepX / 2);
|
|
|
|
|
|
Vector2 start = new Vector2(startX, -baseOffsetY+4);
|
|
|
Vector2 stop = new Vector2(startX + this.squaresAcross* Tile.TileStepX/2,
|
|
|
this.squaresDown*Tile.TileStepY- baseOffsetY+4);
|
|
|
|
|
|
Line.drawLine(batch, start, stop, Color.White);
|
|
|
|
|
|
}
|
|
|
//Lines going down and to the left:
|
|
|
for (int x = 0; x < (2*this.squaresAcross); x++)
|
|
|
{
|
|
|
|
|
|
float startX = (x * Tile.TileStepX) + baseOffsetX - (Tile.TileStepX / 2);
|
|
|
|
|
|
Vector2 start_reverse = new Vector2(startX, -baseOffsetY + 4);
|
|
|
Vector2 stop_reverse = new Vector2(startX + -(this.squaresAcross * Tile.TileStepX / 2),
|
|
|
(this.squaresDown * Tile.TileStepY) - baseOffsetY + 4);
|
|
|
|
|
|
Line.drawLine(batch, start_reverse, stop_reverse, Color.White);
|
|
|
|
|
|
}
|
|
|
|
|
|
batch.DrawString(font, fps, new Vector2(33, 33), Color.Black);
|
|
|
batch.DrawString(font, fps, new Vector2(32, 32), Color.White);
|
|
|
batch.End();
|
|
|
|
|
|
base.Draw(gameTime);
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|