• Advertisement
Sign in to follow this  

Complexity of Dictionary - C#

This topic is 2377 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey, I am creating a game using XNA 4.0 and C#.

I am currently trying to create a HUD. I ended up going with 2 classes to create the HUD. It will be easier to show you than explain:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CGPLibrary.Sprites;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace CGPLibrary
{
public class HUDElement
{
protected Sprite element;
protected Texture2D texture;
protected int width, height;
protected Vector2 m_position;
protected int offsetX, offsetY;
protected GameWindow Window;
protected Color color;


public enum Position
{
TOP_LEFT, TOP_RIGHT, TOP_MIDDLE, MIDDLE_LEFT, MIDDLE_RIGHT, MIDDLE, BOTTOM_LEFT, BOTTOM_RIGHT, BOTTOM_MIDDLE

}

public enum ELEM_TYPE { Health, Armour, H_ABackground, Life }ELEM_TYPE elementType;

public HUDElement(Sprite sprite, GameWindow window)
{
color = sprite.sprColor;
Window = window;
offsetX = 0;
offsetY = 0;
element = sprite;
texture = sprite.spTexture;
width = sprite.Width;
height = sprite.Height;
}

public Sprite spr { get { return element; } }
public int Width { get { return width; } }
public int Height { get { return height; } }
public Color elemColor { get { return color; } set { color = value; } }
public Texture2D elemText { get { return texture; } }
public ELEM_TYPE type { get { return elementType; } set { elementType = value; } }
public Vector2 position { get { return m_position; } }
public int xOffset { get { return offsetX; } set { offsetX = value; } }
public int yOffset { get { return offsetY; } set { offsetY = value; } }

public void setPosition(Position pos)
{
switch (pos)
{
case Position.TOP_LEFT:
m_position = new Vector2(offsetX, offsetY);
break;
case Position.TOP_MIDDLE:
m_position = new Vector2((Window.ClientBounds.Width / 2 - texture.Width / 2) + offsetX, offsetY);
break;
case Position.TOP_RIGHT:
m_position = new Vector2((Window.ClientBounds.Width - texture.Width) + offsetX, offsetY);
break;

case Position.MIDDLE_LEFT:
m_position = new Vector2(offsetX, (Window.ClientBounds.Height / 2 - texture.Height / 2) + offsetY);
break;
case Position.MIDDLE:
m_position = new Vector2((Window.ClientBounds.Width / 2 - texture.Width / 2) + offsetX, (Window.ClientBounds.Height / 2 - texture.Height / 2) + offsetY);
break;
case Position.MIDDLE_RIGHT:
m_position = new Vector2((Window.ClientBounds.Width - texture.Width) + offsetX, (Window.ClientBounds.Height / 2 - texture.Height / 2) + offsetY);
break;

case Position.BOTTOM_LEFT:
m_position = new Vector2(offsetX, (Window.ClientBounds.Height - texture.Height) + offsetY);
break;
case Position.BOTTOM_MIDDLE:
m_position = new Vector2((Window.ClientBounds.Width / 2 - texture.Width / 2) + offsetX, (Window.ClientBounds.Height - texture.Height) + offsetY);
break;
case Position.BOTTOM_RIGHT:
m_position = new Vector2((Window.ClientBounds.Width - texture.Width) + offsetX, (Window.ClientBounds.Height - texture.Height) + offsetY);
break;

}

}
}
}



using Microsoft.Xna.Framework;
using System.Collections.Generic;
using HeadStacker;
using CGPLibrary.Sprites;
using Microsoft.Xna.Framework.Graphics;
using CGPLibrary.Entities;


namespace CGPLibrary
{
/// <summary>
/// This is a game component that implements IUpdateable.
/// </summary>
public class HUD : DrawableGameComponent
{
protected Dictionary<HUDElement.ELEM_TYPE, HUDElement> hudElements;
HumanPlayer player;
protected SpriteBatch batch;
public Main game;

public HUD(Main game)
: base(game)
{
hudElements = new Dictionary<HUDElement.ELEM_TYPE, HUDElement>();
this.game = game;
player =game.human;
this.batch = game.spriteBatch;

}


public void addHudElement(HUDElement elem)
{
hudElements.Add(elem.type, elem);


}
public override void Draw(GameTime gameTime)
{
batch.Begin();
batch.Draw(hudElements[HUDElement.ELEM_TYPE.Life].elemText, hudElements[HUDElement.ELEM_TYPE.Life].position, hudElements[HUDElement.ELEM_TYPE.Life].spr.sourceRect,
hudElements[HUDElement.ELEM_TYPE.Life].elemColor, 0f, Vector2.Zero, hudElements[HUDElement.ELEM_TYPE.Life].spr.Scale,SpriteEffects.None,0f);


batch.Draw(hudElements[HUDElement.ELEM_TYPE.H_ABackground].elemText, hudElements[HUDElement.ELEM_TYPE.H_ABackground].position,null,
hudElements[HUDElement.ELEM_TYPE.H_ABackground].elemColor,0f,Vector2.Zero,hudElements[HUDElement.ELEM_TYPE.H_ABackground].spr.Scale,SpriteEffects.None,0f);



batch.Draw(hudElements[HUDElement.ELEM_TYPE.Health].elemText, hudElements[HUDElement.ELEM_TYPE.Health].position,
new Rectangle(0,0,(int)(hudElements[HUDElement.ELEM_TYPE.Health].Width * ((double)player.health/100)),hudElements[HUDElement.ELEM_TYPE.Health].Height)
,hudElements[HUDElement.ELEM_TYPE.Health].elemColor,0f,Vector2.Zero,hudElements[HUDElement.ELEM_TYPE.Health].spr.Scale,SpriteEffects.None,0f);



batch.Draw(hudElements[HUDElement.ELEM_TYPE.Armour].elemText, hudElements[HUDElement.ELEM_TYPE.Armour].position,
new Rectangle(0, 0, (int)(hudElements[HUDElement.ELEM_TYPE.Armour].Width * ((double)player.armour / 100)), hudElements[HUDElement.ELEM_TYPE.Armour].Height)
, hudElements[HUDElement.ELEM_TYPE.Armour].elemColor,0f, Vector2.Zero, hudElements[HUDElement.ELEM_TYPE.Armour].spr.Scale, SpriteEffects.None, 0f);
batch.End();

base.Draw(gameTime);
}
public override void Update(GameTime gameTime)
{
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
hudElements[HUDElement.ELEM_TYPE.Life].spr.animate(elapsed);
// hudElements[HUDElement.ELEM_TYPE.Health].elemText = player.currentWeapon.texture;

base.Update(gameTime);
}
}
}




