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.
Related
I am currently coding an arkanoid type game for my school project and just started out on monogame. I encountered a collision problem on the big red rectangle and the ball. I just cant figure out what is wrong with my code I appreciate all of your help in advance.
Collision Video: https://youtu.be/HOuUS8bUKn4
Game1.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
namespace TSA3
{
public class Game1 : Game
{
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
// Platform
Platform platform;
Texture2D platformTexture;
Rectangle platformRectangle;
Color platformColor;
// Ball
Ball ball;
Texture2D ballTexture;
Rectangle ballRectangle;
Color ballColor;
bool ballDirectionX = true, ballDirectionY = true;
// Enemy
Enemy enemy;
Texture2D enemyTexture;
Rectangle enemyRectangle;
Color enemyColor;
Random random = new Random();
public const int ScreenW = 1200, ScreenH = 720;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void Initialize()
{
graphics.PreferredBackBufferWidth = ScreenW;
graphics.PreferredBackBufferHeight = ScreenH;
graphics.ApplyChanges();
Window.AllowUserResizing = false;
Window.AllowAltF4 = true;
Window.Title = "Arkanoid";
// Platform
platformTexture = Content.Load<Texture2D>("platform");
platformRectangle = new Rectangle(0, Window.ClientBounds.Height - 50, 100, 30);
platformColor = Color.White;
// Ball
ballTexture = Content.Load<Texture2D>("ball");
ballRectangle = new Rectangle(0, 0, 20, 20);
ballColor = Color.DarkBlue;
// Enemy
enemyTexture = Content.Load<Texture2D>("enemyPiece");
enemyRectangle = new Rectangle(Window.ClientBounds.Width / 2, Window.ClientBounds.Height / 2, 200, 200);
enemyColor = Color.White;
base.Initialize();
}
protected override void LoadContent()
{
// Player
platform = new Platform(platformTexture, platformRectangle, platformColor, Window.ClientBounds.Width - 100);
// Ball
ball = new Ball(ballTexture, ballRectangle, ballColor, Window.ClientBounds.Width - 20, Window.ClientBounds.Height - 20, ballDirectionX, ballDirectionY);
// Enemy
enemy = new Enemy(enemyTexture, enemyRectangle, enemyColor);
spriteBatch = new SpriteBatch(GraphicsDevice);
}
float spawn = 0;
protected override void Update(GameTime gameTime)
{
spawn += (float)gameTime.ElapsedGameTime.TotalSeconds;
ball.ballBounce(platform.PlatformRectangle);
Keys[] k = Keyboard.GetState().GetPressedKeys();
foreach (Keys key in k)
{
platform.platformMovement(key);
break;
}
if (Keyboard.GetState().IsKeyDown(Keys.Space) && !ball.StartGame)
ball.StartGame = true;
ball.ballCollision(platform.PlatformRectangle);
ball.enemyCollision(enemy.enemyRectangle);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(ball.BallTexture, ball.BallRectangle, ball.BallColor);
spriteBatch.Draw(platform.PlatformTexture, platform.PlatformRectangle, platform.PlatformColor);
spriteBatch.Draw(enemy.enemyTexture, enemy.enemyRectangle, enemy.enemyColor);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Ball.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Text;
namespace TSA3
{
public class Ball
{
Texture2D ballTexture;
Rectangle ballRectangle;
Color ballColor;
int boundaryX, boundaryY;
bool ballDirectionX, ballDirectionY;
bool startGame;
public const int BALL_SPEED = 7;
public Ball(Texture2D ballTexture, Rectangle ballRectangle, Color ballColor, int boundaryX, int boundaryY, bool ballDirectionX, bool ballDirectionY)
{
this.ballTexture = ballTexture;
this.ballRectangle = ballRectangle;
this.ballColor = ballColor;
this.boundaryX = boundaryX;
this.boundaryY = boundaryY;
this.ballDirectionX = ballDirectionX;
this.ballDirectionY = ballDirectionY;
startGame = false;
}
public Texture2D BallTexture { get => ballTexture; }
public Rectangle BallRectangle { get => ballRectangle; }
public Color BallColor { get => ballColor; }
public bool StartGame { get => startGame; set => startGame = value; }
public void ballBounce(Rectangle platformRectangle)
{
if (startGame)
{
if (ballRectangle.X <= 0)
ballDirectionX = true;
else if (ballRectangle.X >= boundaryX)
ballDirectionX = false;
if (ballRectangle.Y <= 0)
{
ballDirectionY = true;
}
else if (ballRectangle.Y >= boundaryY)
{
startGame = false;
}
if (ballDirectionX)
ballRectangle.X += BALL_SPEED;
else
ballRectangle.X -= BALL_SPEED;
if (ballDirectionY)
ballRectangle.Y += BALL_SPEED;
else
ballRectangle.Y -= BALL_SPEED;
}
else
{
ballRectangle.Location = new Point(platformRectangle.X + (platformRectangle.Width / 2) - 10, platformRectangle.Y - (ballRectangle.Height - 5));
}
}
public void ballCollision(Rectangle platform)
{
if (ballRectangle.Intersects(platform))
ballDirectionY = false;
}
public void enemyCollision(Rectangle enemyRectangle)
{
if (ballRectangle.Intersects(enemyRectangle))
ballDirectionY = false;
}
}
}
Enemy.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Text;
namespace TSA3
{
public class Enemy
{
public Texture2D enemyTexture;
public Rectangle enemyRectangle;
public Color enemyColor;
public bool isVisible = true;
Random random = new Random();
public Enemy(Texture2D enemyTexture, Rectangle enemyRectangle, Color enemyColor)
{
this.enemyTexture = enemyTexture;
this.enemyRectangle = enemyRectangle;
this.enemyColor = enemyColor;
}
public Texture2D EnemyTexture { get => enemyTexture; }
public Rectangle EnemyRectangle { get => enemyRectangle; }
public Color EnemyColor { get => enemyColor; }
}
}
Platform.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Text;
namespace TSA3
{
public class Platform
{
Texture2D platformTexture;
Rectangle platformRectangle;
Color platformColor;
int boundaryX;
public const int PLATFORM_SPEED = 10;
public Platform(Texture2D platformTexture, Rectangle platformRectangle, Color platformColor, int boundaryX)
{
this.platformTexture = platformTexture;
this.platformRectangle = platformRectangle;
this.platformColor = platformColor;
this.boundaryX = boundaryX;
}
public Texture2D PlatformTexture { get => platformTexture; }
public Rectangle PlatformRectangle { get => platformRectangle; }
public Color PlatformColor { get => platformColor; }
public void platformMovement(Keys controls)
{
if (controls == Keys.A && platformRectangle.X > 0)
platformRectangle.X -= PLATFORM_SPEED;
if (controls == Keys.D && platformRectangle.X < boundaryX)
platformRectangle.X += PLATFORM_SPEED;
}
}
}
Thank you in advance to anyone who will help!
This method is missing the necessary code to function properly to approach the block from any side:
public void enemyCollision(Rectangle enemyRectangle)
{
if (ballRectangle.Intersects(enemyRectangle))
ballDirectionY = false;
}
Currently it only works the same as your platform does: set the Y direction upwards on collision. This works fine for the platform, as it's thin and close to the edge of the screen, so it doesn't need other collision checks.
Try improving this method similair with what you've done with the ball collisions on the edges of the screen.
What would be important here, is knowing the positions of the corners of the red rectangle, so you can calculate at which position the ball is hitting the rectangle.
As far I know, you cannot have the exact borders, but you can measure the same with calculating the positions of the corners. you could for example take the EnemyRectangle and get their x/y position, that would be it's top-left, than you can add the rectangle's width, and you'll have the top-right (same also works with the height for the bottom corners). If you calculate the balls position along with the rectangle corners, you'll know at which side the ball is colliding with the screen.
An example of a collision on top:
public void enemyCollision(Rectangle enemyRectangle)
{
if (ballRectangle.Intersects(enemyRectangle))
{
if (ballRectangle.x > enemyRectangle.x &&
ballRectangle.x < enemyRectangle.x + enemyRectangle.Width &&
ballRectangle.y > enemyRectangle.y)
ballDirectionY = false;
}
}
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.
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.
I'm a complete newbie at XNA and I am currently learning from this tutorial:
http://msdn.microsoft.com/en-us/library/bb203893.aspx
The problem occurs when running the program after completion of step five. I don't think it's a typo as others have pointed out the same problem in the comments.
My sprite is meant to bounce around the screen automatically when my program is run, however is does not move even a pixel from 0,0.
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
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
Texture2D myTexture;
Vector2 spritePosition = Vector2.Zero;
Vector2 spriteSpeed = new Vector2(50.0f, 50.0f);
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
myTexture = Content.Load<Texture2D>("Main");
}
protected override void UnloadContent()
{
}
void UpdateSprite(GameTime gameTime)
{
//Move the sprite by speed, scaled by elapsed time
spritePosition +=
spriteSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;
int MaxX =
graphics.GraphicsDevice.Viewport.Width - myTexture.Width;
int MinX = 0;
int MaxY =
graphics.GraphicsDevice.Viewport.Height - myTexture.Height;
int MinY = 0;
//Check for bounce.
if (spritePosition.X > MaxX)
{
spriteSpeed.X *= -1;
spritePosition.X = MaxX;
}
else if (spritePosition.X < MinX)
{
spriteSpeed.X *= -1;
spritePosition.X = MinX;
}
if (spritePosition.Y > MaxY)
{
spriteSpeed.Y *= -1;
spritePosition.Y = MaxY;
}
else if (spritePosition.Y < MinY)
{
spriteSpeed.Y *= -1;
spritePosition.Y = MinY;
}
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
spriteBatch.Draw(myTexture, spritePosition, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
UpdateSprite method is not called from anywhere...
You should override the Update method and call your UpdateSprite method from there...
EDIT:
Add this to your game class:
protected override void Update(GameTime gameTime)
{
UpdateSprite(gameTime);
}
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?