coltonoscopy
JGO n00b  Posts: 27 Medals: 1
|
 |
«
on:
2011-11-06 19:43:23 » |
|
Hey, everybody! I've been working on incorporating my tile engine into an actual menu-driven interface. I realized it didn't make any sense that I was having my renderer component act as a JFrame when I should rather be using it as a JPanel to be contained within a JFrame, so I made some changes to both the renderer and the new program I created to act as the menu wrapper for the renderer. What I wanted to do was have the JFrame (VastGame) run and display some menu options for the player. Right now, it just has a little message and allows the player to press Enter to switch to the renderer. The renderer was working perfectly beforehand, so I think I just messed up changing things around and making the renderer a JPanel instead of a JFrame, which it used to be. Upon pressing Enter, the message stays there rather than disappears but shows the renderer at a standstill, flickering in the background. I suppose this must mean they both run at the same time, without the renderer updating itself, so if anybody could offer some advice or assistance in how I could accomplish what I sought out to do, which is switch control between the menu display within the JFrame and the renderer's display through the JPanel, I would be much appreciative. :] Here is the code for both relevant classes: The new menu class and JFrame, VastGame: 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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
| import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import javax.imageio.*; import javax.swing.JFrame; import javax.swing.*; import java.util.Random; import java.awt.Color; public class VastGame extends JFrame { private static LevelRenderer myRenderer; private Level myLevel; private Screen s; private static BufferStrategy buffer; private boolean endGame = false; private Graphics graphics; private int menuLayer = 0; public VastGame() { setPreferredSize(new Dimension(1280, 768)); setIgnoreRepaint( true ); setUndecorated( true );
setFocusable(true); requestFocus(); setResizable(false); addKeyListener( new KeyAdapter() { public void keyPressed(KeyEvent e) { processKey(e); } public void keyReleased(KeyEvent e) { processRelease(e); } }); } public void run(DisplayMode dm) { setBackground(Color.BLACK); s = new Screen(); s.setFullScreen(dm, this); this.createBufferStrategy( 2 ); buffer = this.getBufferStrategy(); myRenderer = new LevelRenderer(buffer); while (!endGame) { do { do { try { update(); render(); } catch (Exception ex) { System.err.println("Game Update Error: " + ex); } try { Thread.sleep(10); } catch (Exception ex) { System.out.println("Can't sleep!"); } } while (buffer.contentsRestored()); buffer.show(); } while (buffer.contentsLost()); } s.restoreScreen(); } public void update() { graphics = buffer.getDrawGraphics(); } public void render() { switch (menuLayer) { case 0: graphics.setFont( new Font( "Courier New", Font.PLAIN, 28 ) ); graphics.setColor( Color.GREEN ); graphics.drawString( "Welcome to the game!", 20, 20 ); break; case 1: break; case 2: break; case 3: break; } } private void processKey(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_ESCAPE) { endGame = true; } if (keyCode == KeyEvent.VK_ENTER) { this.getContentPane().add(myRenderer); myRenderer.run(new DisplayMode(1280, 768, 32, DisplayMode.REFRESH_RATE_UNKNOWN)); } } private void processRelease(KeyEvent e) { } public void restoreScreen() { s.restoreScreen(); } public static void main(String args[]) { VastGame myGame = new VastGame(); DisplayMode dm = new DisplayMode(1280, 768, 32, DisplayMode.REFRESH_RATE_UNKNOWN); myGame.run(dm); myGame.restoreScreen(); } }
|
And the renderer's JPanel code: 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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
| import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import javax.imageio.*; import javax.swing.JFrame; import javax.swing.*; import java.util.Random; import java.awt.Color;
public class LevelRenderer extends JPanel { private final int TILE_SIZE = 32; private final int SCREEN_WIDTH = 1280; private final int SCREEN_HEIGHT = 768; private final int PLAYER_HEIGHT = 28; private final int PLAYER_WIDTH = 14; private BufferStrategy buffer; private Player myPlayer; private Level myLevel; private Screen s; private Graphics graphics; private boolean endGame; private int fps = 0; private int frames = 0; private long totalTime = 0; private long curTime = System.currentTimeMillis(); private long lastTime = curTime; private long now = 0; private long rest = now; public LevelRenderer(BufferStrategy bs) { setPreferredSize(new Dimension(1280, 768)); setIgnoreRepaint( true );
setFocusable(true); requestFocus(); graphics = bs.getDrawGraphics(); addKeyListener( new KeyAdapter() { public void keyPressed(KeyEvent e) { processKey(e); } public void keyReleased(KeyEvent e) { processRelease(e); } }); myPlayer = new Player(); myLevel = new Level("obstaclemap"); endGame = false; } public static BufferedImage loadImage(String ref) { BufferedImage bimg = null; try { bimg = ImageIO.read(new File(ref)); } catch (Exception e) { e.printStackTrace(); } return bimg; } public void run(DisplayMode dm) { setBackground(Color.WHITE);
while (!endGame) { update(); render(); } } private void update() { lastTime = curTime; curTime = System.currentTimeMillis(); totalTime += curTime - lastTime; if( totalTime > 1000 ) { totalTime -= 1000; fps = frames; frames = 0; } ++frames; now = System.currentTimeMillis(); myPlayer.animatePlayer(); myLevel.updateOffsets(); } private void render() { myLevel.drawLevel(graphics, 0, 0); myPlayer.drawPlayer(graphics, (SCREEN_WIDTH / 2) - PLAYER_WIDTH / 2, (SCREEN_HEIGHT / 2) - PLAYER_HEIGHT / 2); myLevel.drawCollision(graphics); graphics.setFont( new Font( "Courier New", Font.PLAIN, 12 ) ); graphics.setColor( Color.GREEN ); graphics.drawString( String.format( "FPS: %s", fps ), 20, 20 ); rest = 1000 / 60 - (System.currentTimeMillis() - now); if (rest < 0) { rest = 0; } graphics.dispose(); } public void processKey(KeyEvent e) { int keyCode = e.getKeyCode(); boolean moved = false; int xDisplace, yDisplace; if (keyCode == KeyEvent.VK_ESCAPE) { endGame = true; } switch (keyCode) { case KeyEvent.VK_UP: myPlayer.updatePlayer(0); myLevel.updateLevel(0); break; case KeyEvent.VK_LEFT: myPlayer.updatePlayer(1); myLevel.updateLevel(1); break; case KeyEvent.VK_RIGHT: myPlayer.updatePlayer(2); myLevel.updateLevel(2); break; case KeyEvent.VK_DOWN: myPlayer.updatePlayer(3); myLevel.updateLevel(3); break; case KeyEvent.VK_SPACE: myPlayer.updatePlayer(4); break; } } public void processRelease(KeyEvent e) { int keyCode = e.getKeyCode(); boolean moved = false; int xDisplace, yDisplace; switch (keyCode) { case KeyEvent.VK_UP: myPlayer.updatePlayer(0); myLevel.updateLevel(5); break; case KeyEvent.VK_LEFT: myPlayer.updatePlayer(5); myLevel.updateLevel(6); break; case KeyEvent.VK_RIGHT: myPlayer.updatePlayer(6); myLevel.updateLevel(7); break; case KeyEvent.VK_DOWN: myPlayer.updatePlayer(3); myLevel.updateLevel(8); break; case KeyEvent.VK_SPACE: myPlayer.updatePlayer(4); break; } } }
|
Thank you guys for your help! :] Best regards, Colton
|
|
|
|
|
ra4king
JGO Kernel      Posts: 3156 Medals: 196
I'm the King!
|
 |
