What I have:
game class
model class for my ship
Camera class
when I Press F5 my game opens, it shows blue, but my model doesnt appear, anyone got any advice for why this is happening?
if anyone would be able to help i would really thankful.
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 test1
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
//Visual components
Ship ship = new Ship();
Camera _camera;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
this.graphics.ToggleFullScreen();
this._camera = new Camera(graphics.GraphicsDevice.Viewport);
this._camera.LookAt = new Vector3(0.0f, 0.0f, -1.0f);
base.Initialize();
}
protected override void LoadContent()
{
ship.Model = Content.Load<Model>("Models/p1_wedge");
ship.Transforms = _camera.SetupEffectDefaults(ship.Model);
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
// Get some input.
UpdateInput();
base.Update(gameTime);
}
protected void UpdateInput()
{
// Get the game pad state.
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
KeyboardState currentKeyState = Keyboard.GetState();
ship.Update(currentState);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
//camera
this._camera.Update();
_camera.LookAt = ship.Position;
Matrix shipTransformMatrix = ship.RotationMatrix
* Matrix.CreateTranslation(ship.Position);
DrawModel(ship.Model, shipTransformMatrix, ship.Transforms);
base.Draw(gameTime);
}
public static void DrawModel(Model model, Matrix modelTransform,
Matrix[] absoluteBoneTransforms)
{
//Draw the model, a model can have multiple meshes, so loop
foreach (ModelMesh mesh in model.Meshes)
{
//This is where the mesh orientation is set
foreach (BasicEffect effect in mesh.Effects)
{
effect.World =
absoluteBoneTransforms[mesh.ParentBone.Index] *
modelTransform;
}
mesh.Draw();
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace test1
{
class Ship
{
public Model Model;
public Matrix[] Transforms;
//Position of the model in world space
public Vector3 Position = Vector3.Zero;
//Velocity of the model, applied each frame to the model's position
public Vector3 Velocity = Vector3.Zero;
private const float VelocityScale = 5.0f;
public Matrix RotationMatrix =
Matrix.CreateRotationX(MathHelper.PiOver2);
private float rotation;
public float Rotation
{
get { return rotation; }
set
{
float newVal = value;
while (newVal >= MathHelper.TwoPi)
{
newVal -= MathHelper.TwoPi;
}
while (newVal < 0)
{
newVal += MathHelper.TwoPi;
}
if (rotation != value)
{
rotation = value;
RotationMatrix =
Matrix.CreateRotationX(MathHelper.PiOver2) *
Matrix.CreateRotationZ(rotation);
}
}
}
public void Update(GamePadState controllerState)
{
KeyboardState currentKeyState = Keyboard.GetState();
if (currentKeyState.IsKeyDown(Keys.A))
Rotation += 0.10f;
else
// Rotate the model using the left thumbstick, and scale it down.
Rotation -= controllerState.ThumbSticks.Left.X * 0.10f;
if (currentKeyState.IsKeyDown(Keys.D))
Rotation -= 0.10f;
if (currentKeyState.IsKeyDown(Keys.W))
Velocity += RotationMatrix.Forward * VelocityScale;
else
// Finally, add this vector to our velocity.
Velocity += RotationMatrix.Forward * VelocityScale *
controllerState.Triggers.Right;
// In case you get lost, press A to warp back to the center.
if (currentKeyState.IsKeyDown(Keys.Enter))
{
Position = Vector3.Zero;
Velocity = Vector3.Zero;
Rotation = 0.0f;
}
Position += Velocity;
Velocity *= 0.95f;
}
}
}
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.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Graphics;
namespace test1
{
public class Camera
{
private Vector3 _position;
private Vector3 _lookAt;
private Matrix _viewMatrix;
private Matrix _projectionMatrix;
private float _aspectRatio;
public Camera(Viewport viewport)
{
this._aspectRatio = ((float)viewport.Width) / ((float)viewport.Height);
this._projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(40.0f),
this._aspectRatio,
20000.0f,
30000.0f);
}
public Vector3 Position
{
get { return this._position; }
set { this._position = value; }
}
public Vector3 LookAt
{
get { return this._lookAt; }
set { this._lookAt = value; }
}
public Matrix ViewMatrix
{
get { return this._viewMatrix; }
}
public Matrix ProjectionMatrix
{
get { return this._projectionMatrix; }
}
public void Update()
{
this._viewMatrix =
Matrix.CreateLookAt(this._position, this._lookAt, Vector3.Up);
}
public Matrix[] SetupEffectDefaults(Model myModel)
{
Matrix[] absoluteTransforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(absoluteTransforms);
foreach (ModelMesh mesh in myModel.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.Projection = ProjectionMatrix;
effect.View = ViewMatrix;
}
}
return absoluteTransforms;
}
}
}
EDIT
public static void DrawModel(Model model, Matrix modelTransform,
Matrix[] absoluteBoneTransforms)
{
//Draw the model, a model can have multiple meshes, so loop
foreach (ModelMesh mesh in model.Meshes)
{
//This is where the mesh orientation is set
foreach (BasicEffect effect in mesh.Effects)
{
effect.World =
absoluteBoneTransforms[mesh.ParentBone.Index] *
modelTransform;
effect.Projection = _camera.ProjectionMatrix;
effect.View = _camera.ViewMatrix;
}
//Draw the mesh, will use the effects set above.
mesh.Draw();
}
I think there are 2 issues with your code:
Look At You don't seem to update the Look At of your camera to point towards your spaceship, either make your camera "track" the spaceship by giving it a reference to it and in your Update update the look at position or manually update the lookat position from your Game1.
View / Projection Matrix Even though your camera has a view matrix and a projection matrix, you don't use them in your DrawModel. When you assign your world, consider adding the two following lines
effect.Projection = _camera.ProjectionMatrix;
effect.View = _camera.ViewMatrix;
There are possibly several issues in your code preventing it from working as expected. The two that pop out at me is that 1.) you never set the camera position so it defaults to 0,0,0 which colocates it with the ship model. So your camera is actually inside the model and any triangle that is in it's view would be culled as a backside triangle if 2.) it wasn't already frustrum culled since your nearplane is set to 20000.
Related
Im trying to make a game in Monogame and have followed a camera tutorial here https://www.youtube.com/watch?v=c_SPRT7DAeM&t=180s (which works great) The only problem is that when it zooms it zooms to the corner of the player sprite as you can see here:
Here is my code
camera.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace RpgGameCrossPlatform
{
class Camera
{
private Matrix transform;
public Matrix Transform
{
get { return transform; }
}
private Vector2 centre;
private Viewport viewport;
private float zoom = 3;
public float rotation = 0;
public float CentreX
{
get { return centre.X; }
set { centre.X = value; }
}
public float CentreY
{
get { return centre.Y; }
set { centre.Y = value; }
}
public float Zoom
{
get { return zoom; }
set { zoom = value; if (zoom < 0.1f) zoom = 0.1f; }
}
public Camera (Viewport newViewport)
{
viewport = newViewport;
}
public void CameraUpdate(Vector2 position)
{
centre = new Vector2(position.X, position.Y);
transform = Matrix.CreateTranslation(new Vector3(-centre.X, -centre.Y, 0)) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) *
Matrix.CreateTranslation(new Vector3(viewport.Width / 2, viewport.Height / 2, 0));
}
}
}
player.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace RpgGameCrossPlatform
{
class Camera
{
private Matrix transform;
public Matrix Transform
{
get { return transform; }
}
private Vector2 centre;
private Viewport viewport;
private float zoom = 3;
public float rotation = 0;
public float CentreX
{
get { return centre.X; }
set { centre.X = value; }
}
public float CentreY
{
get { return centre.Y; }
set { centre.Y = value; }
}
public float Zoom
{
get { return zoom; }
set { zoom = value; if (zoom < 0.1f) zoom = 0.1f; }
}
public Camera (Viewport newViewport)
{
viewport = newViewport;
}
public void CameraUpdate(Vector2 position)
{
centre = new Vector2(position.X, position.Y);
transform = Matrix.CreateTranslation(new Vector3(-centre.X, -centre.Y, 0)) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) *
Matrix.CreateTranslation(new Vector3(viewport.Width / 2, viewport.Height / 2, 0));
}
}
}
and game.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace RpgGameCrossPlatform
{
class Camera
{
private Matrix transform;
public Matrix Transform
{
get { return transform; }
}
private Vector2 centre;
private Viewport viewport;
private float zoom = 3;
public float rotation = 0;
public float CentreX
{
get { return centre.X; }
set { centre.X = value; }
}
public float CentreY
{
get { return centre.Y; }
set { centre.Y = value; }
}
public float Zoom
{
get { return zoom; }
set { zoom = value; if (zoom < 0.1f) zoom = 0.1f; }
}
public Camera (Viewport newViewport)
{
viewport = newViewport;
}
public void CameraUpdate(Vector2 position)
{
centre = new Vector2(position.X, position.Y);
transform = Matrix.CreateTranslation(new Vector3(-centre.X, -centre.Y, 0)) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 0)) *
Matrix.CreateTranslation(new Vector3(viewport.Width / 2, viewport.Height / 2, 0));
}
}
}
help would be appreciated as well as some general tips as I am new :)
This could mean that the camera is focussing on the player's default position, which is always on top-left.
You should set a center position (called the 'origin') for the player, this could be done by adding half of the player's width (for x) and height (for y) at the current default position it's focussing at.
I am trying to create a simple menu, the string that is selected changes colur as it is instructed to do, I just can't seem to space out each item in the string list on the Y axis, currently they are all positioned in the middle but at the top of the screen overlapping each other. I know this is probably a very simple fix but I am a novice at XNA. Any help would be very appreciated. Thanks in advance.
MenuManagement Class
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Game2
{
class MenuManagement
{
KeyboardState keyboard;
KeyboardState prevKey;
MouseState mouse;
Vector2 position;
List<String> buttonList = new List<string>();
SpriteFont spriteFont;
int selected = 0;
public MenuManagement ()
{
buttonList.Add("Play");
buttonList.Add("Options");
buttonList.Add("instructions");
buttonList.Add("Exit");
}
private void MeasureMenu()
{
height = 0;
width = 0;
foreach (string item in buttonList)
{
Vector2 size = spriteFont.MeasureString(item);
height += spriteFont.LineSpacing + 5;
}
}
public void LoadContent (ContentManager Content )
{
spriteFont = Content.Load<SpriteFont>("spriteFont");
}
public void Update (GameTime theGameTime)
{
keyboard = Keyboard.GetState();
if (checkKeyBoard(Keys.Up))
{
if (selected > 0)
{
selected--;
}
}
if (checkKeyBoard(Keys.Down))
{
if (selected < buttonList.Count - 1)
{
selected++;
}
}
prevKey = keyboard;
}
public bool checkKeyBoard (Keys key)
{
return (keyboard.IsKeyDown(key) && prevKey.IsKeyDown(key));
}
public void Draw (SpriteBatch theSpriteBatch)
{
theSpriteBatch.Begin();
Color color;
for (int i = 0; i < buttonList.Count; i++)
{
Vector2 location = position;
if (i == selected)
{
color = Color.Yellow;
}
else
{
color = Color.Blue;
}
location.Y += spriteFont.LineSpacing + 5;
}
theSpriteBatch.DrawString(spriteFont, buttonList[0], new Vector2 (300, 100), color);
theSpriteBatch.DrawString(spriteFont, buttonList[1], new Vector2(300, 150), color);
theSpriteBatch.DrawString(spriteFont, buttonList[2], new Vector2(300, 200), color);
theSpriteBatch.DrawString(spriteFont, buttonList[3], new Vector2(300, 250), color);
theSpriteBatch.End();
}
}
}
Game1
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace Game2
{
/// <summary>
/// This is the main type for your game.
/// </summary>
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch theSpriteBatch;
public static Rectangle screen;
public static string GameState = "Menu";
MenuManagement menuManagement;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
menuManagement = new MenuManagement();
screen = new Rectangle(0, 0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);
base.Initialize();
}
protected override void LoadContent()
{
theSpriteBatch = new SpriteBatch(GraphicsDevice);
menuManagement.LoadContent(Content);
// TODO: use this.Content to load your game content here
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
switch (GameState)
{
case "Menu":
menuManagement.Update(gameTime);
break;
}
base.Update(gameTime);
}
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
switch (GameState)
{
case "Menu":
menuManagement.Draw(theSpriteBatch);
break;
}
base.Draw(gameTime);
}
}
}
You can calculate the length of the strings and place the next item where you want. You should look to SpriteFont.MeasureString().
https://msdn.microsoft.com/en-us/library/bb464128(v=xnagamestudio.30).aspx
To be clear, the reason they are overlapping is because you are putting them all in the same position:
Vector2 location = position;
and then:
new Vector2 (300, location.Y)
is where you are drawing the entire batch. You need to change the position of each of the menu items. The simplest fix is to increment the Y value of the location for each item. That will move the next menu item toward the bottom. Increment X to move right.
I am new to XNA and found a tutorial online for making a pong like game using it.I am going through the tutorial but I am getting an error even though it is the exact same code.Here is my Game1.cs* 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 WindowsGame1
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Paddle paddle;
Rectangle screenBounds;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
screenBounds = new Rectangle(
0,
0,
graphics.PreferredBackBufferWidth,
graphics.PreferredBackBufferHeight);
}
/// <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()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
Texture2D tempTexture = Content.Load<Texture2D>("paddle");
paddle = new Paddle(tempTexture, screenBounds);
}
/// <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();
paddle.Update();
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)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
paddle.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
I also have this class
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace BreakingOut
{
class Paddle
{
Vector2 position;
Vector2 motion;
float paddleSpeed = 8f;
KeyboardState keyboardState;
GamePadState gamePadState;
Texture2D texture;
Rectangle screenBounds;
public Paddle(Texture2D texture, Rectangle screenBounds)
{
this.texture = texture;
this.screenBounds = screenBounds;
SetInStartPosition();
}
public void Update()
{
motion = Vector2.Zero;
keyboardState = Keyboard.GetState();
gamePadState = GamePad.GetState(PlayerIndex.One);
if (keyboardState.IsKeyDown(Keys.Left))
motion.X = -1;
if (keyboardState.IsKeyDown(Keys.Right))
motion.X = 1;
if (gamePadState.ThumbSticks.Left.X < -.5f)
motion.X = -1;
if (gamePadState.ThumbSticks.Left.X > .5f)
motion.X = 1;
motion.X *= paddleSpeed;
position += motion;
LockPaddle();
}
private void LockPaddle()
{
if (position.X < 0)
position.X = 0;
if (position.X + texture.Width > screenBounds.Width)
position.X = screenBounds.Width - texture.Width;
}
public void SetInStartPosition()
{
position.X = (screenBounds.Width - texture.Width) / 2;
position.Y = screenBounds.Height - texture.Height - 5;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, Color.White);
}
public Rectangle GetBounds()
{
return new Rectangle(
(int)position.X,
(int)position.Y,
texture.Width,
texture.Height);
}
}
}
this code so far is just for creating a paddle that the user can move.I also have an image of the paddle loaded in properly.This is the error it produces:
The type or namespace name 'Paddle' could not be found (are you missing a using directive or an assembly reference?)
This is the part producing this error:
Paddle paddle;
I have done exactly what the tutorial has said to do and it worked for whoever made the tutorial.Any help would be hugely appreciated and if you need more info just ask.Thank you.
The Paddle class is inside the "BreakingOut" namespace, which is not referenced on your Game1 class.
So you can either add the "using BreakingOut" before the Game1 class, or change the namespace of Paddle.
Option 1 would look like this:
using Microsoft.Xna.Framework.Media;
using BreakingOut; // Add the namespace of the object!!!!!
namespace WindowsGame1
Option 2 would be:
using Microsoft.Xna.Framework.Input;
namespace WindowsGame1 // Change the namespace of your object!!!!!
{
class Paddle
{
You need a reference to your Paddle class namespace, but if the Paddle class is in the same project just rename the namespace to WindowsGame1.
as Jason struckholf is saying to change namespace of paddle class
use this code
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace WindowsGame1
{
class Paddle
{
Vector2 position;
Vector2 motion;
float paddleSpeed = 8f;
KeyboardState keyboardState;
GamePadState gamePadState;
Texture2D texture;
Rectangle screenBounds;
public Paddle(Texture2D texture, Rectangle screenBounds)
{
this.texture = texture;
this.screenBounds = screenBounds;
SetInStartPosition();
}
public void Update()
{
motion = Vector2.Zero;
keyboardState = Keyboard.GetState();
gamePadState = GamePad.GetState(PlayerIndex.One);
if (keyboardState.IsKeyDown(Keys.Left))
motion.X = -1;
if (keyboardState.IsKeyDown(Keys.Right))
motion.X = 1;
if (gamePadState.ThumbSticks.Left.X < -.5f)
motion.X = -1;
if (gamePadState.ThumbSticks.Left.X > .5f)
motion.X = 1;
motion.X *= paddleSpeed;
position += motion;
LockPaddle();
}
private void LockPaddle()
{
if (position.X < 0)
position.X = 0;
if (position.X + texture.Width > screenBounds.Width)
position.X = screenBounds.Width - texture.Width;
}
public void SetInStartPosition()
{
position.X = (screenBounds.Width - texture.Width) / 2;
position.Y = screenBounds.Height - texture.Height - 5;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, Color.White);
}
public Rectangle GetBounds()
{
return new Rectangle(
(int)position.X,
(int)position.Y,
texture.Width,
texture.Height);
}
}
}
I have 3 classes: a game class, a camera class and a model class. The project builds and runs,
the model appears, when i press w and make it go forward the camera follows it, but when i restart the project and rotate the model to face any other ways it seems to do a nose dive, and not go stright, what im trying to achieve is a camera which follows the model,
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 test1
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
//Visual components
Ship ship = new Ship();
Camera _camera;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
// this.graphics.ToggleFullScreen();
this._camera = new Camera(graphics.GraphicsDevice.Viewport);
this._camera.LookAt = new Vector3(0.0f, 0.0f, 0.0f);
this._camera.Position = new Vector3(0.0f, -5000.0f, 1000.0f);
base.Initialize();
}
protected override void LoadContent()
{
ship.Model = Content.Load<Model>("Models/p1_wedge");
ship.Transforms = _camera.SetupEffectDefaults(ship.Model);
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
// Get some input.
UpdateInput();
base.Update(gameTime);
}
protected void UpdateInput()
{
// Get the game pad state.
GamePadState currentState = GamePad.GetState(PlayerIndex.One);
KeyboardState currentKeyState = Keyboard.GetState();
ship.Update(currentState);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
//camera
this._camera.Update();
_camera.LookAt = ship.Position;
Matrix shipTransformMatrix = ship.RotationMatrix
* Matrix.CreateTranslation(ship.Position);
DrawModel(ship.Model, shipTransformMatrix, ship.Transforms);
base.Draw(gameTime);
}
public void DrawModel(Model model, Matrix modelTransform,
Matrix[] absoluteBoneTransforms)
{
//Draw the model, a model can have multiple meshes, so loop
foreach (ModelMesh mesh in model.Meshes)
{
//This is where the mesh orientation is set
foreach (BasicEffect effect in mesh.Effects)
{
effect.World =
absoluteBoneTransforms[mesh.ParentBone.Index] *
modelTransform;
effect.Projection = _camera.ProjectionMatrix;
effect.View = _camera.ViewMatrix;
}
//Draw the mesh, will use the effects set above.
mesh.Draw();
}
}
}
}
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 test1
{
public class Camera
{
private Vector3 _position;
private Vector3 _lookAt;
private Matrix _viewMatrix;
private Matrix _projectionMatrix;
private float _aspectRatio;
public Camera(Viewport viewport)
{
this._aspectRatio = ((float)viewport.Width) / ((float)viewport.Height);
this._projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(40.0f),
this._aspectRatio,
1.0f,
10000.0f);
}
public Matrix[] SetupEffectDefaults(Model myModel)
{
Matrix[] absoluteTransforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(absoluteTransforms);
foreach (ModelMesh mesh in myModel.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.Projection = ProjectionMatrix;
effect.View = ViewMatrix;
}
}
return absoluteTransforms;
}
public Vector3 Position
{
get { return this._position; }
set { this._position = value; }
}
public Vector3 LookAt //= Vector3.Zero;
{
get { return this._lookAt; }
set { this._lookAt = value; }
}
public Matrix ViewMatrix
{
get { return this._viewMatrix; }
}
public Matrix ProjectionMatrix
{
get { return this._projectionMatrix; }
}
public void Update()
{
this._viewMatrix =
Matrix.CreateLookAt(this._position, this._lookAt, Vector3.Up);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace test1
{
class Ship
{
public Model Model;
public Matrix[] Transforms;
//Position of the model in world space
public Vector3 Position = Vector3.Zero;
//Velocity of the model, applied each frame to the model's position
public Vector3 Velocity = Vector3.Zero;
private const float VelocityScale = 5.0f;
public Matrix RotationMatrix =
Matrix.CreateRotationX(MathHelper.PiOver2);
private float rotation;
public float Rotation
{
get { return rotation; }
set
{
float newVal = value;
while (newVal >= MathHelper.TwoPi)
{
newVal -= MathHelper.TwoPi;
}
while (newVal < 0)
{
newVal += MathHelper.TwoPi;
}
if (rotation != value)
{
rotation = value;
RotationMatrix =
Matrix.CreateRotationX(MathHelper.PiOver2) *
Matrix.CreateRotationZ(rotation);
}
}
}
public void Update(GamePadState controllerState)
{
KeyboardState currentKeyState = Keyboard.GetState();
if (currentKeyState.IsKeyDown(Keys.A))
Rotation += 0.10f;
else
// Rotate the model using the left thumbstick, and scale it down.
Rotation -= controllerState.ThumbSticks.Left.X * 0.10f;
if (currentKeyState.IsKeyDown(Keys.D))
Rotation -= 0.10f;
if (currentKeyState.IsKeyDown(Keys.W))
Velocity += RotationMatrix.Forward * VelocityScale;
else
// Finally, add this vector to our velocity.
Velocity += RotationMatrix.Forward * VelocityScale *
controllerState.Triggers.Right;
// In case you get lost, press A to warp back to the center.
if (currentKeyState.IsKeyDown(Keys.Enter))
{
Position = Vector3.Zero;
Velocity = Vector3.Zero;
Rotation = 0.0f;
}
Position += Velocity;
Velocity *= 0.95f;
}
}
}
I'd do it this way:
I'm showing it in a plane to easy understanding, but it's not needed to do the calcs.
You only need a forward vector for the camera, a forward vector for the ship, a distance from the camera to the ship and an elevation vector for the camera.
this way when ship moves would do something similar to this:
Camera.Forward = Vector3.Lerp( Ship.Forward, Camera.Fordward, 0.05f);
Camera.Forward.Normalize();
Camera.Forward*=Camera.Distance;
Camera.Target = Ship.Target;
Camera.Source = Ship.Target - Camera.Forward;
Camera.Position = Camera.Source + Camera.Elevation;
I hope this will be useful.
I am trying to make a game and I want "enemies" or meteors to spawn from the right side and going to the left side. I am working on some code and it seems to be working pretty good but the respawning fails. They end up spawning one and one REALLY slow and then after a while they don't spawn at all. All help would be really appreciated.
Here's my 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 WindowsGame2
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
List<Enemies> enemies = new List<Enemies>();
Random random = new Random();
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
}
protected override void UnloadContent()
{
}
float spawn = 0;
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
spawn += (float)gameTime.ElapsedGameTime.TotalSeconds;
foreach (Enemies enemy in enemies)
{
enemy.Update(graphics.GraphicsDevice);
}
LoadEnemies();
base.Update(gameTime);
}
public void LoadEnemies()
{
int randY = random.Next(100, 400);
if (spawn > 1)
{
spawn = 0;
if (enemies.Count() < 10)
enemies.Add(new Enemies(Content.Load<Texture2D>("meteor"), new Vector2(1110, randY)));
}
for (int i = 0; i < enemies.Count; i++)
{
if (!enemies[i].isVisible)
{
enemies.RemoveAt(i);
i--;
}
}
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
foreach (Enemies enemy in enemies)
{
enemy.Draw(spriteBatch);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}
and here's my class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
namespace WindowsGame2
{
class Enemies
{
public Texture2D texture;
public Vector2 position;
public Vector2 velocity;
public bool isVisible = true;
Random random = new Random();
int randX, randY;
public Enemies(Texture2D newTexture, Vector2 newPosition)
{
texture = newTexture;
position = newPosition;
randX = random.Next(-4, 4);
randY = random.Next(-4, -1);
velocity = new Vector2(randX, randY);
}
public void Update(GraphicsDevice graphics)
{
position += velocity;
if (position.Y <= 0 || position.Y >= graphics.Viewport.Height - texture.Height)
{
velocity.Y = -velocity.Y;
}
if (position.X < 0 - texture.Width)
{
isVisible = false;
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, Color.White);
}
}
}
Your problem lies here. Some of your meteors are moving right and some are not moving at all.
randX = random.Next(-4, 4);
Try using
randX = random.Next(-4, -1);
Your enemies/meteors sometimes had a velocity on the X that was between 0 and 4, so they moved right.
I can see you changed the Y to this, maybe you got them mixed up?