IsFullScreen from my GraphicsDeviceManager doesn't work using XNA - c#

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;

Related

adding a background in monogame isn't working

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 ;)

The Bomb doesn't get placed when I want it to

I have a game that I made for Windows phone using XNA/C#, and now I've decided to go and add a Bomb to help the player.
Now I have setup a timer and a bool, so that only 1 bomb can be used per level.
But, as soon as the game opens, the bomb is already there! I don't think the timer is working.
bool canDrawBomb = false;
public static Texture2D bomb;
GameTimer bombTimer = new GameTimer();
protected override void Initialize()
{
// Bomb timer.
bombTimer.UpdateInterval.Add(new TimeSpan(50000));
bombTimer.Update += bombTimer_Update;
bombTimer.Start();
base.Initialize();
}
void bombTimer_Update(object sender, GameTimerEventArgs e)
{
canDrawBomb = true;
bombTimer.Stop();
}
protected override void LoadContent()
{
bomb = Content.Load<Texture2D>("Bomb");
}
protected override void Draw(GameTime gameTime)
{
if (canDrawBomb)
{
// Draw the bomb.
// TESTED: OK. The bomb can draw but not at right time.
spriteBatch.Draw(bomb, new Vector2(), Color.White);
}
}
Now the problem is that even though I have set the bombTimer to ah 50 seconds, it still draws at the very beginning of the game!
How can I fix this? I haev been at this for hours and it's driving me insane. I don't know what I'm doing wrong!
The following line will not change the interval property (because the TimeSpan.Add() method makes a fresh copy, it does not change the existing TimeSpan):
bombTimer.UpdateInterval.Add(new TimeSpan(50000));
just use
bombTimer.UpdateInterval = new TimeSpan(50000);
I suspect that the GameTimer.Update event is fired as soon as GameTimer.Start() is called. Add a counter variable and only set canDrawBomb to false on the second call (and equaly only disable the timer on the second call)
Or use the DispatcherTimer if that is available in XNA, which definitely does not fire on the Start call.

Bullets aren't showing up in Space Invaders-like game

I have just started making a game that is going to be somewhat like space invaders.
I'm a complete novice when it comes to programming and have little experience (I'm only attempting this as I need to have a software design project due at the end of next week).
Anyways, I have been following a tutorial on how to fire bullets. and it doesn't seem to be working. I have copied almost every aspect of this tutorial except for the 'velocity' variable in the 'bullets' class (which I don't think I need as I'm only using side to side movement not forward/back).
This is the code below. Thanks in advance. :)
Main
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 Software_Design_Major_Project
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D ship; // Declaring the sprite
Vector2 shipposition = Vector2.Zero;
List<bullets> bullets = new List<bullets>();
KeyboardState pastkey;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferWidth = 600;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
ship = Content.Load<Texture2D>("ship"); // Loads the ship into the memory.
shipposition = new Vector2((graphics.GraphicsDevice.Viewport.Width / 2) -
(ship.Width / 2), 420);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Left) && shipposition.X
>= 0)
{
shipposition.X -= 6;
}
if(Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Right) && shipposition.X <
((graphics.GraphicsDevice.Viewport.Width) - (ship.Width)))
{
shipposition.X += 6;
}
if (Keyboard.GetState().IsKeyDown(Keys.Space) && pastkey.IsKeyUp(Keys.Space))
{
shoot();
}
pastkey = Keyboard.GetState();
updatebullets();
base.Update(gameTime);
}
public void updatebullets()
{
foreach(bullets bullet in bullets)
{
if (Vector2.Distance(bullet.position, shipposition) < 0)
bullet.isvisible = false;
}
for (int i = 0; i < bullets.Count; i++)
{
if (!bullets[i].isvisible)
bullets.RemoveAt(i);
i--;
}
}
public void shoot()
{
bullets newbullet = new bullets(Content.Load<Texture2D>("bullet"));
newbullet.position = shipposition;
newbullet.isvisible = true;
if (bullets.Count < 20)
bullets.Add(newbullet);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
spriteBatch.Draw(ship, shipposition, Color.White);
spriteBatch.End();
foreach (bullets bullet in bullets)
bullet.Draw(spriteBatch);
base.Draw(gameTime);
}
}
}
Bullets
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Software_Design_Major_Project
{
class bullets // A new class needs to be created to allow for bullets.
{
public Texture2D texture;
public Vector2 position;
public Vector2 origin;
public bool isvisible;
public bullets(Texture2D newtexture)
{
texture = newtexture;
isvisible = false;
}
public void Draw(SpriteBatch spritebatch)
{
spritebatch.Draw(texture, position, null, Color.White, 0f, origin, 1f,
SpriteEffects.None, 0);
}
}
}
P.S. Sorry for the long post.
I don't see any code that changes your bullets position, Your going to need a velocity variable, and update the position based on the velocity each frame.
And you could get the angle from a = Math.Atan(Y,X)
Looks like you probably removed the part that calculates position, as you thought you didn't need the velocity stuff. I suggest you try adding it back to see if it works, and then removing parts you don't need.
Surprised nobody spotted this sooner.
You're ending your SpriteBatch before the bullets have been drawn.
Calls to SpriteBatch.Draw must occur between the Begin and End methods because of all the work that goes on behind the scenes to make drawing as fast as possible.
All you need to do is move spriteBatch.End() further down, like so:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
spriteBatch.Draw(ship, shipposition, Color.White);
foreach (bullets bullet in bullets)
bullet.Draw(spriteBatch);
spriteBatch.End(); //Move to here instead
base.Draw(gameTime);
}
Extra Trivia:
Basically what goes on behind the scenes is that the sprite batch actually batches up the textures using the settings described by begin (yes, these can be changed) and then when end is called, it figures out which bits fall outside the screen and makes note not to draw them, it depth sorts the textures if told to and it does all sorts of other optimisations before drawing them to the back buffer and then finally when all drawing is over, the back buffer gets presented to the screen and the old one is taken and reused for the next draw call. It sounds like a lot of work, but with the way modern computers work, the optimisations tend to create a big improvement.
you could check this sample right here. I've coded this stuff a long time ago, I think in v2.0 of XNA, can't rembember now.
http://gozoomin.com/media/p/69699.aspx
The logic in there is quit simple :)
Starting making a 'classic' is always a good way to start.
Edit - You can get it here as well: http://www.sendspace.com/file/r4s4um
Edit2 - I just checked the code now, it's with some comments documenting most of things, probably you will get some stuff written in portuguese.
PS - Don't copy past the code! Try to learn the basics around the sample.

How to resize window using XNA

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.

interface - null exception thrown

im both new to this site and new to programming. I've been recently trying to learn new skills to help better organise/manage my code and make it both more efficient, readable and contained.
Okay well i wont go on too much about that, the problem i'm having is in XNA 3.1, I'm using C# express 08.
I have a self contained Game conponent called InputHandler, the update loops after the base loop (Game1) which so far just checks for keyboard input and stores the result into an instance of KeyboardState - which has a Get property, the only other code really is it exits Game1 if Escape key is pressed, which it checks for after storing the input.
Code:
private KeyboardState keyboardstate;
public KeyboardState Keyboard_State
{
get { return (keyboardstate); }
}
public override void Update(GameTime gameTime)
{
keyboardstate = Keyboard.GetState();
if (keyboardstate.IsKeyDown(Keys.Escape))
Game.Exit();
base.Update(gameTime);
}
moving onto the problem, another game conponent called Camera tries accessing the Keyboard_State property of the InputHandler via an instance of the IInputHandler (this is an interface btw)
public interface IInputHandler
{
KeyboardState Keyboard_State { get; }
}
it goes without saying that this interface is implemented within the InputHandler component. moving onto the error, well I have in my update loop within the Camera component some logic code, which tries to access the Keyboard_State property through the interface, check against some conditions, then alter the camera apropriatly.
private IInputHandler input;
following code is within the void update loop.. within the Camera component.
if (input.Keyboard_State !=null)
{
if (input.Keyboard_State.IsKeyDown(Keys.Left))
cameraYaw += spinRate;
if (input.Keyboard_State.IsKeyDown(Keys.Right))
cameraYaw -= spinRate;
if (cameraYaw > 360)
cameraYaw -= 360;
else if (cameraYaw < 360)
cameraYaw += 360;
}
I get a Null reference exception at the *if (input.Keyboard_State !=null)* line, complaining that it's not an instance.
I'm new with Interfaces, I've never seen much of a use for them in the past until i started to try learn XNA, and began learning about conponents, ultimately i want to create the basic components to manage a 3D game (nothing fancy, just organised and manageable).
any help would be appreciated. thanks :)
* Other info *
my camera constructer is :
public Camera(Game game)
: base(game)
{
graphics = (GraphicsDeviceManager)Game.Services.GetService(typeof(IGraphicsDeviceManager));
input = (IInputHandler)game.Services.GetService(typeof(IInputHandler));
}
and my InputHandler constructer is empty, my Game1 constructer is:
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
camera = new Camera(this);
Components.Add(camera);
input = new InputHandler(this);
Components.Add(input);
input.UpdateOrder = 0;
camera.UpdateOrder = 1;
// this component alows Asyncroniously save/load game.
Components.Add(new GamerServicesComponent(this));
#if DEBUG
fps = new FPS(this);
Components.Add(fps);
fps.UpdateOrder = 1;
camera.UpdateOrder = 2;
#endif
}
input is an instance of the Input handler game component.
private InputHandler input;
hope this helps :)
It seems to me that you are not initializing the "input"-variable in the camera anywhere ( = input is null ).
Because of that, if (input.Keyboard_State !=null) -line throws NullReferenceException ( and by the way KeyboardState is a struct thus it can't be null). You said that both InputHandler and Camera is a game-component? Try doing something like this then:
In the InputHandler constructor:
public InputHandler(...)
{
// Your initialization code here
this.Game.Services.AddService(typeof(IInputHandler), this);
}
And in the Camera constructor:
public Camera(...)
{
// Your initialization code here
input = this.Game.Services.GetService(typeof(IInputHandler)) as IInputHandler;
}
EDIT, Updated code:
Change your Game-constructor to this:
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
input = new InputHandler(this);
Components.Add(input);
Services.AddService(typeof(IInputHandler), input);
camera = new Camera(this);
Components.Add(camera);
input.UpdateOrder = 0;
camera.UpdateOrder = 1;
// this component alows Asyncroniously save/load game.
Components.Add(new GamerServicesComponent(this));
#if DEBUG
fps = new FPS(this);
Components.Add(fps);
fps.UpdateOrder = 1;
camera.UpdateOrder = 2;
#endif
}

Categories