«
Reply #1 on:
2011-11-06 20:09:21 » |
|
Couple questions: #1. Why does LevelRenderer extend JPanel? #2. There is a while loop inside LevelRenderer's run method that does nothing but update and render. This method should return back to processKey(KeyEvent) so VastGame can call buffer.show() There are too many other things wrong in your code but lets deal with those two for now 
|
|
|
|
coltonoscopy
JGO n00b  Posts: 27 Medals: 1
|
 |
«
Reply #2 on:
2011-11-06 20:43:01 » |
|
ra4king, Thank you for your reply! I extended LevelRenderer to be a JPanel because it was my understanding that it could become a component of a JFrame and so that I could have multiple classes like it for different parts of my game (overworld, level renderer, menu, etc.). Initially, I looked into implementing it as a Canvas and read that JPanels are much more effective. As for the buffer.show() problem, I just spent a few minutes fixing that and will show the code below. It now lets me exit the game with ESCAPE like I desired previously, but the renderer still does not update at all and stays at 0 FPS. Here is the updated class code. Since you said there are many problems with it, I would also like to know these when the time is right, for I want to make sure I am doing everything properly. :] VastGame: 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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
| import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import javax.imageio.*; import javax.swing.JFrame; import javax.swing.*; import java.util.Random; import java.awt.Color; public class VastGame extends JFrame { private static LevelRenderer myRenderer; private Level myLevel; private Screen s; private static BufferStrategy buffer; private boolean endGame = false; private Graphics graphics; private int menuLayer = 0; private boolean rendererOn = false; public VastGame() { setPreferredSize(new Dimension(1280, 768)); setIgnoreRepaint( true ); setUndecorated( true );
setFocusable(true); requestFocus(); setResizable(false); addKeyListener( new KeyAdapter() { public void keyPressed(KeyEvent e) { processKey(e); } public void keyReleased(KeyEvent e) { processRelease(e); } }); } public void run(DisplayMode dm) { setBackground(Color.BLACK); s = new Screen(); s.setFullScreen(dm, this); this.createBufferStrategy( 2 ); buffer = this.getBufferStrategy(); myRenderer = new LevelRenderer(buffer); while (!endGame) { do { do { try { if (!rendererOn) { update(); render(); } else { myRenderer.update(); myRenderer.render(); } } catch (Exception ex) { System.err.println("Game Update Error: " + ex); } try { Thread.sleep(10); } catch (Exception ex) { System.out.println("Can't sleep!"); } } while (buffer.contentsRestored()); buffer.show(); } while (buffer.contentsLost()); } s.restoreScreen(); } public void update() { graphics = buffer.getDrawGraphics(); } public void render() { switch (menuLayer) { case 0: graphics.setFont( new Font( "Courier New", Font.PLAIN, 28 ) ); graphics.setColor( Color.GREEN ); graphics.drawString( "Welcome to the game!", 20, 20 ); break; case 1: break; case 2: break; case 3: break; } } private void processKey(KeyEvent e) { int keyCode = e.getKeyCode(); if (keyCode == KeyEvent.VK_ESCAPE) { endGame = true; } if (keyCode == KeyEvent.VK_ENTER) { this.getContentPane().add(myRenderer); rendererOn = true; } } private void processRelease(KeyEvent e) { } public void restoreScreen() { s.restoreScreen(); } public static void main(String args[]) { VastGame myGame = new VastGame(); DisplayMode dm = new DisplayMode(1280, 768, 32, DisplayMode.REFRESH_RATE_UNKNOWN); myGame.run(dm); myGame.restoreScreen(); } }
|
and LevelRenderer: 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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
| import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.io.*; import javax.imageio.*; import javax.swing.JFrame; import javax.swing.*; import java.util.Random; import java.awt.Color;
public class LevelRenderer extends JPanel { private final int TILE_SIZE = 32; private final int SCREEN_WIDTH = 1280; private final int SCREEN_HEIGHT = 768; private final int PLAYER_HEIGHT = 28; private final int PLAYER_WIDTH = 14; private BufferStrategy buffer; private Player myPlayer; private Level myLevel; private Screen s; private Graphics graphics; private boolean endGame; private int fps = 0; private int frames = 0; private long totalTime = 0; private long curTime = System.currentTimeMillis(); private long lastTime = curTime; private long now = 0; private long rest = now; public LevelRenderer(BufferStrategy bs) { setPreferredSize(new Dimension(1280, 768)); setIgnoreRepaint( true );
setFocusable(true); requestFocus(); graphics = bs.getDrawGraphics(); addKeyListener( new KeyAdapter() { public void keyPressed(KeyEvent e) { processKey(e); } public void keyReleased(KeyEvent e) { processRelease(e); } }); myPlayer = new Player(); myLevel = new Level("obstaclemap"); endGame = false; } public static BufferedImage loadImage(String ref) { BufferedImage bimg = null; try { bimg = ImageIO.read(new File(ref)); } catch (Exception e) { e.printStackTrace(); } return bimg; } public void update() { lastTime = curTime; curTime = System.currentTimeMillis(); totalTime += curTime - lastTime; if( totalTime > 1000 ) { totalTime -= 1000; fps = frames; frames = 0; } ++frames; now = System.currentTimeMillis(); myPlayer.animatePlayer(); myLevel.updateOffsets(); } public void render() { myLevel.drawLevel(graphics, 0, 0); myPlayer.drawPlayer(graphics, (SCREEN_WIDTH / 2) - PLAYER_WIDTH / 2, (SCREEN_HEIGHT / 2) - PLAYER_HEIGHT / 2); myLevel.drawCollision(graphics); graphics.setFont( new Font( "Courier New", Font.PLAIN, 12 ) ); graphics.setColor( Color.GREEN ); graphics.drawString( String.format( "FPS: %s", fps ), 20, 20 ); rest = 1000 / 60 - (System.currentTimeMillis() - now); if (rest < 0) { rest = 0; } graphics.dispose(); } public void processKey(KeyEvent e) { int keyCode = e.getKeyCode(); boolean moved = false; int xDisplace, yDisplace; if (keyCode == KeyEvent.VK_ESCAPE) { endGame = true; } switch (keyCode) { case KeyEvent.VK_UP: myPlayer.updatePlayer(0); myLevel.updateLevel(0); break; case KeyEvent.VK_LEFT: myPlayer.updatePlayer(1); myLevel.updateLevel(1); break; case KeyEvent.VK_RIGHT: myPlayer.updatePlayer(2); myLevel.updateLevel(2); break; case KeyEvent.VK_DOWN: myPlayer.updatePlayer(3); myLevel.updateLevel(3); break; case KeyEvent.VK_SPACE: myPlayer.updatePlayer(4); break; } } public void processRelease(KeyEvent e) { int keyCode = e.getKeyCode(); boolean moved = false; int xDisplace, yDisplace; switch (keyCode) { case KeyEvent.VK_UP: myPlayer.updatePlayer(0); myLevel.updateLevel(5); break; case KeyEvent.VK_LEFT: myPlayer.updatePlayer(5); myLevel.updateLevel(6); break; case KeyEvent.VK_RIGHT: myPlayer.updatePlayer(6); myLevel.updateLevel(7); break; case KeyEvent.VK_DOWN: myPlayer.updatePlayer(3); myLevel.updateLevel(8); break; case KeyEvent.VK_SPACE: myPlayer.updatePlayer(4); break; } } }
|
Thanks again!
|
|
|
|
|
Games published by our own members! Go get 'em!
|
|
ra4king
JGO Kernel      Posts: 3156 Medals: 196
I'm the King!
|
 |
