How to rotate static model in XNA? - c#

How would I rotate a static model in XNA? The model is loaded into a separate class called 'ModelManager':
I needed to rotate the model called 'track_new' but it is stored as a whole with other models. Would the rotation go under the 'modelManager' class or the main 'Game!.cs' file?
Here is my code:
public class ModelManager : DrawableGameComponent
{
List<BasicModel> models = new List<BasicModel>();
public ModelManager(Game game) : base(game) { }
public override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
models.Add(new BasicModel(Game.Content.Load<Model>(#"Models\track_new")));
base.LoadContent();
}
public override void Update(GameTime gameTime)
{
for (int i = 0; i < models.Count; ++i)
models[i].Update();
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
foreach (BasicModel bm in models)
bm.Draw(((Game1)Game).camera);
base.Draw(gameTime);
}
}

The Model.Draw method accepts a World and a View matrix - you should be able to specify a different World matrix for that model alone to achieve the effect required.

Related

C# ArgumentNullException was unhandled (SpriteBatch.Draw)

I am actually a new student in XNA, finding this library very interesting, but I still lack some knowledge to go further as I felt on a issue I can't fix on my own :(
The spriteBatch.Draw() method says my texture is null, however I have loaded it in a Resources.cs class and passed the texture in MainMenu.cs, so I don't really know where the problem resides, if anybody could help me about that I would be very thankful !
Resources.cs
class Resources
{
public static Texture2D pixel;
public static Texture2D startButton, loadButton, quitButton;
public static SpriteFont consoleFont;
public static void LoadContent(ContentManager Content)
{
pixel = Content.Load<Texture2D>("Pixel");
consoleFont = Content.Load<SpriteFont>("Console");
// UI Ressources :
startButton = Content.Load<Texture2D>("UI/StartButton");
loadButton = Content.Load<Texture2D>("UI/LoadButton");
quitButton = Content.Load<Texture2D>("UI/QuitButton");
}
}
MainMenu.cs
class MainMenu
{
// Fields
List<Button> buttons = new List<Button>();
// Constructors
public MainMenu()
{
this.buttons.Add(new Button(new Vector2(480, 132), 256, 48, Resources.startButton));
this.buttons.Add(new Button(new Vector2(480, 212), 256, 48, Resources.loadButton));
this.buttons.Add(new Button(new Vector2(480, 292), 256, 48, Resources.quitButton));
}
// Methods
// Update
public void Update()
{
}
// Draw
public void Draw(SpriteBatch spriteBatch)
{
foreach (Button button in buttons)
{
button.Draw(spriteBatch);
}
}
}
Button.cs
class Button : UIElement
{
int width, height;
Texture2D texture;
public Button()
{
}
public Button(Vector2 b_position, int b_width, int b_height, Texture2D b_texture)
{
this.position = b_position;
this.width = b_width;
this.height = b_height;
this.texture = b_texture;
}
public void Update()
{
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, Color.White);
}
}
Simple realy
You just have to know the calling order of functions of Game1. First, Game1 constructor is called. That's where you've put mainMenu = new MainMenu();. After that go Initialize, Load and so on. You have to move mainMenu = new MainMenu(); from Game1 constructor to Load function, after the Resources.LoadContent(Content);, so the resources can be loaded before they are used in MainMenu. Your Game1.cs code should look like this:
public class GameMain : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
MainMenu mainMenu;
public GameMain()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
this.IsMouseVisible = true;
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
Resources.LoadContent(Content);
mainMenu = new MainMenu();
}
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)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
mainMenu.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
While I do not see your Game class my first assumption is that your never calling the public static void LoadContent(ContentManager Content) method inside your Resources class. Since this function is instantiating your textures perhaps this isn't being called.
Thank you for your reply !
Indeed I forgot to include the Game class, is this the right way to call the resources ?
public class GameMain : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
MainMenu mainMenu;
public GameMain()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
this.IsMouseVisible = true;
mainMenu = new MainMenu();
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
Resources.LoadContent(Content);
}
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)
this.Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
mainMenu.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}

State Design pattern and infinite loops with MonoGame

