Witam,napisałem sobie taki oto kod do gry
Camera.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
namespace MyLittleWorld
{
class Camera : GameComponent
{
//Atrybuty - Attributes
private Vector3 cameraPosition;
private Vector3 cameraRotation;
private float cameraSpeed;
private Vector3 cameraLookAt;
private Vector3 mouseRotationBuffer;
private MouseState currentMouseState;
private MouseState PreviousMouseState;
//Właściwości - Properties
public Matrix Projection
{
get;
protected set;
}
public Vector3 Position
{
get { return cameraPosition; }
set
{
cameraPosition = value;
UpdateLookAt();
}
}
public Vector3 Rotation
{
get { return cameraRotation; }
set
{
cameraRotation = value;
UpdateLookAt();
}
}
public Matrix View
{
get { return Matrix.CreateLookAt(cameraPosition, cameraLookAt, Vector3.Up); }
}
//Konstruktor
public Camera(Game game, Vector3 position, Vector3 rotation, float speed)
: base(game)
{
cameraSpeed = speed;
//Konfiguracja Projekcji
Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Game.GraphicsDevice.Viewport.AspectRatio, 0.05f, 1000.0f);
//Ustawienia Domyślnej Rotacji i Pozycji Kamery
MoveTo(position, rotation);
PreviousMouseState = Mouse.GetState();
}
private void MoveTo(Vector3 pos, Vector3 rot)
{
Position = pos;
Rotation = rot;
}
//Aktualizacja Widoku na
private void UpdateLookAt()
{
//Budowa Macierzystej Rotacji
Matrix rotationMatrix = Matrix.CreateRotationX(cameraRotation.X) * Matrix.CreateRotationY(cameraRotation.Y);
//Budowa widoku na wektor przesunięcia
Vector3 LookAtOffset = Vector3.Transform(Vector3.UnitZ, rotationMatrix);
//Aktualizacja Widoku na
cameraLookAt = cameraPosition + LookAtOffset;
}
// Metoda Aktualizacji
public override void Update(GameTime gameTime)
{
float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
currentMouseState = Mouse.GetState();
KeyboardState ks = Keyboard.GetState();
//Przejmuje podstawowe poruszanie się za pomocą klawiszy
Vector3 moveVector = Vector3.Zero;
if (ks.IsKeyDown(Keys.Escape))
Game.Exit();
if (ks.IsKeyDown(Keys.W))
moveVector.Z = 1;
if (ks.IsKeyDown(Keys.S))
moveVector.Z = -1;
if (ks.IsKeyDown(Keys.A))
moveVector.X = 1;
if (ks.IsKeyDown(Keys.D))
moveVector.X = -1;
if (ks.IsKeyDown(Keys.Space))
moveVector.Y = 1;
if (ks.IsKeyDown(Keys.LeftShift))
moveVector.Y = -1;
if (ks.IsKeyDown(Keys.RightShift))
cameraSpeed++;
if (ks.IsKeyDown(Keys.RightControl))
{
cameraSpeed--;
if (cameraSpeed < 0)
cameraSpeed = 10f;
}
if (moveVector != Vector3.Zero)
{
moveVector.Normalize();
moveVector *= dt * cameraSpeed;
Move(moveVector);
}
float deltaX;
float deltaY;
if (currentMouseState != PreviousMouseState)
{
deltaX = currentMouseState.X - (Game.GraphicsDevice.Viewport.Width / 2);
deltaY = currentMouseState.Y - (Game.GraphicsDevice.Viewport.Height / 2);
mouseRotationBuffer.X -= 0.1f * deltaX * dt;
mouseRotationBuffer.Y -= 0.1f * deltaY * dt;
if (mouseRotationBuffer.Y < MathHelper.ToRadians(-75.0f))
mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.ToRadians(-75.0f));
if (mouseRotationBuffer.Y > MathHelper.ToRadians(75.0f))
mouseRotationBuffer.Y = mouseRotationBuffer.Y - (mouseRotationBuffer.Y - MathHelper.ToRadians(75.0f));
Rotation = new Vector3(-MathHelper.Clamp(mouseRotationBuffer.Y, MathHelper.ToRadians(-75.0f), MathHelper.ToRadians(75.0f)), MathHelper.WrapAngle(mouseRotationBuffer.X), 0);
deltaX = 0;
deltaY = 0;
}
PreviousMouseState = currentMouseState;
base.Update(gameTime);
}
//Metoda Poruszania się Kamery
private Vector3 PreviewMove(Vector3 amount)
{
//Tworzy macierzystą rotację
Matrix rotate = Matrix.CreateRotationY(cameraRotation.Y);
//Tworzy wektor poruszania się
Vector3 movement = new Vector3(amount.X, amount.Y, amount.Z);
movement = Vector3.Transform(movement, rotate);
//Zwraca wartość pozycji kamery i wartość wektora poruszania sie
return cameraPosition + movement;
}
//Metoda która właściwie pozwala poruszać się kamerze
private void Move(Vector3 scale)
{
MoveTo(PreviewMove(scale), Rotation);
}
}
}
Floor.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace XNA_First_Person_Camera
{
class Floor
{
//Atrybuty - Attributes
private int floorWidth;
private int floorHeight;
private VertexBuffer floorBuffer;
private GraphicsDevice device;
private Color[] floorColors = new Color[2] { Color.Black, Color.White };
//Konstruktor
public Floor(GraphicsDevice device, int width, int height)
{
this.device = device;
this.floorWidth = width;
this.floorHeight = height;
BuildFloorBuffer();
}
//Buduje Vertex Buffer
private void BuildFloorBuffer()
{
List<VertexPositionColor> vertexList = new List<VertexPositionColor>();
int counter = 0;
//Pętla tworząca podłoge
for (int x = 0; x < floorWidth; x++)
{
counter++;
for (int z = 0; z < floorHeight; z++)
{
counter++;
//Pętla tworząca wierzchołki
foreach (VertexPositionColor vertex in FloorTile(x, z, floorColors[counter % 2]))
{
vertexList.Add(vertex);
}
}
}
//Tworzy Buffer
floorBuffer = new VertexBuffer(device,VertexPositionColor.VertexDeclaration,vertexList.Count,BufferUsage.None);
floorBuffer.SetData<VertexPositionColor>(vertexList.ToArray());
}
//Definiuje pojedyńczą klatkę w naszej podłodze
private List<VertexPositionColor> FloorTile(int xOffset, int zOffset, Color TileColor)
{
List<VertexPositionColor> vList = new List<VertexPositionColor>();
vList.Add(new VertexPositionColor(new Vector3(0 + xOffset, 0, 0 + zOffset), TileColor));
vList.Add(new VertexPositionColor(new Vector3(1 + xOffset, 0, 0 + zOffset), TileColor));
vList.Add(new VertexPositionColor(new Vector3(0 + xOffset, 0, 1 + zOffset), TileColor));
vList.Add(new VertexPositionColor(new Vector3(1 + xOffset, 0, 0 + zOffset), TileColor));
vList.Add(new VertexPositionColor(new Vector3(1 + xOffset, 0, 1 + zOffset), TileColor));
vList.Add(new VertexPositionColor(new Vector3(0 + xOffset, 0, 1 + zOffset), TileColor));
return vList;
}
//Metoda rysująca
public void Draw(Camera camera, BasicEffect effect)
{
effect.VertexColorEnabled = true;
effect.View = camera.View;
effect.Projection = camera.Projection;
effect.World = Matrix.Identity;
//Pętla rysująca Wierzchołki
foreach (EffectPass pass in effect.CurrentTechnique.Passes)
{
pass.Apply();
device.SetVertexBuffer(floorBuffer);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, floorBuffer.VertexCount / 3 );
}
}
}
}
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 XNA_First_Person_Camera
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Camera camera;
BasicEffect effect;
Floor floor;
Model model;
Vector3 modelPosition;
Matrix View;
Matrix Projection;
float AspectRatio;
SpriteFont font;
KeyboardState ks;
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
ks = Keyboard.GetState();
camera = new Camera(this,new Vector3(0,0,0),Vector3.Zero,10f);
Components.Add(camera);
floor = new Floor(GraphicsDevice, 8, 8);
effect = new BasicEffect(GraphicsDevice);
this.IsMouseVisible = true;
font = Content.Load<SpriteFont>("Font");
AspectRatio = graphics.GraphicsDevice.Viewport.AspectRatio;
View = Matrix.CreateLookAt(camera.Position, Vector3.Zero, Vector3.Up);
Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(40.0f), AspectRatio, 100.0f, 100000.0f);
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);
model = Content.Load<Model>("Scene1");
// TODO: use this.Content to load your game content here
}
/// <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
}
public void ShowProperties()
{
spriteBatch.DrawString(font,camera.Position.ToString(),new Vector2(0,0),Color.White);
}
/// <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
// TODO: Add your update logic here
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
/// private void SetSharedEffectParameters()
///
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(new Color(148,152,154,0));
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effectt in mesh.Effects)
{
effectt.EnableDefaultLighting();
effectt.World = transforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(modelPosition);
effectt.View = View;
effectt.Projection = Projection;
}
mesh.Draw();
}
// TODO: Add your drawing code here
// floor.Draw(camera,effect);
floor.Draw(camera,effect);
spriteBatch.Begin();
if (ks.IsKeyDown(Keys.F3))
{
ShowProperties();
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Mam tutaj również dodany kod Modelu Kostki i Czcionki informującej o pozycji głównej kamer,problem w tym,że czcionka nie pojawia się na pozycjach x = 0,y = 0,z = 0 w przeciwieństwie do Kamery i Podłogi która pojawia się prawidłowo.
Dostrzegłem też inny błąd Kostka,z niewiadomego powodu podąża za moim kursorem.