PART FIFTEEN
FLOAT TEXT
MESSAGE SYSTEM
Message Class
Create class Message. It should have the following:
Data
protected String text
protected float x
protected float y
protected Color color
protected Font font
Methods
public Message (String text, float x, float y, Color color, Font font)
Initializes all the data using provided parameters
public void update()
Empty for now
public void render(Graphics g)
Sets the font and color and then draw the text at the specified coordinates.
MessageManager
Create class MessageManager. This class is going to be entirely filled with static data and methods. It is simply a utility we'll use to track and display messages across our whole program.
Data
public static ArrayList<Message> messages
Methods
public static void init()
Initializes messages
public static void addMessage(Message message)
Adds message to the list of messages
public static void update()
Empty for now
public static void render(Graphics g)
Calls each message's render method
Putting It All Together
In Title
In init()
call the MessageManager's init().
In Game and Shop
In update()
call the MessageManager's update()
In render(Graphics g)
call the MessageManager's render(g)
In Game
In mousePressed(), add some test code to make sure this system actually works. Each time we click, call the MessageManager's addMessage() method with a simple message.
CHECKPOINT
Run your code and see...
When you click, a message should appear in that position.
OVERLOADING AND DURATION
What is Overloading?
A method with two versions that have the same name but different parameters is considered overloaded. This is a common method used to make our methods easier to use.
For example, consider how println() can take Strings, ints, and even booleans. But g.drawString() only takes Strings, which makes it a little awkward to use sometimes.
Overloading isn't always required, but in this case will make our code easier to read and require less typing. This idea is sometimes called syntatic sugar, because it makes the syntax sweeter.
In this section we will overload a few methods and constructors to give ourselves more options when calling these methods.
Default Constructor
We'll write a second, more basic constructor for the Message class:
public Message(String text, float x, float y)
This constructor is going to call our other constructor using the this keyword.
You will provide it with some defaults for color and font
Alongside this, we may also want to add a few setters to make the message easy to change:
public void setColor(Color color)
public void setFont(Font font)
TimeLeft and Duration
We'll want to make messages that don't last forever. Let's add more data:
public int duration
public int timeLeft
A duration of -1 will mean the object is permanent.
We'll update our constructors by expanding the main constructor. By the end, you should have three versions of the constructor to allow flexibility in the type of message created.
Write accessor methods for getDuration() and getTimeLeft().
You'll want to decrease timeLeft in the update() method if it is above zero.
Finally, we'll need to both update all messages and remove messages for which timeLeft equals zero. In class MessageManager
When we loop through each message, we'll want to check if getTimeLeft() is equal to zero. If so, remove it from the list.
GainMoney
In class Game, Let's make a second version of the gainMoney() method, this time taking a coordinate, Font, and color as a parameter. It will output a message automatically.
This method should set a default font and color for your message.
You should look carefully at the example code to the right, we'll center the text at the specified point.
We'll then want to override this to have a third version which takes a Cell as a parameter. To keep things simple, we'll use call the other gainMoney() in this method.
Call the "cell" version of gainMoney() each time you harvest a crop, destroy a rock, or chop down a tree.
Tip: Make sure you call this *before* you remove the rock, tree, or crop from the cell.
CHECKPOINT
Run your code and see...
A message should display every time you gain money from harvesting a plant, chopping down a tree, or breaking a rock.
FADE
Time Left As Percentage
In class Message
Write a method public float getPercentTimeLeft() that returns the percentage of time remaining based on the original duration.
Fade Effect
In class Message, add a boolean variable called fading. If this value is true, the message should fade out gradually as getTimeLeft() approaches zero.
You should expand the message constructor's parameter list to allow the called to assign this value to true or false.
Each time we render, make a new color based on the old color variable. Note that we don't modify the old color directly!
If we had done so, then passed this Message something like color.White, it would modify *all* the uses of white in our program.
CHECKPOINT
Run your code and see...
A message should display every time you gain money from harvesting a plant, chopping down a tree, or breaking a rock.
FLOATING MESSAGE
Adding The Class
Create class FloatMessage (extends Message)
The constructor should take five parameters: text, x, y, color, and duration.
Call the message constructor, passing all this data along but...
Always uses a set font of your choice
Always fades
Override the update() method.
Call super.update()
Decrease the y position by some amount
In class Game
Modify gainMoney() to create a FloatMessage instead.
ANNOUNCEMENT
Announcement System
Create class BigMessage (extends Message)
The constructor should take three parameters: text, color, and duration.
Create an accessor method which calculates the xPosition
Call the message constructor, passing all this data along but...
Sets x and y to a fixed position of the screen of your choice
Always uses a set font of your choice
Always fades
In class Game
Modify nextDay() to add a BigMessage that tells the player the new day is starting, and says the current day number.
The text is centered on the screen, but left aligned! This means we'll need to do math based on the width of the text.
Let's Make Centering Better
In class Message
Write a method called centerText() that shifts the x position to the left by half its width
This method has some dangers: if called multiple times, it won't accurately center the message. It also won't update if we change the text after creating a message. We could make a more robust centering system if we plan to use this functionality extensively. To at least mitigate the risks of this being misused, we'll make this method protected so it can only be called directly within Message classes.
In class BigMessage
In the constructor, call centerText()
As a thought experiment: how might you write this differently to help prevent it from shifting a value multiple times? What about allowing the user to go back and forth between different text alignments?
CHECKPOINT
Run your code and see...
A message should appear when you start a new day.
Consider other times might you want to put up this sort of announcement.