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:
/*
* VAST GAME EXECUTING CLASS (Version 0.1)
*
* The purpose of this class will be to run the actual game manager that controls all of VAST's constituents. For
* this version, it will simply show a simple title screen, allow the user to create a level of his or her choice to
* render, and then allow the player to explore the level. The player may then break any block within the level of his
* or her choosing. If the player wishes to exit, they may press ESCAPE, at which point a prompt will verify that the
* player wishes to terminate. Version 1.0 does not save any data nor contain items or enemies.
*/
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
{
// level renderer object to actually display the level
private static LevelRenderer myRenderer;
// level object to store the needed tiles and methods
private Level myLevel;
// screen object
private Screen s;
// back buffer
private static BufferStrategy buffer;
// boolean to keep track of the game's running
private boolean endGame = false;
// Graphics object for the buffer strategy
private Graphics graphics;
// int to represent which layer of the menu the player is in
private int menuLayer = 0;
// CONSTRUCTOR
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);
}
});
}
// execution of VastGame JFrame
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();
}
// updating method
public void update()
{
// get new draw graphics
graphics = buffer.getDrawGraphics();
}
// rendering method for the menus
public void render()
{
switch (menuLayer)
{
// title screen with logo and "click to continue"
case 0:
// display frames per second...
graphics.setFont( new Font( "Courier New", Font.PLAIN, 28 ) );
graphics.setColor( Color.GREEN );
graphics.drawString( "Welcome to the game!", 20, 20 );
break;
// menu layer with "create a level" and "exit"
case 1:
break;
// menu layer with all of the level types
case 2:
break;
// menu layer with "loading"
case 3:
break;
}
}
// process key input
private void processKey(KeyEvent e)
{
int keyCode = e.getKeyCode();
// termination key
if (keyCode == KeyEvent.VK_ESCAPE)
{
endGame = true;
}
// start renderer
if (keyCode == KeyEvent.VK_ENTER)
{
// add renderer panel to the frame
this.getContentPane().add(myRenderer);
// run the renderer
myRenderer.run(new DisplayMode(1280, 768, 32, DisplayMode.REFRESH_RATE_UNKNOWN));
}
}
// process release of key
private void processRelease(KeyEvent e)
{
}
// restore screen of the game's JFrame
public void restoreScreen()
{
s.restoreScreen();
}
// point of execution
public static void main(String args[])
{
VastGame myGame = new VastGame();
// display mode passed to the renderer
DisplayMode dm = new DisplayMode(1280, 768, 32, DisplayMode.REFRESH_RATE_UNKNOWN);
// run the game's code (basic menu system to lead to the renderer)
myGame.run(dm);
// restore screen when done with
myGame.restoreScreen();
}
}
And the renderer’s JPanel code:
/* This class's job is to manage a Player and Level object and call their render and update routines. */
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
{
//
// CONSTANTS
//
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;
//
// END OF CONSTANTS
//
// back buffer
private BufferStrategy buffer;
// character object
private Player myPlayer;
// level object
private Level myLevel;
// screen object
private Screen s;
// Graphics object for the buffer strategy
private Graphics graphics;
// boolean to determine when to end the game
private boolean endGame;
// Variables for counting frames per second
private int fps = 0;
private int frames = 0;
private long totalTime = 0;
private long curTime = System.currentTimeMillis();
private long lastTime = curTime;
// thread sleep count variables
private long now = 0;
private long rest = now;
// CONSTRUCTOR
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;
}
// method to simply load an image from a path
public static BufferedImage loadImage(String ref)
{
BufferedImage bimg = null;
try
{
bimg = ImageIO.read(new File(ref));
}
catch (Exception e)
{
e.printStackTrace();
}
return bimg;
}
// Run method for class
public void run(DisplayMode dm)
{
setBackground(Color.WHITE);
while (!endGame)
{
update();
render();
}
}
// method to update player and level
private void update()
{
// count Frames per second...
lastTime = curTime;
curTime = System.currentTimeMillis();
totalTime += curTime - lastTime;
if( totalTime > 1000 )
{
totalTime -= 1000;
fps = frames;
frames = 0;
}
++frames;
// get first reference to calculate sleep time
now = System.currentTimeMillis();
// edit/draw player and level
myPlayer.animatePlayer();
myLevel.updateOffsets();
}
// method to render player, level, and FPS
private void render()
{
// draw level and player
myLevel.drawLevel(graphics, 0, 0);
myPlayer.drawPlayer(graphics, (SCREEN_WIDTH / 2) - PLAYER_WIDTH / 2, (SCREEN_HEIGHT / 2) - PLAYER_HEIGHT / 2);
myLevel.drawCollision(graphics);
// display frames per second...
graphics.setFont( new Font( "Courier New", Font.PLAIN, 12 ) );
graphics.setColor( Color.GREEN );
graphics.drawString( String.format( "FPS: %s", fps ), 20, 20 );
// calculate sleep time
rest = 1000 / 60 - (System.currentTimeMillis() - now);
if (rest < 0)
{
rest = 0;
}
// dispose graphics
graphics.dispose();
}
// method to handle inputs and adjust the player accordingly
public void processKey(KeyEvent e)
{
int keyCode = e.getKeyCode();
boolean moved = false;
int xDisplace, yDisplace;
// termination key
if (keyCode == KeyEvent.VK_ESCAPE)
{
endGame = true;
}
// 0 - up
// 1 - left
// 2 - right
// 3 - down
// 4 - jump
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;
}
}
// method to handle inputs and adjust the player accordingly
public void processRelease(KeyEvent e)
{
int keyCode = e.getKeyCode();
boolean moved = false;
int xDisplace, yDisplace;
// 0 - up
// 5 - left
// 6 - right
// 3 - down
// 4 - jump
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