«
Reply #3 on:
2011-11-06 20:46:34 » |
|
Aha, the problem is that you are supposed to get a new Graphics object every frame. Move the line that says "graphics = bs.getDrawGraphics();" to the render() method in LevelRenderer.
EDIT: Also try using a debugger to run through your code line by line.
|
|
|
|
coltonoscopy
JGO n00b  Posts: 27 Medals: 1
|
 |
«
Reply #4 on:
2011-11-06 20:59:10 » |
|
Ah, brilliant and thank you! The transition is seamless now. The only problem is that my renderer won't take any input now :p Is there an easy fix to this?
Also, I do from time to time go into my debugger in Netbeans and test some things out, as well as profile my code, but I suppose I should do so more often. For some reason, I'm very comfortable doing things through the command line :p I'm sure I'll get used to and become favorable toward an IDE eventually.
Thanks for your help, ra4king!
EDIT: I was able to figure it out :] I just put the processKey methods from LevelRenderer into those in VastGame. If there is any more advice you'd be willing to share in regard to how I can refactor or improve my code, though, I'd be very thankful.
|
|
|
|
|
ra4king
JGO Kernel      Posts: 3156 Medals: 196
I'm the King!
|
 |
«
Reply #5 on:
2011-11-07 00:28:56 » |
|
Eclipse FTW!  EDIT: Oh and there is no point to extend JPanel since you are not adding the JPanel to the JFrame and you are getting the BufferStrategy from the JFrame.
|
|
|
|
coltonoscopy
JGO n00b  Posts: 27 Medals: 1
|
 |
