From a0f6cd976b8661eb608794ae169185b45b1b0a88 Mon Sep 17 00:00:00 2001 From: Starla Insigna Date: Thu, 5 Mar 2009 20:54:17 -0500 Subject: Engine: Created Message Escapes Rewrote MessageWindow to render text through another class called TextRenderer, which takes settings and parses the text with its message escapes. The text-color-setting escape works perfectly but the pause escape doesn't. It works pretty well, except for some reason, if the escape is directly next to some text on the left, it won't be parsed. Also, the pause escape was implemented as \P rather than \| because | is a special character .in regular expressions. The variable-displaying escape was not added for two reasons: First of all, a dynamically introduced variable would mess up the generated layout and the text would not wrap correctly. Secondly, a much easier/better way of including a variable in a message than message escapes exists: Using string concatenation when writing the DisplayMessage() call. As FourPuzzle is a programming library, it is much more powerful than RM2K and clients need not resort to strange hacks such as message escapes to include variables in messages. Clients can include whatever dynamic data they wish in messages, rather than some predefined stuff RM2K provides. A small bug was discovered in PauseTimer that made it wait for it's underlying Interval to elapse before it could elapse, even if it had zero ticks remaining. This has been fixed. Closes #16 --- src/com/fourisland/fourpuzzle/util/PauseTimer.java | 12 +- .../fourisland/fourpuzzle/window/ChoiceWindow.java | 2 +- .../fourpuzzle/window/MessageEscape.java | 79 ++++++ .../fourpuzzle/window/MessageWindow.java | 115 ++------ .../fourpuzzle/window/SystemGraphic.java | 9 +- .../fourisland/fourpuzzle/window/TextRenderer.java | 306 +++++++++++++++++++++ 6 files changed, 420 insertions(+), 103 deletions(-) create mode 100644 src/com/fourisland/fourpuzzle/window/MessageEscape.java create mode 100644 src/com/fourisland/fourpuzzle/window/TextRenderer.java (limited to 'src/com/fourisland') diff --git a/src/com/fourisland/fourpuzzle/util/PauseTimer.java b/src/com/fourisland/fourpuzzle/util/PauseTimer.java index 7d66d1a..f26f105 100644 --- a/src/com/fourisland/fourpuzzle/util/PauseTimer.java +++ b/src/com/fourisland/fourpuzzle/util/PauseTimer.java @@ -29,12 +29,12 @@ public class PauseTimer { if (in.isElapsed()) { - if (ticks == 0) - { - return true; - } else { - ticks--; - } + ticks--; + } + + if (ticks <= 0) + { + return true; } return false; diff --git a/src/com/fourisland/fourpuzzle/window/ChoiceWindow.java b/src/com/fourisland/fourpuzzle/window/ChoiceWindow.java index 4926a6d..90f2d96 100755 --- a/src/com/fourisland/fourpuzzle/window/ChoiceWindow.java +++ b/src/com/fourisland/fourpuzzle/window/ChoiceWindow.java @@ -79,7 +79,7 @@ public class ChoiceWindow implements Renderable { g2.drawImage(Window.Selector.getImage(fw-Window.Selector.getLeftX(), fh-Window.Selector.getTopY()), tx-SPACER, ty-fh-SPACER, null); } - g2.setPaint(new TexturePaint(SystemGraphic.getTextColor(), new Rectangle(tx, ty, fw, fh))); + g2.setPaint(new TexturePaint(SystemGraphic.getTextColor(0), new Rectangle(tx, ty, fw, fh))); g2.drawString(choice, tx, ty); ty+=(SPACER+fh); diff --git a/src/com/fourisland/fourpuzzle/window/MessageEscape.java b/src/com/fourisland/fourpuzzle/window/MessageEscape.java new file mode 100644 index 0000000..2ae55b2 --- /dev/null +++ b/src/com/fourisland/fourpuzzle/window/MessageEscape.java @@ -0,0 +1,79 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.fourisland.fourpuzzle.window; + +import java.util.regex.MatchResult; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +/** + * + * @author hatkirby + */ +public enum MessageEscape +{ + Color("\\\\C\\[(\\d+)\\]"), + Pause("\\\\P"); + + private Pattern pattern; + private MessageEscape(String pattern) + { + this.pattern = Pattern.compile(pattern); + } + + public static String removeEscapes(String message) + { + for (MessageEscape escape : values()) + { + message = escape.pattern.matcher(message).replaceAll(""); + } + + return message; + } + + public boolean match(String substring) + { + Matcher m = pattern.matcher(substring); + + return (m.lookingAt() && (m.start() == 0)); + } + + public String removeEscape(String message) + { + return pattern.matcher(message).replaceFirst(""); + } + + MessageEscapePair getMatch(String substring) + { + Matcher m = pattern.matcher(substring); + m.lookingAt(); + + return new MessageEscapePair(this, m.toMatchResult()); + } +} + +class MessageEscapePair +{ + MessageEscape escape; + MatchResult match; + + public MessageEscapePair(MessageEscape escape, MatchResult match) + { + this.escape = escape; + this.match = match; + } + + public MessageEscape getMessageEscape() + { + return escape; + } + + public MatchResult getMatchResult() + { + return match; + } +} \ No newline at end of file diff --git a/src/com/fourisland/fourpuzzle/window/MessageWindow.java b/src/com/fourisland/fourpuzzle/window/MessageWindow.java index dab67d1..709704a 100644 --- a/src/com/fourisland/fourpuzzle/window/MessageWindow.java +++ b/src/com/fourisland/fourpuzzle/window/MessageWindow.java @@ -14,11 +14,7 @@ import com.fourisland.fourpuzzle.util.Inputable; import com.fourisland.fourpuzzle.util.Interval; import com.fourisland.fourpuzzle.util.Renderable; import java.awt.Graphics2D; -import java.awt.Rectangle; -import java.awt.TexturePaint; import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.CountDownLatch; /** @@ -30,10 +26,9 @@ public class MessageWindow implements Renderable { private static final int SPACER = 4; private static final int HEIGHT = (4*(Display.getFontMetrics().getHeight()+SPACER)); - private volatile List messages; + TextRenderer tr; int width; BufferedImage cacheBase; - int num = 0; int upTo = 0; boolean bounceArrow = false; Interval in = Interval.createTickInterval(4); @@ -42,7 +37,9 @@ public class MessageWindow implements Renderable { width = Game.WIDTH - Window.Default.getFullWidth(0); cacheBase = Window.Default.getImage(width, HEIGHT); - initalizeMessages(message); + tr = new TextRenderer(width); + tr.setEscapes(true); + tr.initalizeText(message); } boolean hasFace = false; @@ -55,7 +52,10 @@ public class MessageWindow implements Renderable { this.face = FaceSet.getFaceSet(faceSet).getImage(face); hasFace = true; - initalizeMessages(message); + tr = new TextRenderer(width); + tr.setEscapes(true); + tr.setIndent(48 + (SPACER*2)); + tr.initalizeText(message); } private static void displayMessage(final MessageWindow mw) throws InterruptedException @@ -101,96 +101,24 @@ public class MessageWindow implements Renderable { displayMessage(new MessageWindow(message, faceSet, face)); } - private void initalizeMessages(String message) - { - messages = new ArrayList(); - - int length = width - SPACER; - if (hasFace) - { - length -= (48 + (SPACER*3)); - } - - String temp = message; - int len = 0; - while (!temp.isEmpty()) - { - while ((Display.getFontMetrics().stringWidth(temp.substring(0, len)) < length) && (len < temp.length())) - { - len++; - } - - if (len != temp.length()) - { - while ((!temp.substring(len, len+1).equals(" ")) && (len > 0)) - { - len--; - } - } - - messages.add(temp.substring(0, len)); - - if (len != temp.length()) - { - temp = temp.substring(len+1); - } else { - temp = ""; - } - - len = 0; - } - - setLength(); - } - - private void setLength() - { - num = 0; - - for (int i=0;i= num) + if (tr.isCascadingDone()) { - int msgs = messages.size(); - for (int i=0;i= (msgs-4)) { - messages.remove(0); - } - - if (messages.size() > 0) - { - upTo = 0; - setLength(); - } else { return true; + } else { + upTo += 4; + + if (upTo > msgs) + { + upTo = msgs; + } } } diff --git a/src/com/fourisland/fourpuzzle/window/SystemGraphic.java b/src/com/fourisland/fourpuzzle/window/SystemGraphic.java index 75e2b45..aa0b593 100755 --- a/src/com/fourisland/fourpuzzle/window/SystemGraphic.java +++ b/src/com/fourisland/fourpuzzle/window/SystemGraphic.java @@ -64,14 +64,19 @@ public class SystemGraphic { return systemGraphic.getSubimage(sca.x, sca.y, sca.width, sca.height); } - public static BufferedImage getTextColor() + public static BufferedImage getTextColor(int color) { if (systemGraphic == null) { initalize(); } - return systemGraphic.getSubimage(0, 48, 16, 16); + if (color < 10) + { + return systemGraphic.getSubimage(color*16, 48, 16, 16); + } else { + return systemGraphic.getSubimage(color*16, 64, 16, 16); + } } public static BufferedImage getUpArrow() diff --git a/src/com/fourisland/fourpuzzle/window/TextRenderer.java b/src/com/fourisland/fourpuzzle/window/TextRenderer.java new file mode 100644 index 0000000..f114c4d --- /dev/null +++ b/src/com/fourisland/fourpuzzle/window/TextRenderer.java @@ -0,0 +1,306 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package com.fourisland.fourpuzzle.window; + +import com.fourisland.fourpuzzle.Display; +import com.fourisland.fourpuzzle.Game; +import com.fourisland.fourpuzzle.util.PauseTimer; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.TexturePaint; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +/** + * + * @author hatkirby + */ +public class TextRenderer { + + private static final int SPACER = 4; + + private boolean initalized = false; + private int width; + private List messages = new ArrayList(); + + public TextRenderer(int width) + { + this.width = width; + } + + private boolean useEscapes = false; + public void setEscapes(boolean use) + { + if (initalized == true) + { + throw new IllegalStateException("Already initalized"); + } + + useEscapes = use; + } + + private int indent = 0; + public void setIndent(int indent) + { + if (initalized == true) + { + throw new IllegalStateException("Already initalized"); + } + + this.indent = indent; + } + + public void initalizeText(String message) + { + if (initalized == true) + { + throw new IllegalStateException("Already initalized"); + } + + int length = width - SPACER - indent; + int len = 0; + LineOfText temp = new LineOfText(message); + + if (useEscapes) + { + for (int i=0; i 0)) + { + len--; + } + } + + messages.add(temp.part(0, len)); + + if (len != temp.length()) + { + temp = temp.part(len+1, temp.length()); + } else { + break; + } + + len = 0; + } + + initalized = true; + } + + int upTo = Integer.MIN_VALUE; + int num = 0; + int lastStart = Integer.MIN_VALUE+1; + PauseTimer pt = new PauseTimer(0); + public BufferedImage render(int start) + { + if (initalized == false) + { + throw new IllegalStateException("TextRenderer must be initalized prior to rendering"); + } + + if (lastStart != start) + { + num = 0; + for (int i=start;i= num); + } + +} + +class LineOfText implements CharSequence +{ + String line; + Map> escapes = new HashMap>(); + public LineOfText(String line) + { + this.line = line; + } + + public LineOfText(String line, Map> escapes) + { + this.line = line; + + for (int i=0; i()); + } + + escapes.get(index).add(escape); + } + + public Vector getEscapes(int index) + { + if (!escapes.containsKey(index)) + { + return new Vector(); + } else { + return escapes.get(index); + } + } + + public LineOfText part(int start, int end) + { + LineOfText temp = new LineOfText(line.substring(start, end)); + + for (int i=start; i