Skip to main content
GameDev.net gamedev.net
🔒 Locked

[java] msg box for rpg

Started by esde Dec 25, 2006 at 9:52 PM 1 replies 850+ views
Original Post
esde
esde
hi all, i've taken a course in school on basics of C++ & oop. tried basic examples such as breakout/pong in windows api and they proved to be quite simple(concepts wise). since then i've switched to java since applets can be embedded in a webpage, allowing games to be conveniently shared. my interest in gamedev is mainly RPG. however, without actual coding by myself, i find a "storyline" within a game loop pretty confusing since everything is to be rendered by frame. thus, i've started with a MsgBox class for rpg text. import java.awt.*; import java.awt.event.*; import java.applet.*; public class MsgBox { int x, y; //textbox position int width, height; String text; int char_pos; boolean visible; MsgBox next; //next textbox to display when button is pressed public MsgBox(MsgBox n) { next = n; //for a start "pointer" to textboxes } public MsgBox(int x_pos, int y_pos, int w, int h, String str, MsgBox n) { x = x_pos; y = y_pos; width = w; height = h; text = str; char_pos = 0; visible = true; next = n; } public void setVisible(boolean v) { visible = v; } public void complete() { //display all the text when action button is pressed char_pos = text.length(); } public void reset() { char_pos = 0; } public void paint(Graphics g) { if(visible == true) { if(char_pos < text.length()) { char_pos++; //show more of the text each time } g.setColor( Color.blue ); //draw box g.fillRoundRect(x, y, width, height, 8, 8); //. g.setColor( Color.gray ); //. g.drawRoundRect(x, y, width, height, 8, 8); //. g.setColor( Color.black ); //. g.drawRoundRect(x+2, y+2, width-4, height-4, 8, 8); //. g.setColor( Color.white ); //. g.drawRoundRect(x+1, y+1, width-2, height-2, 8, 8); //draw box g.drawString(text.substring(0,char_pos), x+10, y+20); //draw text } } } thank you to all those who actually lasted this long. basically, until i create a MsgBoxManager to support multiple textboxes in 1 screen(probably using a linked list), there can only be one at each time and it shall be painted using my start pointer to the current MsgBox, start.paint(g). here comes the questions. you can be very truthful about how wrong or inefficient my code is, i'm always willing to start from scratch to get my basics right :) 1. is this even a correct approach for text in rpg? else the following questions could entirely be skipped. And please do point me in the right direction. 2. as you would already guess by now.. the init() function in the applet would be filled with msg = new MsgBox(0, 109, 239, 50, "testing...", next_msg); is there a java equivalent of #define in C++ i can use so that it shortens the statement to msg = new MsgBox("testing...", next_msg); unless specified (i know i could create another constructor for it though), the reason for this being, later on when i add more stuff such as fonts and types of textboxes(timed ones,transparent ones), the constructor would be very much longer. 3. is it a huge waste of memory to create so many instances of the class? especially if an Image is passed every time the constructor is called. Working without pointers can be pretty confusing. 4. I'm finding a way draw the textbox to an Image so that the box could be painted upon initialising and the text only needs to be drawn once each time. One possibility would be offscreen graphics but i'm actually having trouble creating an image within the MsgBox class. 5. Would it be better to create a Image textbox layer and have all textboxes drawn on it(including cases where several textboxes are on the screen). these are all the questions for now.. i appreciate just any help you can give. of course, you don't have to answer every single question =) A huge thank you for your time and effort to read such a long post.
FlaiseSaffron
FlaiseSaffron
Quote:
Original post by esde
1. is this even a correct approach for text in rpg? else the following questions could entirely be skipped. And please do point me in the right direction.

I don't think there is any one right answer for an RPG or any other application. As for a solution, you're on the right track. But first off, I would recommend you make your MsgBox class extend one of the containers in java.awt or javax.swing, and then use a Label or JLabel to handle the positioning of the text for you.

This way, the event dispatch thread from the graphics API would call your paint(Graphics) method without you having to do it yourself.

Second off, updating the cursor position inside the paint method can lead to inconsistent behavior when the window is invalidated, for example by another window being dragged over it. Instead you should pass Runnable objects to the event dispatch thread, like so:

final Runnable runnable = new Runnable() {  public void run() {    // That HTML code below is supposed to be the "less than" symbol    if(theMsgBox.char_pos < theMsgBox.text.length()) {      // Advance the cursor, just like in your code      theMsgBox.char_pos++;      // Tell the event dispatch thread to redraw what we just changed      theMsgBox.repaint();      // Start a new thread to handle the delay, so we don't slow the GUI      new Thread() {        public void run() {          try {            Thread.sleep(10); // Keep the delay short; long delays here are evil            // Tell the event dispatch thread to execute the runnable again            EventQueue.invokeLater(runnable);          }          catch(InterruptedException exit) {            // The exception was probably thrown because the            // Virtual machine is exiting, so simply stop executing.          }        }      }.start();    }  }};// Tell the event dispatch thread to execute the runnableEventQueue.invokeLater(runnable);


Just after running the above code, the event dispatch thread

Quote:
2. as you would already guess by now.. the init() function in the applet would be filled with msg = new MsgBox(0, 109, 239, 50, "testing...", next_msg);
is there a java equivalent of #define in C++ i can use so that it shortens the statement to msg = new MsgBox("testing...", next_msg); unless specified (i know i could create another constructor for it though), the reason for this being, later on when i add more stuff such as fonts and types of textboxes(timed ones,transparent ones), the constructor would be very much longer.

Macros are commonly considered evil, and so are not supported in Java. If you really need to save typing, just use a private static method. It works just like an inline function in C++.

Quote:
3. is it a huge waste of memory to create so many instances of the class? especially if an Image is passed every time the constructor is called. Working without pointers can be pretty confusing.

Reference variables in Java work (for our purposes) exactly like C pointers except that you cannot perform pointer arithmetic. So no, because you are not copying the image repeatedly.

Quote:
4. I'm finding a way draw the textbox to an Image so that the box could be painted upon initializing and the text only needs to be drawn once each time. One possibility would be offscreen graphics but i'm actually having trouble creating an image within the MsgBox class.

Easy:

import java.awt.image.BufferedImage;Image img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);Graphics g = img.getGraphics();theMsgBox.paint(g);


Quote:
5. Would it be better to create a Image textbox layer and have all textboxes drawn on it(including cases where several textboxes are on the screen).

Not worth your time unless you're repainting more than a few hundred times per second.
esde
esde
Thanks for your help, Dathgale. Most of my doubts were cleared. As for the changes in the implementation, I'll need some time to try it out. Thank you once again for your time =D

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.