«
Reply #6 on:
2011-11-07 02:39:39 » |
|
I used Eclipse in the past and was happy with it, as well. There was something about the aesthetics with Netbeans that appealed to me more, however, and the fact that it included the Javadoc integration so seamlessly, but I'm sure there's an Eclipse plugin that lets you do the same thing.
I hadn't realized through all the refactoring that I'd completely disregarded the getContentPane() call I'd used previously which had made me think I needed one. So what you're essentially saying is I could make LevelRenderer a class that simply interacts with and renders to the BufferStrategy? So I wouldn't in this sense ever really need a JPanel, just the BufferStrategy access, making my life much easier. If this is the case, then in which situation would I ever need a JPanel? I appreciate all your help. :]
Colton
|
|
|
|
|
theagentd
JGO Wizard     Posts: 1392 Medals: 88
|
 |
«
Reply #7 on:
2011-11-07 04:45:35 » |
|
Excuse me jumping straight into here, but I've had use for JFrames when I made a map editor. That way I could have one Canvas which my I drew the game at (I was using OpenGL, with Java2D you can just use a JFrame there), one for a tile chooser and a last one for a menu at the bottom of the screen. It's convenient because you can easily change the layout of the components and get automatic resizing/interaction of everything through a layout manager. BorderLayout was awesome for this.
|
There is no god.
|
|
|
coltonoscopy
JGO n00b  Posts: 27 Medals: 1
|
 |
