Hi i need find out size of viewing area of my game window. I found this code :
int height = GraphicsDevice.Viewport.Height;
but return this error:
Object reference not set to an instance of an object.
Can you anyone help me how solve this problem ? Thanks and sorry for my English
I would say that GraphicsDevice.Viewport.Height is null then, not inited yet. GraphicsDevice is inside Microsoft.Xna.Framework.Graphics namespace.
if you are inheriting from game class try with:
this.GraphicsDevice.Viewport.Height
or with
this.Game.GraphicsDevice.Viewport.Height
where are you trying to populate those integers?
added example
using Microsoft.Xna.Framework.Graphics;
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public int screenWidth;
public int screenHeight;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
screenWidth = GraphicsDevice.Viewport.Width;
screenHeight = GraphicsDevice.Viewport.Height;
}
}
Height looks like it could be a class or something due to its capitalization, but the biggest clue is the part in the error where it says object reference. The .Height at the end gets the Height object of Viewport. You need to access a property/member variable of the object (probably named height; the easiest way to find it would be code completion) to assign it to a variable.
Related
I recently made a custom inspector and I just realized that my OnValidate() is not being called when I edit a variable in the Inspector. Any ideas on how to get my calls back to OnValidate() again while keeping the custom inspector I used?
The answer was in serializing and propertyfield.
Example with my code, the first part here is just showing that in my main script I have this declared. Remember now, public variables are already serialized so no need to put that.
public class Original : MonoBehaviour {
// Used for the user to input their board section width and height.
[Tooltip("The desired Camera Width.")]
public float cameraWidth;
}
Now in my Custom inspector I have this:
pubilc class Original_Editor : Editor{
public override void OnInspectorGUI(){
serializedObject.Update();
// Get the camera width.
SerializedProperty width = serializedObject.FindProperty("cameraWidth");
// Set the layout.
EditorGUILayout.PropertyField(width);
// Clamp the desired values
width.floatValue = Mathf.Clamp((int)width.floatValue, 0, 9999);
// apply
serializedObject.ApplyModifiedProperties();
}
}
I've created a rectangle, that has its own class. In the class I have a delegate created, that closes the game.
Creating the delegate:
public event EventHandler ExitRequested = delegate { };
In the update method I tell when to execute it:
if (mouseState.LeftButton == ButtonState.Pressed)
{
ExitRequested(this, EventArgs.Empty);
}
In my main class I execute the delegate like this (the exitGame is a rectangle):
exitGame.ExitRequested += exitGame_ExitRequested;
What I'm wondering about is there a way how to remove all items from the screen? Lets say it's for a "new game" functionality. I tried to create this functionality the same way I created the exit functionality but I can't figure out how to remove the items...
As far as I understand, you are trying to remove all game entities / objects in order to start a new game. Usually this is achieved by storing entities in a collection, and then simply removing all collection entries when a 'new game' is needed. As for entities which are not generic, such as the player, usually you just reset every member that needs to be reset; position, points etc.
Say you have a class to hold information about entities, such as enemies:
public class Entity
{
public Texture2D Sprite;
public Rectangle Bounds;
public Entity(Texture2D Sprite, Rectangle Bounds)
{
this.Sprite = Sprite;
this.Bounds = Bounds;
}
public void Update(GameTime gameTime)
{
//Movement code here
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(Sprite,Bounds,Color.White);
}
}
And you then store all entities in a collection:
public List<Entity> Entities = new List<Entity>();
You update and draw each entity by looping through the collection:
//In main game class
public void Update(GameTime gameTime)
{
foreach (Entity e in Entities)
e.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
foreach (Entity e in Entities)
e.Draw(spriteBatch);
}
Then when you want to start a new game, and effectively remove all entities, you can simply remove all entries in the Entities list. (For example using List.Clear(), there are many ways)
Keep in mind this is an example which has not been tested, so to say. This is can be optimized, and is more to give you an idea of why collections are useful for organizing game objects / entities.
Hello everyone ı have a problem with flyweight patter ;
I try to implement flyweight patter to my sprite class. There are tons of smilarty as attributes each Sprite object only diffirences are Position and frame;
Im my code ı have a problem, whenever ı set(Position or frame) of one sprite , every other objects attribute also change, ı dont want that ı want most of attributes are same but frame and position is diffrent for each object.
Here is the code:
public enum Type
{
sprite,
None,
};
public class FactorySprite
{
private LinkList SpriteList = new LinkList();
private Hashtable Sprites = new Hashtable();
public FactorySprite()
{
// SpriteList.AddtoBegining(new Sprite());
Sprites.Add(Type.sprite, new Sprite());
}
public GameSprite getSprite(Type type)
{
// return (Sprite)SpriteList.Search(O);
GameSprite gamesprite = null;
if(Sprites.ContainsKey(type))
{
gamesprite =( GameSprite)Sprites[type];
}
return gamesprite;
}
}
public abstract class GameSprite
{
protected Texture2D texture;
// protected Vector2 position;
protected Texture loadTexture;
// protected int frame;
protected Vector2 Speed;
protected Rectangle SourceRectangle;
protected Color color;
public Type type;
protected SpriteBatch spriteBatch;
public abstract void Draw();
public abstract void Update();
public abstract void setframe(int frame_number);
public abstract void setPosition(int x,int y);
}
public class Sprite : GameSprite
{
private int frame;
private Vector2 position;
public Sprite()
{
frame =0;
type = Type.sprite;
spriteBatch = Game1.GameInstance.spriteBatch;
texture = Texture.Instance().GetTexture();
Speed = new Vector2(0, 1);
color = Color.White;
}
public override void Draw()
{
spriteBatch.Draw(texture,position,Image.Instance().drawframe(this.frame), color);
}
public override void setframe(int frame_number) {this.frame = frame_number; }
public override void setPosition(int x, int y) {this.position = new Vector2(x, y); }
public Type getType()
{
return type;
}
public override void Update(){}
}
Here is manin that ı create factory flayweight and each object that ı create
SpriteManager sm = SpriteManager.Instance();
FactorySprite factory = new FactorySprite();
Sprite s1 = (Sprite)factory.getSprite(Type.sprite);
s1.setframe(6);
s1.setPosition(200, 300);
sm.AddSprite(s1);
Sprite s2 = (Sprite)factory.getSprite(Type.sprite);
s2.setframe(5);
s2.setPosition(100, 100);
sm.AddSprite(s2);
Problem here to be more clear s1 and s2 has same frame and position(whic one is last updated all other object become same)
This thing about the FlyWeight pattern is that every time you ask for one, you get the same instance. Thus every time you call GetSprite you are returning the same one, not a copy but the same one.
So if you call it twice, you now have two references to the same object. If you change it in one place it will change in the other because the two ARE THE SAME THING! That's actually the point of the FlyWeight pattern.
I would suggest that you don't use this pattern where you need different objects as you do.
One way around trhis is to extract all this bits of a Sprite which do not ever change into a new class, which you can then use the FlyWeight pattern on. The changeable bits would stay in the Sprite class, with the addition of a reference to your new 'ImutableSprite' instance.
The Flyweight pattern doesn't apply here.
Flyweight means that you use the same object with a specific in all cases where you want this specific value. Obviously, if you change the value in one place, the change will appear everywhere.
If you want to reduce the number of sprites, you could use immutable semantics: Use a single Sprite instance for a specific set of Position,Frame and create a copy when you want a Sprite with a different set.
I know people have asked this before, but it would appear that their solution doesn't work for me or I'm doing something wrong.
public class Sprite
{
private Game m_game;
private SpriteBatch m_spriteBatch;
private string m_filename;
private Texture2D m_texture;
public Sprite(Game game, SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
{
m_game = game;
m_spriteBatch = spriteBatch;
m_texture = new Texture2D(graphicsDevice, graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height);
}
public void LoadSprite(string filename)
{
m_texture = m_game.Content.Load<Texture2D>(filename);
}
}
The error is generated at LoadSprite when I pass "tree" as the filename.
m_texture isn't null because (tried to) initialise it in the constructor.
The same call to Content.Load is used in the main loop fine but I want to move that into the Sprite class.
treeTexture = Content.Load<Texture2D>("tree");
This works fine in the main loop so it shows that the "tree" file exists.
Can anyone see what I'm doing wrong?
m_game or m_game.Content is probably null.
I have an interface (ICamera) which is implemented by 2 classes (FreeCamera, StaticCamera). The classes are inheriting from GameComponent.
Example definiton:
public class FreeCamera : GameComponent, ICamera
{
...
}
Now I'm adding the classes to the Game Components and register one of the components to a game service
private FreeCamera freeCam;
private StaticCamera staticCam;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
freeCam = new FreeCamera(this) { Enabled = true };
staticCam = new StaticCamera(this) { Enabled = false };
Services.AddService(typeof(ICamera, freeCam);
Components.Add(freeCam);
Components.Add(staticCam);
...
}
Then I want to change the provider for the service during the application flow with help of a toggle function
namespace Game1
{
protected override void Update(GameTime gameTime)
{
var keyboard = Keyboard.GetState();
if(keyboard.IsKeyDown(Keys.C))
{
if(freeCam.Enabled)
{
Services.RemoveService(typeof(ICamera));
Services.AddService(typeof(ICamera, staticCam);
freeCam.Enabled = !freeCam.Enabled;
staticCam.Enabled = !staticCam.Enabled;
}
else
{
Services.RemoveService(typeof(ICamera));
Services.AddService(typeof(ICamera, freeCam);
freeCam.Enabled = !freeCam.Enabled;
staticCam.Enabled = !staticCam.Enabled;
}
}
base.Update(gameTime);
}
}
The StaticCamera takes only input by mouse (you can rotate the camera), the FreeCamera can also moved by keyboard input. When I call the method above (by pressing C on the keyboard) the FreeCamera class gets deactivated but the viewport seems frozen and does not react to any input. When I call the method again after a short time the FreeCamera gets activated again and everything works as expected.
Now I have 2 questions regarding this:
Is it possible to change the service
provider of a game service in the
game loop?
Is there a better approach
to handle different camera types in a
game and switch between them easily?
Thanks in advance for any help.
Like you answered, use a camera manager. It acts as both a factory and a container for the current camera. The manager you can register as a service. Manager would look something like this:
public class CameraManager
{
private Dictionary<Type, ICamera> _cameras;
private ICamera _current;
public ICamera Current
{
get
{
return _current;
}
}
// Sets the current cammera to the internal instance of the camera type
public void SetCurrent<T>() where T : ICamera
{
if (!_cameras.ContainsKey(typeof(T)))
{
// TODO: Instantiate a new camera class here...
}
_current = _cameras[typeof(T)];
}
}
This is just rough code - would need to be filled in more. One limitation is you can only have one camera per type. Giving cameras a string name, or an enum flag would let you toggle between an arbitrary number of cameras.
Thanks for the tip. I just wrote the code down from my head without my IDE at hand, so please do not look too much into syntax errors etc.
In my game I'm using wrapper classes for the input. The code is just a brief example of the problem - how to substitute a game service if both classes are using the same interface.
My new idea: I could use a "manager" class (like CameraManager in this case) which has the following methods
public void SetCameraType(CameraType type) //CameraType could be an enum
public ICamera GetCamera()
and then put the manager class into the service (with its own interface like ICameraManager).
Edit: this was considered as an answer to the comment above ... but it seems I clicked the wrong button - sorry
I think if you left off the code about adding and removing the service in the Update you'd be good and added lines changing the Visible property. The Enable property effects calls to Update, but the Visible property effects calls to Draw.
So I'd suggest the Update look like this:
protected override void Update(GameTime gameTime)
{
var keyboard = Keyboard.GetState();
if(keyboard.IsKeyDown(Keys.C))
{
if(freeCam.Enabled)
{
freeCam.Enabled = false;
freeCam.Visible = false;
staticCam.Enabled = true;
staticCam.Visible= true;
}
else
{
freeCam.Enabled = true;
freeCam.Visible = true;
staticCam.Enabled = false;
staticCam.Visible= false;
}
}
base.Update(gameTime);
}