Basfreak

Members
  • Content count

    4
  • Joined

  • Last visited

Community Reputation

101 Neutral

About Basfreak

  • Rank
    Newbie
  1. [C#] Ingame context menu

    Good point. Enums it is
  2. [C#] Ingame context menu

    Sorry for the late response. I agree with you on the last part, I like my code to be structured logically. So I think I'll go with my second idea, I'll implement ContextMenu and override contextMenuOnClick() something like this: [code] public void contextMenuOnClick(ContextMenuItem clickedItem) { if(clickedItem.getText() == "Item 1") { // do something } } [/code]
  3. Regarding your first question: you can also check which entities are in range when moving your player and than set a flag on them to not update, e.g. entity.inRange=false
  4. Hey guys, I'm working on a RTS like game and just implemented context menus. When you click on a tree or anything a context menu will popup with the available options. It works, but I'd like to know if it could be done nicer / better. I've got a ContextMenu class where the drawing and events are handled, a Tree class to show how it's used and a part of Game1.cs: ContextMenu.cs: [code] using System; using System.Collections.Generic; using System.Linq; using System.Text; 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 MyGame { public class ContextMenu { public static int minMenuWidth = 64; public static int minMenuHeight = 64; public static Sprite contextMenuBackground; public static Sprite contextMenuBorder; private Game1 theGame; private Vector2 position; private bool visible; private GameObject target; private List<ContextMenuItem> itemList = new List<ContextMenuItem>(); private int width = minMenuWidth; private int height = minMenuHeight; public ContextMenu(Game1 g, List<ContextMenuItem> items) { theGame = g; foreach (ContextMenuItem item in items) { if (9 * item.getText().Length > width) width = 9 * item.getText().Length; } itemList = items; target = null; } public ContextMenu(Game1 g) { theGame = g; target = null; } public bool onClick(MouseState mouseState) { Point mousePosition = new Point(mouseState.X, mouseState.Y); Rectangle menuHitBox = new Rectangle((int)position.X, (int)position.Y, width, height); if (menuHitBox.Contains(mousePosition)) { for (int i = 0; i < itemList.Count; i++) { ContextMenuItem item = itemList[i]; Rectangle hitBox = new Rectangle((int)position.X + 10, (int)position.Y + 8 + 12 * (i), width - 20, 12); if (hitBox.Contains(mousePosition)) { item.onClick(target); return true; } } return true; } return false; } public void setTarget(GameObject o) { target = o; } public GameObject getTarget() { return target; } public void updateHovers(MouseState mouseState) { Point mousePosition = new Point(mouseState.X, mouseState.Y); Rectangle menuHitBox = new Rectangle((int)position.X, (int)position.Y, width, height); if (menuHitBox.Contains(mousePosition)) { for (int i = 0; i < itemList.Count; i++) { ContextMenuItem item = itemList[i]; item.setHovering(false); Rectangle hitBox = new Rectangle((int)position.X + 10, (int)position.Y + 8 + 12 * (i), width - 20, 12); if (hitBox.Contains(mousePosition)) { item.setHovering(true); } } } } public Rectangle getHitBox() { return new Rectangle((int)position.X, (int)position.Y, width, height); } public bool isVisible() { return visible; } public void addContextMenuItem(ContextMenuItem item) { itemList.Add(item); } public ContextMenuItem getContextMenuItem(int i) { if (i >= 0 && i < itemList.Count) return itemList[i]; else return null; } public void draw() { if (!visible || itemList.Count == 0) return; // bg for (int y = 0; y < ((float)height / 64); y++) { for (int x = 0; x < ((float)width / 64); x++) { if (y * 64 + 64 <= height && x * 64 + 64 <= width) { theGame.spriteBatch.Draw(contextMenuBackground.getTexture(), new Rectangle((int)position.X + 64 * x, (int)position.Y + 64 * y, 64, 64), contextMenuBackground.getSourceRectangle(0), Color.White); } else { Rectangle sourceRect = contextMenuBackground.getSourceRectangle(0); sourceRect.Width = width - x * 64; sourceRect.Height = height - y * 64; theGame.spriteBatch.Draw(contextMenuBackground.getTexture(), new Rectangle((int)position.X + 64 * x, (int)position.Y + 64 * y, sourceRect.Width, sourceRect.Height), sourceRect, Color.White); } } } // left top theGame.spriteBatch.Draw(contextMenuBorder.getTexture(), new Rectangle((int)position.X, (int)position.Y, 8, 8), contextMenuBorder.getSourceRectangle(0), Color.White); // right top theGame.spriteBatch.Draw(contextMenuBorder.getTexture(), new Rectangle((int)position.X + width - 8, (int)position.Y, 8, 8), contextMenuBorder.getSourceRectangle(1), Color.White); // left theGame.spriteBatch.Draw(contextMenuBorder.getTexture(), new Rectangle((int)position.X, (int)position.Y + 8, 8, height - 16), contextMenuBorder.getSourceRectangle(4), Color.White); // right theGame.spriteBatch.Draw(contextMenuBorder.getTexture(), new Rectangle((int)position.X + width - 8, (int)position.Y + 8, 8, height - 16), contextMenuBorder.getSourceRectangle(5), Color.White); // top theGame.spriteBatch.Draw(contextMenuBorder.getTexture(), new Rectangle((int)position.X + 8, (int)position.Y, width - 16, 8), contextMenuBorder.getSourceRectangle(7), Color.White); // bottom theGame.spriteBatch.Draw(contextMenuBorder.getTexture(), new Rectangle((int)position.X + 8, (int)position.Y + height - 8, width - 16, 8), contextMenuBorder.getSourceRectangle(6), Color.White); // left bottom theGame.spriteBatch.Draw(contextMenuBorder.getTexture(), new Rectangle((int)position.X, (int)position.Y + height - 8, 8, 8), contextMenuBorder.getSourceRectangle(2), Color.White); // right bottom theGame.spriteBatch.Draw(contextMenuBorder.getTexture(), new Rectangle((int)position.X + width - 8, (int)position.Y + height - 8, 8, 8), contextMenuBorder.getSourceRectangle(3), Color.White); // Draw the items: for (int i = 0; i < itemList.Count; i++) { ContextMenuItem item = itemList[i]; if (item.isHovering()) { Rectangle hitBox = new Rectangle((int)position.X + 9, (int)position.Y + 9 + 12 * (i), width - 18, 12); theGame.spriteBatch.Draw(theGame.dummy, new Vector2((float)hitBox.X, (float)hitBox.Y), null, new Color(255, 255, 255) * 0.3f, 0f, Vector2.Zero, new Vector2(hitBox.Width, hitBox.Height), SpriteEffects.None, 0f); } theGame.drawShadedString(theGame.spriteBatch, theGame.defaultFont, item.getText(), new Vector2((int)position.X + 10, (int)position.Y + 8 + 12*(i)), Color.White, 1.0f, new Vector2(1.0f, 1.0f), Color.Black); } } public void setPosition(int x, int y) { position.X = (float) x; position.Y = (float) y; } public void setWidth(int w) { width = w; } public void setHeight(int h) { height = h; } public void show() { visible = true; } public void hide() { visible = false; } } } [/code] Tree.cs: [code] using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework; namespace MyGame { class Tree : ResourceObject { public static int treeWidth = 16; public static int treeHeight = 16; public static double maxTreeHealth = 100.0; public static ContextMenu contextMenu; private Sprite sprite; private Random rand; public Tree(Game1 g, Level l, Sprite s, int x, int y) { // bla bla } public override void tick(GameTime gameTime) { } public override void draw() { theGame.spriteBatch.Draw(sprite.getTexture(), new Rectangle((int)position.X, (int)position.Y, width, height), sprite.getSourceRectangle(), Color.White); } public override ContextMenu getContextMenu() { return contextMenu; } } } [/code] The action that will happen when an item is clicked is defined in Game1.cs: [code] List<ContextMenuItem> menuItemlist = new List<ContextMenuItem>(); menuItemlist.Add(new ContextMenuItem("Chop tree", delegate(GameObject o) { if (o != null) { if (selectedAnts.Count > 0) { foreach (Ant selectedAnt in selectedAnts) { Point walkTarget = new Point(o.getX(), o.getY()); selectedAnt.setTarget(o); selectedAnt.walkNear(walkTarget); contextMenu.hide(); } } } })); Tree.contextMenu = new ContextMenu(this, menuItemlist); [/code] Is this a good way of doing this? Using delegates as parameters for menu items? Another idea I had was the following: Create a IContextMenu interface with 2 methods: getContextMenuItems() and contextMenuOnClick(ContextMenuItem clickedItem) a right-clickable gameobject will than implement this interface. The drawing and handling of the clicks are than handled within Game1.cs. Thanks [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img] Bas