I know this question has been asked many times before. However, all solutions I have found after over an hour of googling are essentially the same thing. Everyone says that in order to resize a window in XNA you simply add the following lines of code(or some slight variation of these lines of code) to your Initiate() method in the Game1 class:
//A lot of people say that the ApplyChanges() call is not necessary,
//and equally as many say that it is.
graphics.IsFullScreen = false;
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
graphics.ApplyChanges();
This does not work for me. The code compiles, and runs, but absolutely nothing changes. I've been scouring the documentation for the GraphicsDevice and GraphicsDeviceManager classes, but I have been unable to find any information indicating that I need to do anything other than the above.
I am also fairly sure my graphics card is sufficient(ATI HD 5870), although it appears that the wiki entry on XNA graphics card compatibility has not been updated for a while.
I'm running on Windows 7, with the above graphics card, Visual C# 2010 Express, and the latest version of XNA.
So I'm just hoping that someone can help me find where I am messing up. I will post my entire Game1 class(I renamed it MainApp) below. If anyone would like to see any of the other classes that are called on, ask and I'll post them.
public class MainApp : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Player player;
public MainApp()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
player = new Player();
//This does not do ANYTHING
graphics.IsFullScreen = false;
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
graphics.ApplyChanges();
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
Vector2 playerPosition = new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X,
GraphicsDevice.Viewport.TitleSafeArea.Y
+ 2*(graphics.GraphicsDevice.Viewport.TitleSafeArea.Height / 3));
player.Initialize(Content.Load<Texture2D>("basePlayerTexture"),
playerPosition);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
player.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
P.S. This is my second day with C#, so if this is due to a really stupid error I apologize for wasting your time.
It is frustrating that (as you say) "A lot of people say that the ApplyChanges() call is not necessary, and equally as many say that it is" -- the fact of the matter is that it depends on what you are doing and where you are doing it!
(How do I know all this? I've implemented it. See also: this answer.)
When you are setting the initial resolution when your game starts up:
Do this in your constructor (obviously if you rename Game1, do it in your renamed constructor!)
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferHeight = 600;
graphics.PreferredBackBufferWidth = 800;
}
// ...
}
And do not touch it during Initialize()! And do not call ApplyChanges().
When Game.Run() gets called (the default template project calls it in Program.cs), it will call GraphicsDeviceManager.CreateDevice to set up the initial display before Initialize() is called! This is why you must create the GraphicsDeviceManager and set your desired settings in the constructor of your game class (which is called before Game.Run()).
If you try to set the resolution in Initialize, you cause the graphics device to be set up twice. Bad.
(To be honest I'm surprised that this causes such confusion. This is the code that is provided in the default project template!)
When you are modifying the resolution while the game is running:
If you present a "resolution selection" menu somewhere in your game, and you want to respond to a user (for example) clicking an option in that menu - then (and only then) should you use ApplyChanges. You should only call it from within Update. For example:
public class Game1 : Microsoft.Xna.Framework.Game
{
protected override void Update(GameTime gameTime)
{
if(userClickedTheResolutionChangeButton)
{
graphics.IsFullScreen = userRequestedFullScreen;
graphics.PreferredBackBufferHeight = userRequestedHeight;
graphics.PreferredBackBufferWidth = userRequestedWidth;
graphics.ApplyChanges();
}
// ...
}
// ...
}
Finally, note that ToggleFullScreen() is the same as doing:
graphics.IsFullScreen = !graphics.IsFullScreen;
graphics.ApplyChanges();
The GraphicsDevice.Viewport width and height by default on my computer is 800x480, try setting a size above that that will be noticeable - like 1024x768.
graphics.PreferredBackBufferHeight = 768;
graphics.PreferredBackBufferWidth = 1024;
graphics.ApplyChanges();
The above code in Initialize was sufficient to expand the window for me.
Related
I just want to add a background image in my c# monogame main menu. I already have a main menu with buttons and a working game. Just the background is missing.
This is a part of my code:
public void LoadAssets()
{
background = ScreenManager.Texture("background");
[...] //unimportant stuff for this problem
}
public void Draw(GameTime gameTime)
{
SpriteBatch spriteBatch= new SpriteBatch();
spriteBatch.Begin();
spriteBatch.Draw(background, new Rectangle(0, 0, 800, 480), Color.White);
spriteBatch.End();
foreach (var button in mButtons)
{
button.Draw(ScreenManager.mSprites);
}
}
I get the following error CS7036 C# There is no argument given that corresponds to the required formal parameter of "graphicsDevice" from "SpriteBatch.SpriteBatch(GraphicsDevice).
I included the image in content. I don't know where is my error.
Thanks, for help!
First, you do NOT create a new SpriteBatch instance each draw call. That would be like 60 new instances per second (at 60fps)
Instead, you create it in your LoadContent() method and use it all the way in your Draw()
method:
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
[...]
}
Second, GraphicsDevice is definetly available in your Draw-Call as long as you have not messed something up really bad ;)
I'm coming back to make a game with XNA, but I got an issue.
When I use IsFullScreen from my GraphicsDeviceManager and put it to true in the Game contructor, my game doesn't go to full screen, it's staying windowed.
I looked for the value of IsFullScreen, and while I'm in the Game constructor its value is true, but when I look at the value in the Update or Draw the valoue is false.
I tried to put the value to true when I press F, but nothing changed.
I also tried to use ToggleFullScreen, the value of IsFullScreen is well changed but nothing is happening.
I tried to set the PreferredBackBuffer width and height, then I need to use ApplyChanges and it put IsFullScreen to false every time I call it. Even if it changes the window size, it's not in full screen, so not what I want.
Here is my code, tell me if you see anything, any advice is welcome.
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 MyGames
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class SpaceInvader : Game
{
private readonly GraphicsDeviceManager graphics_;
private KeyboardState oldKeyboardState_;
private KeyboardState newKeyboardState_;
private SpriteBatch spriteBatch_;
private Ship playerShip_;
public SpaceInvader()
{
graphics_ = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
// Set device frame rate to 60 fps.
TargetElapsedTime = TimeSpan.FromSeconds(1 / 60.0);
graphics_.PreferredBackBufferWidth = 480;
graphics_.PreferredBackBufferHeight = 268;
}
protected override void Initialize()
{
playerShip_ = new Ship(new Vector2(Window.ClientBounds.Width / 2, Window.ClientBounds.Height - 150), new Vector2(10,10));
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch_ = new SpriteBatch(GraphicsDevice);
playerShip_.LoadContent(Content);
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
newKeyboardState_ = Keyboard.GetState();
// Allows the game to exit
if (newKeyboardState_.IsKeyDown(Keys.Escape))
Exit();
// TODO: Add your update logic here
playerShip_.Update(Window, newKeyboardState_, oldKeyboardState_);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
if (oldKeyboardState_.IsKeyDown(Keys.F) && newKeyboardState_.IsKeyUp(Keys.F))
graphics_.ToggleFullScreen();
graphics_.GraphicsDevice.Clear(Color.CornflowerBlue);
//set rendering back to the back buffer
// Draw the sprite.
spriteBatch_.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
playerShip_.Draw(spriteBatch_);
spriteBatch_.End();
base.Draw(gameTime);
oldKeyboardState_ = newKeyboardState_;
}
}
}
I'm using Windows 7, and VisualStudio Ultimate 2012.
EDIT1:
I just tried with VisualStudio 2010 and it works perfectly.
I've also noticed another issue I had before, in the Program.cs I cannot use:
using (SpaceInvader game = new SpaceInvader())
{
game.Run();
}
I need to use instead:
SpaceInvader game = new SpaceInvader();
game.Run();
I don't know if it's changing something but it will throw me the exception NullReferenceException was unhandled on the second brace.
EDIT2:
I read on the download page of XNA that it allows me to use VisualStudio 2010 but it is not talking about VisualStudio 2012.
And after reading these kind of pages I guess it is normal that it's not working well because I didn't do anything of that sort to install XNA.
I guess this is an issue due to VS2012.
Haha. Small mistake, you need to add: this.graphics.ApplyChanges();. I did the same thing once. Understand that you need to do that every time you want to change something, there will be no changes until that is called.
I am going to close the subject as answered cause as I said to use XNA you need to use VS2010.
I read on the download page of XNA that it allows me to use VisualStudio 2010 but it is not talking about VisualStudio 2012. And after reading these kind of pages I guess it is normal that it's not working well because I didn't do anything of that sort to install XNA.
I guess this is an issue due to VS2012.
Try the code below instead of toggling a bool:
isFullscreen() = true;
I already tried alot and it doesnt work. I'm trying to start programing a game with XNA. So, I tried to load an Image. But it can't find it. This is my code
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture character;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
character = Content.Load<Texture2D>("pic");
}
So, for me there isnt a mistake. I added the picture by clickend with right click on Game_Test and then add existing item. Game_Test is the name of the project
Does anyone know where the mistake could be?
You need to add it not to "Game_Test" but to "Game_TestContent".
This is the place where XNA searching for Content.
for example my project called XNA_Tutorial, so i added to the yellow marked project :
I've been fighting with this problems for days now, browsing through the net, yet nothing helped me solve it: I'm creating a MonoGame application on Visual Studio 2012, yet when trying to load a texture I get the following problem:
Could not load Menu/btnPlay asset!
I have set content directory: Content.RootDirectory = "Assets"; Also the file btnPlay.png has properties set: Build Action: Content and Copy to Output directory: Copy if newer.
My constructor and LoadContent functions are totally empty, but have a look yourself:
public WizardGame()
{
Window.Title = "Just another Wizard game";
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Assets";
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
_spriteBatch = new SpriteBatch(GraphicsDevice);
Texture2D texture = Content.Load<Texture2D>("Menu/btnPlay");
_graphics.IsFullScreen = true;
_graphics.ApplyChanges();
}
I would be glad for any help! I'm totally desperate about the problem....
Under VS2012, Windows 8 64-bits and latest MonoGame as of today (3.0.1) :
create a subfolder named Assets
set Copy to Output to anything else than Do not copy
prepend assets to your texture path when loading it
namespace GameName2
{
public class Game1 : Game
{
private Texture2D _texture2D;
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
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
_texture2D = Content.Load<Texture2D>("assets/snap0009");
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(_texture2D, Vector2.Zero, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Here's your texture drawn :D
Note:
By convenience I kept the original value that the content's root directory points to : Content.
However, you can also directly specify Assets in the path:
Content.RootDirectory = #"Content\Assets";
Then load your texture without prepending Assets to its path:
_texture2D = Content.Load<Texture2D>("snap0009");
I'm a c++ programmer trying out c#. I've done a lot with box2d in c++, but this is my first time with c#. So, I'm trying to make a simple game with farseer physics engine. When I try to compile my code (I'm using visual studio c# 2010 express and xna game studio 4.0), it stops in body.cs at IBroadPhase broadPhase = World.ContactManager.BroadPhase; With this error: nullreferenceexception was unhandled. I believe the problem is in my Player class, so here's the code for that:
public class Player : Entity
{
Vector2 position;
SpriteBatch spriteBatch;
Texture2D texture;
Rectangle rectangle;
Body body;
CircleShape shape;
Fixture fixture;
public Player()
{
// TODO: Construct any child components here
}
///
/// 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.
///
public override void Initialize(World world, SpriteBatch spriteBatch, Texture2D texture)
{
// TODO: Add your initialization code here
this.spriteBatch = spriteBatch;
this.texture = texture;
rectangle = new Rectangle(0, 0, 11, 14);
body = BodyFactory.CreateBody(world);
body.BodyType = BodyType.Dynamic;
body.Position = new Vector2(0, 0);
shape = new CircleShape(1.0f, 1.0f);
fixture = body.CreateFixture(shape);
base.Initialize(world, spriteBatch, texture);
}
///
/// Allows the game component to update itself.
///
/// <param name="gameTime" />Provides a snapshot of timing values.
public override void Update(GameTime gameTime)
{
// TODO: Add your update code here
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
spriteBatch.Draw(texture, new Vector2(body.WorldCenter.X * 10, body.WorldCenter.Y * 10), rectangle, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
The farseer testbed runs fine, so I'm pretty sure my code is the problem, and not farseer. Let me know if you need to see more of my code. I've also posted this in the farseer forums, so If I get an answer there, I'll let you guys know. Thanks in advance.
Someone asked me to show the code of Game1.cs, and found the problem. The problem was that I had never constructed the world before initializing my player. It was fixed by adding world = new World(Vector2.Zero); before I initialized the player.