You can see in the draw method, I find each element inside the Dictionary and draw it. My question is, will this cause any kind of overhead? I think I read that the Dictionary is normally O( c )but that was using the .containsKey() method. Will using the [] notation cause any slowdowns(or increased performance)?

Share this post


Link to post
Share on other sites
Advertisement
I can't speak to the efficiency of your system, but your code makes my eyes bleed. Why don't you try something like this?



HudElement element = hudElements[HUDElement.ELEM_TYPE.Life];
batch.Draw(element.elemText, element.position, element.spr.sourceRect, element.elemColor, 0f, Vector2.Zero, element.spr.Scale,SpriteEffects.None,0f);

Share this post


Link to post
Share on other sites

I can't speak to the efficiency of your system, but your code makes my eyes bleed. Why don't you try something like this?



HudElement element = hudElements[HUDElement.ELEM_TYPE.Life];
batch.Draw(element.elemText, element.position, element.spr.sourceRect, element.elemColor, 0f, Vector2.Zero, element.spr.Scale,SpriteEffects.None,0f);




Haha, It makes mine bleed , also, I have no idea why I didn't do that in the first place. Thanks for that

Share this post


Link to post
Share on other sites

HudElement life = hudElements[HUDElement.ELEM_TYPE.Life];
batch.Draw(life.elemText, life.position, life.spr.sourceRect, life.elemColor, 0f, Vector2.Zero, life.spr.Scale,SpriteEffects.None,0f);
//or
HudElement HUDLife = hudElements[HUDElement.ELEM_TYPE.Life];
batch.Draw(HUDLife.elemText, HUDLife.position, HUDLife.spr.sourceRect, HUDLife.elemColor, 0f, Vector2.Zero, HUDLife.spr.Scale,SpriteEffects.None,0f);


I don't know. Suspense's code definitely does the job. But I guess, if it were me, I'd like a little more description.

Share this post


Link to post
Share on other sites
All of the above would work better if it were turned the other way round:
class HudElement {
...
public void RenderToSpriteBatch(SpriteBatch s) {
s.draw(elemText, position, spr.sourceRect, elemColor, 0f, Vector2.Zero, spr.Scale,SpriteEffects.None, 0f);
}
...
};


Then:
...
public override void Draw(GameTime gameTime)
{
batch.Begin();
foreach(KeyValuePair<HUDElement.ELEM_TYPE, HUDElement> e in hudElements) {
e.Value.RenderToSpriteBatch(batch);
}
batch.End();
...

Share this post


Link to post
Share on other sites


HudElement life = hudElements[HUDElement.ELEM_TYPE.Life];
batch.Draw(life.elemText, life.position, life.spr.sourceRect, life.elemColor, 0f, Vector2.Zero, life.spr.Scale,SpriteEffects.None,0f);
//or
HudElement HUDLife = hudElements[HUDElement.ELEM_TYPE.Life];
batch.Draw(HUDLife.elemText, HUDLife.position, HUDLife.spr.sourceRect, HUDLife.elemColor, 0f, Vector2.Zero, HUDLife.spr.Scale,SpriteEffects.None,0f);


I don't know. Suspense's code definitely does the job. But I guess, if it were me, I'd like a little more description.


Ye thanks, I did it the way you did aswell after I read Suspense's reply. I also like some description :D.. He was probably just generalising anyway.

Share this post


Link to post
Share on other sites
Speaking to your question, I'd be surprised --extremely surprised-- if: aDictionary.containsKey("blah") was faster or improved in any way than aDictionary["blah"]. If anything, aDictionary.containsKey("blah") would have to do a scan of all keys until it reached the key it was looking for. aDictionary["blah"], IIRC, is the better choice of the two. And definitely should be still O(c).

Share this post


Link to post
Share on other sites

All of the above would work better if it were turned the other way round:
class HudElement {
...
public void RenderToSpriteBatch(SpriteBatch s) {
s.draw(elemText, position, spr.sourceRect, elemColor, 0f, Vector2.Zero, spr.Scale,SpriteEffects.None, 0f);
}
...
};


Then:
...
public override void Draw(GameTime gameTime)
{
batch.Begin();
foreach(KeyValuePair<HUDElement.ELEM_TYPE, HUDElement> e in hudElements) {
e.Value.RenderToSpriteBatch(batch);
}
batch.End();
...




Ahhh cool, I was looking for a way to do it all at once after I got it working. Thanks!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement