Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (580)
games submitted by our members
Games in WIP (500)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  JPanel, JFrame, MainMenu Problems  (Read 983 times)
0 Members and 1 Guest are viewing this topic.
Offline Slyth2727
« Posted 2013-04-28 20:25:17 »

Ok, first, just to verify: This is not for Ludum Dare. I'm not quiteee experienced enough yet to do it but I am watching lots of the live streams for tips.

Anyways on to the question:
I have a VERY messy setup for a main menu, and (obviously) it isn't working, and I really don't know how to do it correctly.
Here are my classes:
MainMenu (main class) :
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
package Engine;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MainMenu extends JFrame {

   public static String title = "TSA Droidz Defense";
   public static Dimension size = new Dimension(700, 550);
   public Screen screen;
   public static Point mse = new Point(0, 0);
   public static MainMenuPanel img;
   public static MainMenuHelp hlp;

   public MainMenu(int width, int height) {
      size = new Dimension(width, height);
      img = new MainMenuPanel(this);
      Image ii = new ImageIcon(MainMenu.class.getResource("imgs/icon.png")).getImage();
      setIconImage(ii);
      setTitle(title);
      setSize(size);
      setResizable(false);
      setLocationRelativeTo(null);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      init();
   }

   public void init() {
      setLayout(new GridLayout());
      addKeyListener(new KeyHandle());
      setVisible(true);
      setScreen(img);
   }

   public void setScreen(JPanel panel, JPanel remove) {
      remove(remove);
      add(panel);
   }

   public void setScreen(JPanel panel) {
      remove(img);
      add(panel);
   }
}


MainMenuPanel(the JPanel for the main menu):
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
package Engine;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class MainMenuPanel extends JPanel implements Runnable {

   public static String[] elements = { "New Game", "Load Save", "Help", "Quit" };
   public String[] items = { "New Game", "Load Save", "Help", "Quit" };
   public static Rectangle[] boxes = new Rectangle[elements.length];
   public int offS = 0;
   public MainMenu menu;
   public Thread thread;

   public MainMenuPanel(MainMenu menu) {
      this.setSize(menu.getSize());
      this.menu = menu;
      thread = new Thread(this);
      thread.start();
      menu.addMouseListener(new MenuInput());
      menu.addMouseMotionListener(new MenuInput());
      SoundEngine.playSound(Sounds.inGameMusic, true);
   }

   public void paint(Graphics g) {
      Font font = new Font("DialogInput", 1, 25);
      g.setColor(Color.DARK_GRAY);
      g.fillRect(0, 0, 800, 520);
      g.drawImage(createImageIcon("imgs/mainMenu.png").getImage(), 0, 0, 800, 520, null);
      g.setFont(font);
      g.setColor(Color.WHITE);
      for (int i = 0; i < elements.length; i++) {
         g.drawString(items[i], 390 - items[i].length() * 6, 200 + i * 40);
         boxes[i] = new Rectangle(390 - elements[i].length() * 6, 200 + i * 40 + 8, elements[i].length() * 25, 24);
         if (boxes[i].contains(MainMenu.mse)) {
            items[i] = "> " + elements[i] + " <";
         } else {
            items[i] = elements[i];
         }
      }
   }

   public void action(Point p) {
      for (int i = 0; i < boxes.length; i++) {
         if (boxes[i].contains(p)) {
            doAction(i);
         }
      }
   }

   protected ImageIcon createImageIcon(String path) {
      java.net.URL imgURL = getClass().getResource(path);
      if (imgURL != null) {
         return new ImageIcon(imgURL);
      } else {
         System.err.println("Couldn't find file: " + path);
         return null;
      }
   }

   public void doAction(int num) {
      if (num == 0) {
         new Frame(700, 550, true);
         menu.dispose();
      } else if (num == 1) {

      } else if (num == 2) {
         if (MainMenu.hlp == null) {
            MainMenu.hlp = new MainMenuHelp(menu);
         }
         menu.setScreen(MainMenu.hlp, MainMenu.img);
         for (int i = 0; i < boxes.length; i++) {
            boxes[i] = new Rectangle(0, 0, 0, 0);
         }
      } else if (num == 3) {
         menu.dispose();
         System.exit(0);
      }
   }

   @Override
   public void run() {
      while (true) {
         repaint();
      }
   }
}


MainMenuHelp (the help page which is just a slideshow of images of help):
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
package Engine;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class MainMenuHelp extends JPanel implements Runnable {

   public static String[] elements = { "Next", "Main Menu", "Previous" };
   public String[] items = { "Next", "Main Menu", "Previous" };
   public static Rectangle[] boxes = new Rectangle[elements.length];
   public Image[] slides = new Image[6];
   public int offS = 0;
   public MainMenu menu;
   public Thread thread;
   public int imageIterator = 0;

   public MainMenuHelp(MainMenu menu) {
      this.setSize(menu.getSize());
      this.menu = menu;
      thread = new Thread(this);
      thread.start();
      menu.addMouseListener(new MenuInput());
      menu.addMouseMotionListener(new MenuInput());
      slides[0] = createImageIcon("imgs/sliden1.png").getImage();
      slides[1] = createImageIcon("imgs/sliden2.png").getImage();
      slides[2] = createImageIcon("imgs/sliden3.png").getImage();
      slides[3] = createImageIcon("imgs/sliden4.png").getImage();
      slides[4] = createImageIcon("imgs/sliden5.png").getImage();
      slides[5] = createImageIcon("imgs/sliden6.png").getImage();
   }

   public void paint(Graphics g) {
      Font font = new Font("DialogInput", 1, 25);
      g.setColor(Color.DARK_GRAY);
      g.fillRect(0, 0, 800, 520);
      g.drawImage(slides[imageIterator], 0, 0, 800, 460, null);
      System.out.println(imageIterator);
      g.setFont(font);
      g.setColor(Color.WHITE);

      g.drawString(items[0], 25 - items[0].length() * 2, 479);
      boxes[0] = new Rectangle(25 - items[0].length() * 2, 479, elements[0].length() * 25, 24);

      g.drawString(items[1], 340 - items[1].length() * 2, 479);
      boxes[1] = new Rectangle(340 - items[1].length() * 2, 479, elements[1].length() * 25, 24);

      g.drawString(items[2], 680 - items[2].length() * 2, 479);
      boxes[2] = new Rectangle(680 - items[2].length() * 2, 479, elements[2].length() * 25, 24);

      for (int i = 0; i < boxes.length; i++) {
         if (boxes[i].contains(MainMenu.mse)) {
            items[i] = "> " + elements[i] + " <";
         } else {
            items[i] = elements[i];
         }
      }

   }

   public void action(Point p) {
      for (int i = 0; i < boxes.length; i++) {
         if (boxes[i].contains(p)) {
            doAction(i);
         }
      }
   }

   public void doAction(int num) {
      if (num == 0 && imageIterator != 5) {
         imageIterator++;
      } else if (num == 2 && imageIterator > 0) {
         imageIterator--;
      } else if (num == 1) {
         menu.setScreen(menu.img, this);
      }
   }

   protected ImageIcon createImageIcon(String path) {
      java.net.URL imgURL = Frame.class.getResource(path);
      if (imgURL != null) {
         return new ImageIcon(imgURL);
      } else {
         System.err.println("Couldn't find file: " + path);
         return null;
      }
   }

   public void run() {
      while (true) {
         repaint();
      }
   }
}


as well as the input class(may not be important, but I'll include it anyway):
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
package Engine;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class MenuInput implements MouseMotionListener, MouseListener {

   @Override
   public void mouseEntered(MouseEvent e) {

   }

   @Override
   public void mousePressed(MouseEvent e) {

   }

   @Override
   public void mouseDragged(MouseEvent e) {
      MainMenu.mse = e.getPoint();
   }

   @Override
   public void mouseMoved(MouseEvent e) {
      MainMenu.mse = e.getPoint();
   }

   @Override
   public void mouseClicked(MouseEvent e) {
      MainMenu.img.action(e.getPoint());
      if (MainMenu.hlp != null) {
         MainMenu.hlp.action(e.getPoint());
      }
   }

   @Override
   public void mouseExited(MouseEvent e) {

   }

   @Override
   public void mouseReleased(MouseEvent e) {

   }
}


basically, my problem is that, if I go into the help menu, go back to the main menu, and click new game, it opens up TWO new games instead of one. Again, this is probably the messiest setup of this in the world, so it could be a number of things, I was thinking maybe the Threads colliding or multiple objects that get messed up because of static or something else. I am about to rip out my hair here so help is very much appreciated.
-cMp

Check out Escaping Vox, a 3D
|\ _\  voxel based puzzler!
 \|_|
Offline davedes
« Reply #1 - Posted 2013-04-28 21:07:14 »

Your code is messy and hard to read. I would suggest learning some basic patterns like command design and learning a bit more about objects (i.e. using multiple objects in an ArrayList to define buttons for your menu). You should also avoid "magic numbers" -- this is where you have code like this:
1  
boxes[i] = new Rectangle(390 - elements[i].length() * 6, 200 + i * 40 + 8, elements[i].length() * 25, 24);


This makes the code very difficult to read, difficult to debug, prone to errors, difficult to adapt to changes, etc. Whereas instead you could have code that scales and reads beautifully, with little extra effort.

Another problem is that your game loop is not a game loop; it's just an infinite loop that repaints the frame. I'm not sure how well this is performing on your end but it will probably just lead to further problems down the road.

Ultimately if you are aiming to make a game I would recommend LibGDX. I recommend this to all beginners because (a) it's easier to use than Swing/Java2D for a game, (b) it allows you to write a game without re-inventing the wheel, (c) it includes tons of documentation and examples often written by very skilled programmers (even full open-source games), (d) it will always out-perform Java2D for sprite rendering, and (e) it can distribute to Android, iOS and HTML5.

To show you how easy a menu would look in LibGDX, using a slightly more thought out design:

http://www.java-gaming.org/topics/easy-way-to-click-an-image/29386/msg/269651/view.html#msg269651

The code is flexible and it should be straight-forward to add or remove buttons to your menu. The result looks something like this:



Of course, you can use images instead of the default UI skin, and re-position them to your liking (using alignment, padding, or what have you).

Offline Slyth2727
« Reply #2 - Posted 2013-04-28 23:18:36 »

As I said, I know it's extremely messy. The numbers, they aren't random, I made them according to the size of the screen. Thank you very much for the link though, I will learn about enums, which I haven't ever taken a look at before.

Check out Escaping Vox, a 3D
|\ _\  voxel based puzzler!
 \|_|
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline davedes
« Reply #3 - Posted 2013-04-29 00:07:17 »

"Magic numbers" is a term describing an anti-pattern.

Generally code like this works better:
1  
2  
3  
4  
final float BUTTONS_Y_OFF = 50;

...
    ... drawRect( x, y + BUTTONS_Y_OFF, ...)


A better alternative would be to use resolution-independent layouts of some sort, even something simple like centering it to the frame or anchoring it 5 pixels from the bottom right corner.


Offline Slyth2727
« Reply #4 - Posted 2013-04-29 16:29:22 »

Th game loop was, as you said, a very messy one however this is only because it was used as a test. The actual game loop starts when the game itself gets going. Is this a problem and shsould I run everything on one loop?

Check out Escaping Vox, a 3D
|\ _\  voxel based puzzler!
 \|_|
Offline davedes
« Reply #5 - Posted 2013-04-29 16:40:48 »

You should never use an infinite loop. Generally game loops look like this:
1  
2  
3  
4  
5  
6  
7  
create();

while (running) {
   ... render() ...
}

dispose();


At any time, running can be set to false which terminates the game loop.


Did you look into LibGDX? The example I posted is a fraction of the size of your code and should perform many times faster than anything Java2D is capable of.

Offline Slyth2727
« Reply #6 - Posted 2013-04-30 01:41:18 »

Yes, I decided a long while back that I was going to learn libGDX once I was done with this game. I am very happy with this, as I am almost done with the game by now! So here I come libGDX! Cheesy In the meantime, I will certainly look at these examples!

Check out Escaping Vox, a 3D
|\ _\  voxel based puzzler!
 \|_|
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (51 views)
2014-04-15 18:08:23

BurntPizza (48 views)
2014-04-15 03:46:01

UprightPath (63 views)
2014-04-14 17:39:50

UprightPath (45 views)
2014-04-14 17:35:47

Porlus (62 views)
2014-04-14 15:48:38

tom_mai78101 (86 views)
2014-04-10 04:04:31

BurntPizza (146 views)
2014-04-08 23:06:04

tom_mai78101 (243 views)
2014-04-05 13:34:39

trollwarrior1 (202 views)
2014-04-04 12:06:45

CJLetsGame (209 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!