2
\$\begingroup\$

I'm doing a simple chat system with XNA C#. It is a chatbox that contains 5 lines of chat typed by the users. Something like a MMORPG chatting system.

[User1name] says: Hi
[User2name] says: Hello
[User1name] says: What are you doing?
[User2name] says: I'm fine
[System] The time is now 1:03AM. 

When the user pressed 'ENTER', the text he entered will be added inside an ArrayList

chatList.Add(s);

For displaying the text he entered, I used

for (int i = 0; i < chatList.Count(); i++)
{
spriteBatch.DrawString(font, chatList[i], new Vector2(40, arr1[i]), Color.Yellow);
}
*arr1[i] contains 5 y-axis points to print my 5 line of chats in the chatbox

Question1: What if I have another type of message which will be added into ChatList (something like a system message). I need the System Message to be printed out in red color.

And if the user keeps on chatting, the chat box will be updated according: (MAX 5 LINES) The newest chat will be shown below, and the oldest one will be deleted if they reached the max 5 lines.

[User2name] says: Hello
[User1name] says: What are you doing?
[User2name] says: I'm fine
[System] The time is now 1:03AM.
[User1name] says: Ok, great to hear that!

I'm having trouble to print each line color according to their msg type. For normal msg, it should be yellow. For system msg, it should be red.

Question2: And for the next problem, I need the chat texts to be white color, while the names of the user is yellow (like warcraft3 chat system). How do I do that?

I have a hard time thinking of a solution for these to work. Advise needed.

\$\endgroup\$

2 Answers 2

-1
\$\begingroup\$

You can use a class 'ChatMessage' that contains a property 'MessageType'. It can check what type it is and draw itself in the right color. Something like this (unoptimized):

public class ChatMessage
{
    public Dictionary<string, Color> TypeColors
    {
        get;
        protected set;
    }

    private string MessageType;
    private string Text;
    private string UserName;
    private SpriteFont Font;

    public ChatMessage(string userName, string text, string type, SpriteFont font)// Gets all the data necessary
    {
        MessageType = type;
        Text = text;
        UserName = userName;
        Font = font;

        InitTypeColors();
    }

    protected void InitTypeColors()// Set these to what ever you want and add more
    {
        TypeColors = new Dictionary<string, Color>();
        TypeColors["normal"] = Color.Yellow;
        TypeColors["message"] = Color.White;
        TypeColors["system"] = Color.Red;
    }

    public void Draw (SpriteBatch batch, Vector2 position)
    {
        batch.DrawString(Font, UserName, position, TypeColors[MessageType]);// Draws the user name in one color
        batch.DrawString(Font, Text, new Vector2(position.X + Font.MeasureString(UserName).X + 15, position.Y), TypeColors["message"]);// then the message, 15 pixels to the right, in the color associated with that type
    }
}

Then in your game use a List<ChatMessage> for your chatList. In your Game Draw method replace this:

spriteBatch.DrawString(font, chatList[i], new Vector2(40, arr1[i]), Color.Yellow);

with this :

chatList[i].Draw(spriteBatch, new Vector2(40, arr1[i]));

That should work, but you may want to optimize the code a bit.

\$\endgroup\$
0
9
\$\begingroup\$

For a flexible system, you'll want to make new classes to represent a line of text that can contain multiple sections of text with a given colour.

public class TextSection
{
    String text;
    Color color;
    Font font;
    public void Draw(SpriteBatch spriteBatch, Vector2 location)
    {
        spriteBatch.DrawString(font, text, location, color);
    }
    public Vector2 GetMeasurements()
    {
        return font.MeasureString(text);
    }
}

public class TextLine
{
    List<TextSection> sections;
    public void Draw(SpriteBatch spriteBatch)
    {
        int x = 0;
        int y = 0;    // Determine this however you want, pass it in maybe?

        foreach(var textSection in sections)
        {
            textSection.Draw(spriteBatch, new Vector2(x, y));
            Vector2 textSize = textSection.GetMeasurements();
            x += textSize.X;
        }
    }
}

Note, the above may not compile, take it with a grain of salt. The concept is there though. Each section of text on a line will be drawn it its own colour, and each section is pushed over by the size of the previous section(s).

Edit: As a general tip, break problems up into small chunks that make sense to you. If the big picture doesn't make sense right away, start working on some of the small helper methods and classes that you know will be used, and work up from there. The pieces usually fall into place.

\$\endgroup\$
6
  • \$\begingroup\$ Hi, can I ask what is the usage of TextSection and TextLine? I'm a little bit new to these coding. Could you explain it a little bit further please? \$\endgroup\$
    – XNA newbie
    Commented Nov 19, 2011 at 11:52
  • 1
    \$\begingroup\$ You may want to check out some xna and or C# tutorials. You can use the two classes above to represent blocks of text on a line and assign a colour to each block. There's not much else I can say short of a C# tutorial. \$\endgroup\$ Commented Nov 21, 2011 at 0:05
  • \$\begingroup\$ Emm Ok I created 2 classes TextSection.cs and TextLine.cs with the codes provided. How do I use them in my game.cs ? \$\endgroup\$
    – XNA newbie
    Commented Nov 21, 2011 at 12:29
  • \$\begingroup\$ Umm how do I use the code? I cant push in any text to print it out with the above code. \$\endgroup\$
    – XNA newbie
    Commented Nov 22, 2011 at 15:37
  • 6
    \$\begingroup\$ I'm sorry, but the code I wrote was a template and was designed to be added on to with constructors, accessors, and modifiers. I would buy a book on C# \$\endgroup\$ Commented Nov 23, 2011 at 17:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .