Remove items from screen on rectangle click - c#

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.

Related

How to use polymorphism in anemic domain model design?

Now i am working on a mmorpg server,Let's talk one scene that player drop something from inventory to world
If I design the Drop with rich domain model,i will create code like this
class Player {
void Drop(IDropable dropable,vector3 pos){
RemoveFromInventory();
dropable.BeDroped(pos);
Net.Broadcast(pos);
}
}
As you can see,the dropable will be called BeDroped(pos),and each entity which implement IDropable will do something special,for example,a weapon be drop,it will hit somebody;a magic ball be dropped,the player's heath point will decrease...
but if I want to design by anemic domain model,how could I use polymorphism for each IDropable?here is the example,the way i can achieve is using if else or switch ,but I know it is stupid.
class DropService {
void RemoveFromPlayerInventory(Player player){
//.....
}
void Drop(Player player, IDropable dropable,vector3 pos){
RemoveFromPlayerInventory(player);
if(dropable is Weapon)
OnDropWeapon(dropable,pos);
else if(dropable is magicball)
OnDropMagicBall(dropable,pos);
//.....
Net.Broadcast(pos);
}
}
One way to get rid of those if/else chains: double dispatch
Example:
class DropService:IDropService {
void RemoveFromPlayerInventory(Player player){
//.....
}
void Drop(Player player, IDropable dropable,vector3 pos){
RemoveFromPlayerInventory(player);
dropable.BeDropped(this, pos);
//.....
Net.Broadcast(pos);
}
void IDropService.Drop(Weapon item, Vector3 pos){ /*impl.*/ }
void IDropService.Drop(Magicball item, Vector3 pos){ /*impl.*/ }
}
public interface IDropable
{
void Bedropped(IDropService dropper, Vector3 pos);
}
public interface IDropService
{
void Drop(Weapon item, Vector3 pos);
void Drop(Magicball item, Vector3 pos);
}
public class Weapon: IDropable
{
public override void BeDropped(IDropService dropper, Vector3 pos)
{
dropper.Drop(this, pos); // Will automagically call the right overload
}
}
// Same for Magicball
As you see, there is no more if/else or switch.
Downside: What people consider to be a code smell is that DropService now needs to know every implementation of IDropable. So anytime a new class implements IDropable, you also need to change DropService.
To avoid this, you could consider a variety of possible patterns. Like several Factory patterns (Factory that creates an appropriate DropBehavior for example?), (Drop-)Strategy pattern ...
One approach could be to treat game objects more as database-entries than actual .net types. So you could for example create an game object in an editor, assign it some graphics, and one or more effects that should happen on some event. So your object might look something like
private EffectManager effectManager;
private Dictionary<EventId, EffectId> effectsOnEvents= new ();
public void OnEvent(EventId eventId) {
if(effectsOnEvents.TryGet(eventId, out var effectId){
effectManager(this, effectId);
}
}
So a weapon would have the DropWeapon effect attached to the Drop event, a magic ball would have the DropMagicBall effect attached and so on. Some class would need to define what each of these effects actually does, but there might be much fewer effects than game objects. Now your player would just need to call item.OnEvent(EventId.Drop), and that would trigger any associated behaviors.
You could also for example add support for multiple scripts to allow things like a magic ball weapon that both damages and heals. And add parameters to the script, so you can easily change the amount of damage dealt or hitpoints restored by updating a value in a database.
I would highly recommend Eric Lippers articles on Wizards and warriors where he points out that using the type system to model domain behaviors can be problematic.

How can I use SetParent to move a gameobject back to his original place in the hierarchy?

If I have the original hierarchy for example:
Cube1
Cube2
And I did on Cube2:
transform.SetParent(null);
Now the Hierarchy is looks like:
Cube1
Cube2
But if I want now to move back Cube2 to his original place ?
Cube1
Cube2
And same for other objects if they were children of children or sub parents and I move a group of objects and made them all SetParent(null) and now I want them all to return them to they original place.
You find the "Cube1" GameObject which was the parent:
GameObject cube1 = GameObject.Find("Cube1");
You call the SetParent function again but with the "Cube1" Transform in the argument passed to it:
transform.SetParent(cube1.transform);
I used something like this for the tutorial of our game. Basically the purpose is to have a game object from the UILayer be transfer to the TutorialLayer.
In the TutorialHandler of our game I made a Dictionary<int, GameObject> originalParent
PutToLayer(GameObject targret) function transfers target to the TutorialLayer and I store the original parent to the dictionary, using the target's instance id as key originalParent.Add(target.GetInstanceId()), target.transform.parent)
Returning the trarget to the original parent can be done by getting it from the dictionary
Transform origParent = originalParent[target.GetInstanceId()];
target.SetParent(origParent);
This way, you can transfer game objects to different parents while keeping track of the original parent
I think a nicer solution wouldn't involve any hard-coded names or inspector assigning since those implementations are prone to breaking when you rename or shift objects around.
I'd create a new component that remembers the original parent and then simply leaves it or rejoins it when you tell it to.
public class RoamingChild : MonoBehaviour {
private Transform _parent;
public void Awake () {
_parent = transform.parent;
}
//Leave the parent and go off on its own!
public void Leave () {
transform.SetParent(null);
}
//Come back to the parent!
public void Rejoin () {
transform.SetParent(_parent);
}
}
It might also be useful for the Child to come back to the same position within the Parent. So Child2 can leave and then rejoin the parent as the second child.
You could add this functionality by also remembering the SiblingIndex.
public class RoamingSibling : MonoBehaviour {
private Transform _parent;
private int _siblingIndex;
public void Awake () {
_parent = transform.parent;
_siblingIndex = transform.GetSiblingIndex();
}
//Leave the parent and go off on its own!
public void Leave () {
transform.SetParent(null);
}
//Come back to the parent!
public void Rejoin () {
transform.SetParent(_parent);
transform.SetSiblingIndex(_siblingIndex);
}
}

FlyWeight Pattern: every object parameters became same as updated

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.

Displaying Different Screens in XNA?

Recently started working with XNA (coming from java) and run into a problem with displaying game screens. When loading up XNA I get given a game.cs class which I interpreted to be a set a functions for drawing a single self-contained screen in the game. As obviously typing the code for all your different screens into this single class would get very messy very quickly so I created the below class to handle changes:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Colonies
{
public class GameManager //manages game screens
{
Microsoft.Xna.Framework.Game currentScreen;
public enum screens { menu, game, summary };
public GameManager()
{
initialize();
}
public void initialize()
{
currentScreen = new Menu(this);
((Menu)currentScreen).Run();
}
public void changeScreen(int i)
{
switch (i)
{
case 0:
currentScreen = new Menu(this);
((Menu)currentScreen).Run();
break;
case 1:
currentScreen = new World(this);
((World)currentScreen).Run();
break;
case 2:
currentScreen = new Summary(this);
((Summary)currentScreen).Run();
break;
}
}
}
}
However when one of these changes is triggered this causes an error flag up telling me I can't call game run more than once. Does this mean by initial estimation about having a single all purpose game screen is actually correct?! Should be manager instead be being queried for game like screens which methods are then called in the main game.cs class?
i.e.
in game.cs update method for example:
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
aGameManager.getAGameObject.DoAnUpdate();
base.Update(gameTime);
}
So essentially my main game class is never run again but just changes what it displays. Would this be the correct solution? (So much of the game class is hidden I am not sure what is the correct way to use it)
The Game class is the entire game. That's why it's called Game. If you want, you can create 'screen' objects, that each control a different screen, and use the Game class as you were trying to use the 'game manager'.
EG:
public static int currentScreen = 0; // Any screen can change this variable when needed
List<Screenobject> myscreens = new List<Screenobject>(); // Populate this with screens
// OR
menuscreen = new menuScreen();
otherscreen = new otherScreen();
// ...
protected override void Update(GameTime gameTime)
{
myscreens[currentScreen].Update(gameTime);
// OR
switch (currentScreen)
{
case 1:
menuscreen.Update(gameTime); break;
// ...
}
base.Update(gameTime);
}
and Draw(..) the same as Update(..)
create enumerator
enum gamestate
mainmenu
gameplay
options
end enum
and then simply in your update (draw) main functions
if gamestate = mainmenu then mainmenu.update();
if gamestate = gameplay then gameplay.update()

XNA Change Game Service dynamically during runtime

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

Categories

Resources