Entity Creation and Messaging in a VB.NET Text-Based Game - Implementing a Message System
(Page 4 of 4 )
When the player bumps into another entity, it might be a good idea to display a short message to the user telling him that someone is in the way. Besides, a messaging system would be nice for other purposes as well. So, let's create one.
First, we need something in which to store our messages. A collection will do the job. However, I'd like to introduce a new kind of collection especially suited for the purpose: the Queue(Of T).
Picture a line (a queue) of people waiting to buy a movie ticket. The first person who gets into the line is the first person to be removed from the line, and the last person who gets into the line is the last person to be removed from the line. A Queue(Of T) works just like this. It's a first-in-first out collection.
Unlike other collections, it has no index associated with it. Instead, we enqueue and dequeue elements. The first element to be enqueued is the first element to be dequeued. This works for our purposes because we have limited screen space to work with it, and we'll need to remove the oldest messages (the first ones to be added) when we run out of room.
Let's go ahead and create a Queue(Of T) as a field of the Game module:
Dim messages As New Queue(Of String)
We don't want to add messages directly to the the collection because we want to be able to limit the size of it. If it gets too large, we need to remove some messages. Speaking of size, let's define a ReadOnly field containing the maximum number of messages in messages at a time:
ReadOnly MessageLimit As Integer = 10
Next, we need to create a method that will add messages. This method needs to check the size of messages at first, and if the number of messages has reached MessageLimit, then an element needs to be dequeued and discarded using the Dequeue method. Then, if the message is too long, it needs to be split up into multiple messages. That way, a message doesn't automatically run to the next line and mess up everything (it will be written over or will run past the allowed height of the message area, possibly causing the screen to scroll). The message then needs to be enqueued using the Enqueue method, and all of the messages need to be redrawn. Here's WriteMessage:
Sub WriteMessage(ByVal message As String)
' Is it too big? If so, split it up.
If message.Length > 70 Then
WriteMessage(message.Substring(0, 70))
WriteMessage(message.Substring(70))
Else
' Do we have too many messages?
If messages.Count = MessageLimit Then
messages.Dequeue()
End If
' Add it and draw the messages
messages.Enqueue(message)
DrawMessages()
End If
End Sub
Now we need to create a method that will draw the messages out to the screen, below the map and user statistics, with one space of padding to the left. This involves two things. First, we need to erase the old messages by writing blank spaces over them. Second, we need to actually write out the current messages. Here's DrawMessages:
Sub DrawMessages()
' Erase old messages by writing blank spaces over them
' Write out ten spaces at a time to minimize flickering
For y As Integer = 1 To MessageLimit
Console.SetCursorPosition(1, 20 + y)
For x As Integer = 1 To 7
Console.Write(" ")
Next
Next
Console.SetCursorPosition(0, 21)
For Each message As String In messages
Console.CursorLeft = 1
Console.WriteLine(message)
Next
End Sub
We now have a working messaging system. You can test it out by writing a welcome message before the game's While loop:
WriteMessage("Welcome to VB Quest!")
Let's modify TryMove to alert the player if he's trying to walk into another entity. This only involves rewriting the For Each loop to check to see if its the player trying to move. If it is, then we need to write a message:
For Each gameEntity As Entity In entities
If gameEntity.X = x And gameEntity.Y = y Then
If toBeMoved Is player Then
WriteMessage(gameEntity.Name & " is in the way.")
End If
Return False
End If
Next
Notice the Is operator and the & (concatenation) operator. The Is operator checks to see if two variables point to the same instance. Here, we're checking to see if the entity to be moved (toBeMoved) is actually the player. The & operator concatenates too strings. The + operator will also work, but it's not generally recommended when concatenating to strings because it's not exclusive to strings as & is.
| DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware. |