I am trying to use state design pattern with my game(MonoGame game).I want to detect collision , so I give cell type and upon it gives me a specific action.But unfortunately this implementation gives infinite loop "Exception.StackOverflow" in player instances.
abstract class PlayerState
{
abstract public void doAction(Player player );
}
Classes implements PlayerState
class DeadState:PlayerState
{
public override void doAction(Player player)
{
player.dead();
player.setState(this);
}
}
class IncreaseGold: PlayerState
{
public override void doAction(Player player)
{
player.increaseGold();
player.setState(this);
}
}
Player.cs
public void setState(PlayerState state) { this.state = state; }
public PlayerState getState() { return state; }
ActionController.cs
Player player = new Player();
public void passCell(int cellType)
{
if (cellType == 1)
{
new DeadState().doAction(player);
}
if (cellType == 2)
{
new IncreaseGold().doAction(player);
}
}
finally in my Update method on Game1.cs
protected override void Update(GameTime gameTime)
{
player.passCell(cellType);
base.Update(gameTime);
}

C# XNA Add a GameComponent from within a GameComponent

public class Menu : DrawableGameComponent
{
ContentManager Content;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Audio MenuMusic;
public Menu(Game game) : base(game)
{
spriteBatch = Game.Services.GetService(typeof(SpriteBatch)) as SpriteBatch;
graphics = Game.Services.GetService(typeof(GraphicsDeviceManager)) as GraphicsDeviceManager;
Content = game.Content;
Content.RootDirectory = #"Content\Menu\";
*MenuMusic = new Audio(game);* // Instantiate the new DrawableGameComponent
Game.Components.Add(this);
MenuMusic.PauseTune = false;
}
public override void Initialize()
{
Menustate = MenuState.LoadContent;
base.Initialize();
}
protected override void LoadContent()
{
base.LoadContent();
}
protected override void UnloadContent()
{
base.UnloadContent();
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
}
}
public class Audio : DrawableGameComponent
{
public bool PauseTune
{
get { return PauseTune; }
set { PauseTune = value; }
}
SoundEffect Tune = null;
SoundEffectInstance SFXInstance;
public Audio(Game game) : base(game)
{
*game.Components.Add(this)*;// This is the problem. It adds an entirely new Game object. :(
}
public override void Initialize()
{
PauseTune = true;
base.Initialize();
}
protected override void LoadContent()
{
switch (Game1.Gamestate)
{
case GameState.Menu:
string AudioPath = #"Audio\";
Tune = Game.Content.Load<SoundEffect>(AudioPath + "Tune");
break;
case GameState.InitialiseGame:
break;
case GameState.PlayGame:
break;
default:
break;
}
if (Tune != null) SFXInstance = Tune.CreateInstance();
base.LoadContent();
}
protected override void UnloadContent()
{
base.UnloadContent();
}
public override void Update(GameTime gameTime)
{
if (Tune != null)
{
if (PauseTune)
{
if (SFXInstance.State == SoundState.Playing)
SFXInstance.Pause();
}
else
{
if (SFXInstance.State != SoundState.Playing)
SFXInstance.Play();
}
}
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
}
}
The probelem comes when I use the Menu to add a new Audio class instance.
The Audio constructor attempts to add the new GameCompent but fails.
What it actually does is create an entirely new Game instance, which then goes on to instantiate a new Menu that attempts to add a new Audio class instance..... Until I eventually get a - would you beleive? - stackoverflow error.
What am I doing wrong? / How can I add one component from within another?
DOH! Some days I should never turn on my computer :)
Or better yet - after a long, tiring day do NOT mess with mycode.
A self-referencing PauseTune property.

Error with constructor when inheriting using a base class

Hey im new to c# and XNA. My goal is to inherit from a Sprite class and make classes such as pongSprite, paddleSprite etc... Im getting an error on my constructor. I have extended the sprite class and i have put the variables and objects from the Sprite class into the :base()
Here is my code:
**
Sprite.cs
**
namespace SimplePong
{
/// <summary>
/// This is a game component that implements IUpdateable.
/// </summary>
public class Sprite : DrawableGameComponent
{
protected string id;
protected Texture2D texture;
//bounding box
//protected Rectangle sourceRectangle;
protected Rectangle destinationRectangle;
protected Color color;
protected Main game;
private Sprite pongBall;
public Sprite(Main game, string id, Texture2D texture,
Rectangle destinationRectangle, Color color)
: base(game)
{
this.game = game;
this.id = id;
this.texture = texture;
this.destinationRectangle = destinationRectangle;
this.color = color;
}
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public override void Initialize()
{
// TODO: Add your initialization code here
base.Initialize();
}
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
game.spriteBatch.Begin();
game.spriteBatch.Draw(texture, destinationRectangle, color);
game.spriteBatch.End();
base.Draw(gameTime);
}
}
}
**
ballSprite.cs
**
using Microsoft.Xna.Framework;
namespace SimplePong
{
public class BallSprite : Sprite
{
// public Main game;
public Sprite pongBall;
public BallSprite()
: base(Main game, string id, Texture2D texture,
Rectangle destinationRectangle, Color color)
{
}
public override void Initialize()
{
base.Initialize();
}
public override void Update(GameTime gameTime)
{
destinationRectangle.X += 2;
destinationRectangle.Y += 2;
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
}
}
}
The syntax of the constructor your inherited class is wrong. I suspect you want:
public BallSprite(Main game, string id, Texture2D texture,
Rectangle destinationRectangle, Color color)
: base(game, id, texture, destinationRectangle, color)
{
}
If you want a parameterless constructor then you're going to have to come up with the values for the parameters yourself (or not call the base constructor).

'particleEngine' being drawn against a vector

I'm using XNA and C#.
I have a problem with calling a vector variable from my particleEmitter. I can draw the particle just fine if it is static or not moving. And when I have a vector variable that is set to a fixed position of (x,y) it's okay and draws on the screen. But if I have a vector variable that has been set to move in the x or y axis it does not draw at all.
Declared variables:
Vector2 shipPos;
float shipMovement;
ParticleEngine particleEngine;
And a method that loads stuff about what should happen with the vectors and the way it should behave:
public void loadEmitter(GameTime gameTime)
{
shipMovement = 2f;
shipPos.Y -= shipMovement;
particleEngine.EmitterLocation = new Vector2(shipPos.X,shipPos.Y);
}
I'm trying to get particleEngine to trail the movement of a ship. What I can't seem to do is get it to draw when I set this up to happen.
Other info: ParticleEngine is a class in itself and basically sets some parameters about how the particles I will be drawing should behave. I have other screens with the spritebatch Begin and End calls. Other than that, here's the code for my main class:
namespace PlanetDrill2
{
class LaunchScreen : Screen
{
Texture2D LaunchScreenTexture;
Texture2D shipLaunch;
Vector2 shipPos;
float shipMovement;
ParticleEngine particleEngine;
Vector2 smokePos;
public LaunchScreen(Game game, SpriteBatch batch, ChangeScreen changeScreen)
: base(game, batch, changeScreen)
{
}
protected override void SetupInputs()
{
base.SetupInputs();
}
public override void Activate()
{
base.Activate();
}
public void LaunchShip()
{
}
public void loadEmitter(GameTime gameTime)
{
shipMovement = 2f;
shipPos.Y -= shipMovement;
particleEngine.EmitterLocation = new Vector2(shipPos.X,shipPos.Y);
}
protected override void LoadScreenContent(ContentManager content)
{
LaunchScreenTexture = content.Load<Texture2D>("launchTest");
shipLaunch = content.Load<Texture2D>("shipLaunch");
List<Texture2D> textures = new List<Texture2D>();
textures.Add(content.Load<Texture2D>("smoketexture"));
particleEngine = new ParticleEngine(textures, new Vector2(0, 0));
base.LoadScreenContent(content);
}
protected override void UpdateScreen(GameTime gameTime, DisplayOrientation screenOrientation)
{
//if (gameTime.TotalGameTime.Seconds>10)
//{
// changeScreenDelegate(ScreenState.UMA);
//}
loadEmitter(gameTime);
particleEngine.Update();
base.UpdateScreen(gameTime, screenOrientation);
}
protected override void DrawScreen(SpriteBatch batch, DisplayOrientation screenOrientation)
{
batch.Draw(LaunchScreenTexture, Vector2.Zero, Color.White);
batch.Draw(shipLaunch, new Vector2(80, 450) +shipPos, Color.White);
particleEngine.Draw(batch);
base.DrawScreen(batch, screenOrientation);
}
protected override void SaveScreenState()
{
base.SaveScreenState();
}
} // end class LaunchScreen
} // end namespace PlanetDrill2
From here
batch.Draw(shipLaunch, new Vector2(80, 450) +shipPos, Color.White);
particleEngine.Draw(batch);
It looks like you are drawing the ship relative to [80, 450], but you are not applying this offset to the particleEngine.

Categories