«
Reply #8 on:
2011-11-07 05:16:40 » |
|
Excuse me jumping straight into here, but I've had use for JFrames when I made a map editor. That way I could have one Canvas which my I drew the game at (I was using OpenGL, with Java2D you can just use a JFrame there), one for a tile chooser and a last one for a menu at the bottom of the screen. It's convenient because you can easily change the layout of the components and get automatic resizing/interaction of everything through a layout manager. BorderLayout was awesome for this.
lol theagentd, You're more than welcome to join in wherever you want. You've helped me a lot in the little time I've been here already. On top of that, I want to hear everything everyone wants or has to say if it concerns me and Java game development. The multi-component interaction aspect does make sense. Once I expand my current game build to incorporate a more robust interface, I'll surely end up experimenting with and experiencing these intricacies and layouts. For some aspects of my game, there will end up being parts that will require the kind of complexity you might find in something like a map editor, like for my eventual alchemy system. This whole process has been something of an adventure for me, because my experience with programming has been more on traditional programming aspects rather than GUI and event-based programming. That, and it's been encouraging me to learn more about data structures. Everything I've been intending to accomplish has been mentally conceived without regard necessarily for the implementation details; I figure with tutorials, reading, API documentation, and kind people such as those I may find here ( O:] ), I can find the way. Thanks for the input, theagentd! Colton
|
|
|
|
|
|