I have a problem where my JFrame is constantly flashing white and black, but I only set the colour to black. I think it has to do with the while (running) {} bit.
It just turns white and black forever, until I close it. I really don't know what is going on.. I only just started to use JFrame so I'm sure I have just put some wrong code.
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static int width = 300;
public static int height = width / 16 * 9;
public static int scale = 3;
public static boolean running = false;
private Thread thread;
private JFrame frame;
public Game() {
Dimension window = new Dimension(width * scale, height * scale);
setPreferredSize(window);
frame = new JFrame();
}
public synchronized void start() {
running = true;
thread = new Thread(this, "Display");
thread.start();
}
public synchronized void stop() {
try {
running = false;
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
while (running) {
render();
}
}
public void update() {
}
public void render() {
BufferStrategy buffer = getBufferStrategy();
if (buffer == null) {
createBufferStrategy(3);
return;
}
Graphics g = buffer.getDrawGraphics();
g.setColor(Color.BLACK);
g.drawRect(0, 0, getWidth(), getHeight());
g.dispose();
buffer.show();
}
public static void main(String[] args) {
Game game = new Game();
game.frame.setResizable(false);
game.frame.setTitle("Game");
game.frame.add(game);
game.frame.pack();
game.frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
}
Solved it myself... I used the method drawRect() And I read the documentation page and it says it only draws the outline of the rectangle.. So I just did drawRect()
Also I changed the buffer to 2.
Sorry for wasting your time.
Related
Ok, so I'm new to programming and I'm following a tutorial on Youtube to build my own game. My problem is that my screen doesn't turn red, it just stays gray. I'm sure I did something wrong but there are no errors on eclipse. Here is the code:
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static int width = 300;
public static int height = width / 16 * 9;
public static int scale = 3;
private Thread thread;
private JFrame frame;
private boolean running = false;
public Game() {
Dimension size = new Dimension(width * scale, height * scale);
setPreferredSize(size);
frame = new JFrame();
}
public synchronized void start() {
running = true;
thread = new Thread("Display");
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch(InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
while (running) {
update();
render();
}
}
public void update() {
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.RED);
g.fillRect(0, 0, getWidth(), getHeight());
g.dispose();
bs.show();
}
public static void main(String[] args){
Game game = new Game();
game.frame.setResizable(false);
game.frame.setTitle("JJF");
game.frame.add(game);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
}
You never actually provide the Thread with something to run...
public synchronized void start() {
running = true;
// Not the reference to this...
thread = new Thread(this, "Display");
thread.start();
}
By passing this (which is an instance of your Game class which implements Runnable), the Thread will be able to call your run method
nb:
The size of your viewable area should be defined by the component, not the frame. This can be achieved by overriding the getPreferredSize method and returning the preferred viewable size you want the component to be. Otherwise, the viewable area will be the size of the frame minus it's decoration insets, which may not meet your expectations.
In your "game-loop" you should consider having a small delay between cycles to give time for the system to actually update the screen, this takes some of the pressure of the Thread
Runnable example
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static int width = 300;
public static int height = width / 16 * 9;
public static int scale = 3;
private Thread thread;
private JFrame frame;
private boolean running = false;
public Game() {
Dimension size = new Dimension(width * scale, height * scale);
setPreferredSize(size);
frame = new JFrame();
}
public synchronized void start() {
running = true;
thread = new Thread(this, "Display");
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
while (running) {
update();
render();
// try {
// Thread.sleep(40);
// } catch (InterruptedException ex) {
// }
}
}
public void update() {
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.RED);
g.fillRect(0, 0, getWidth(), getHeight());
g.dispose();
bs.show();
}
public static void main(String[] args) {
Game game = new Game();
game.frame.setResizable(false);
game.frame.setTitle("JJF");
game.frame.add(game);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm trying to learn Java and game programming by myself by just playing around with some different things. But now I have come across this problem, when my java app goes fullscreen via GraphicsDevice, the KeyListeners don't work. It's like it doesn't register anything when I press the buttons on my keyboard. When the app isn't fullscreen, everything works as it is supposed to.
I am using Mac.
The code is a bit messy, but it should be somewhat easy to navigate etc.
Game.class
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
// Render Vars
public static final int WIDTH = 1280;
public static final int HEIGHT = 800; //WIDTH / 16 *
public static final int SCALE = 1;
public final static String TITLE = "Test Game - inDev 1.0.0";
public static boolean fullscreen = false;
public static JFrame window = new JFrame(TITLE);
public static Font defaultFont = new Font("Dialog", Font.PLAIN, 12);
public static Color defaultColor = Color.gray;
// Thread Vars
public static boolean running = false;
private static Thread thread;
private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
// Mechanic Vars
public static boolean mouseDown;
public static int mouseX;
public static int mouseY;
// Game Vars
public static GameState gameState = new Play();
public static boolean keyPressed;
public static Game game = new Game();
public static void main(String arghs[]) {
game.setSize(new Dimension(WIDTH, HEIGHT));
game.setPreferredSize(new Dimension(WIDTH, HEIGHT));
fullscreen = true;
window.add(game);
window.setUndecorated(true);
window.pack();
window.setLocationRelativeTo(null);
window.setResizable(false);
window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
window.setVisible(true);
// HERE I GO FULLSCREEN
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(window);
game.addKeyListener(new KeyEventListener());
game.addMouseListener(new MouseEventListener());
game.start();
}
public void run() {
init();
long lastTime = System.nanoTime();
final double numTicks = 100.0;
double ns = 1000000000 / numTicks;
double delta = 0;
int updates = 0;
int frames = 0;
long timer = System.currentTimeMillis();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if (delta >= 1) {
update();
updates++;
delta--;
}
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " Ticks, FPS: " + frames);
updates = 0;
frames = 0;
}
}
stop();
}
private synchronized void start() {
if (running) {
return;
}
running = true;
thread = new Thread(this);
thread.setName("My Game");
thread.start();
}
public synchronized static void stop() {
if (!running) {
return;
}
running = false;
thread = null;
System.exit(1);
}
private void init() {
gameState.init();
}
private void update() {
gameState.update();
}
private void render() {
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setColor(defaultColor);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
// Draw Content
gameState.render(g);
// Draw to Screen;
g.dispose();
bs.show();
}
public static void setGameState(GameState state) {
gameState = state;
gameState.init();
}
}
KeyEventListener.class
public class KeyEventListener extends KeyAdapter {
public void keyPressed(KeyEvent e) {
if (!Game.keyPressed) {
Game.gameState.keyPressed(e);
}
Game.keyPressed = true;
}
public void keyReleased(KeyEvent e) {
Game.gameState.keyReleased(e);
Game.keyPressed = false;
}
}
MouseEventListener.class (Just for recording the mouse position)
public class MouseEventListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
Game.mouseDown = true;
}
public void mouseReleased(MouseEvent e) {
Game.mouseDown = false;
}
public void mouseMoved(MouseEvent e) {
Game.mouseX = e.getX();
Game.mouseY = e.getY();
}
public void mouseDragged(MouseEvent e) {
Game.mouseX = e.getX();
Game.mouseY = e.getY();
}
}
GameState.class
public abstract class GameState {
public abstract void init();
public abstract void update();
public abstract void render(Graphics g);
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
}
And my Play.class which is the current gameState
public class Play extends GameState {
public static int key;
public void init() {
}
public void update() {
}
public void render(Graphics g) {
g.drawString("Key: " + key, 100, 100);
}
public void keyPressed(KeyEvent e) {
key = e.getKeyCode();
}
public void keyReleased(KeyEvent e) {
}
}
KeyListener will only respond to key events when the component is registered to is focusable and has focus.
After you have set the window to full screen, try adding...
game.requestFocusInWindow();
You may also need to use game.setFocusable(true)
If it wasn't for the fact that you're using a Canvas, I'd suggest using the key bindings API to over all these focus issues
Updated
I added...
window.addWindowFocusListener(new WindowAdapter() {
#Override
public void windowGainedFocus(WindowEvent e) {
System.out.println("gainedFocus");
if (!game.requestFocusInWindow()) {
System.out.println("Could not request focus");
}
}
});
To the window after it was visible but before it was made full screen
Updated
Oh, you're going to love this...
Based on this question: FullScreen Swing Components Fail to Receive Keyboard Input on Java 7 on Mac OS X Mountain Lion
I added setVisible(false) followed by setVisible(true) after setting the window to full screen mode and it seems to have fixed it...
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().setFullScreenWindow(window);
window.setVisible(false);
window.setVisible(true);
Verified running on Mac, using Java 7
Why am I getting a Blank screen instead of Black when I debug or run?? I've looked everywhere and tried a lot! Please help. I'm just trying to make my screen black as I am a beginner to all of this java coding. I don't believe anything is wrong with the code as I'm not getting any errors. I'm using eclipse.
package com.techon.rain;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static int width =300;
public static int height = width / 16 * 9;
public static int scale =3;
private JFrame frame;
private Thread thread;
private boolean running = false;
public Game() {
Dimension size = new Dimension(width*scale, height*scale);
setPreferredSize(size);
frame = new JFrame();
}
public synchronized void start() {
running = true;
thread = new Thread(this, "Display");
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
while(running);{
update();
render();
}
}
public void update() {
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if(bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0,0,getWidth(),getHeight());
g.dispose();
bs.show();
}
public static void main(String[] args) {
Game game = new Game();
game.frame.setResizable(false);
game.frame.setTitle("Rain");
game.frame.add(game);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
}
replace
public void run() {
while(running);{
update();
render();
}
by
public void run() {
while(running){
update();
render();
}
due to while(running); it is not executing other stetement inside loop.
I've been trying to fix but it never changes the screen. I'm trying to used the Graphics as seen in the render() method. Tell me if something is wrong inside the render method so I can relax, because I can't seem to find the problem.
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.*;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static int width = 300;
public static int height = width / 16*9;
public static int scale = 3;
private Thread thread;
private boolean running = false;
private JFrame frame;
public synchronized void start() {
thread = new Thread();
thread.start();
running = true;
}
public synchronized void stop() {
running = false;
try{
thread.join();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
public Game() {
Dimension size = new Dimension(width * scale, height * scale);
setPreferredSize(size);
frame = new JFrame();
}
public void run() {
while(running) {
tick();
render();
}
}
void tick() {}
public void render() {
BufferStrategy bs = getBufferStrategy();
if(bs==null){
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
bs.dispose();
bs.show();
}
public static void main(String[] args) {
Game game = new Game();
game.frame.setResizable(false);
game.frame.setTitle("Rain");
game.frame.add(game);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
}
Let me give you a stack trace of your error.
Your render method is not even being called here.
This is because your run method is not being called at all.
The reason behind all this is that you have not passed correct Runnable object at the time of Thread creation. It creates a Thread with empty run.
In your start method, just replace
thread = new Thread();
with
thread = new Thread(this);
And it should work.
Hope this helps. Enjoy.
I'm trying to learn to program my first game and I would like to understand correctly every step I make. I'll face double buffering and other things later.
I'm just trying to load an image in the game loop.
I have two classes. The first it's just a jframe calling the start method.
I wonder if there is some ugly code, in here (I think so).
So, why are my images not showing up?
public class myPanel extends JPanel implements Runnable{
//FIELDS
public static int WIDTH = 1024;
public static int HEIGHT = WIDTH / 16 * 9;
private BufferedImage bg;
private BufferedImage charac;
private boolean running;
private Thread t1;
private int startposX = WIDTH / 2;
private int startposY = HEIGHT / 2;
private int cordX = startposX;
private int cordY = startposY;
int speed = 50;
//METHODS
public synchronized void start (){
running = true;
t1 = new Thread (this);
t1.start();
}
public synchronized void stop (){
running = false;
try {
t1.join();
System.out.println("The game stopped");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//INIT
public myPanel(){
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
requestFocus();
addKeyListener(this);
}
//MAIN RUN METHOD
public void run(){
while (running){
load();
System.out.println("The game runs");
repaint();
}
}
//PAINT WITH GRAPHICS METHOD
public void paint (Graphics g){
super.paint(g);
g.drawImage(bg, 0, 0, this);
g.drawImage(charac, 110, 280, this);
}
//LOAD IMAGES IN MEMORY
public void load (){
try {
String path1 = "res/bg.png";
bg = ImageIO.read(new File (path1));
String path2 = "res/charac.png";
charac = ImageIO.read(new File (path2));
} catch (IOException e) {
e.printStackTrace();
}
}
So, I did some testing about paint vs paintcomponent and I just saw that the first draws on top of the jpanel background. Anyway, I can't still see anything changing the lines to
public void run(){
while (running){
load();
System.out.println("The game runs");
}
}
//PAINT WITH GRAPHICS METHOD
public void paintComponent (Graphics g){
super.paint(g);
g.drawImage(bg, 0, 0, null);
g.drawImage(charac, 110, 280, null);
}
//LOAD IMAGES METHOD AS ABOVE
And yes, I've added the panel to the frame, here is the other class
public class Game {
public static void main (String [] args){
JFrame frame = new JFrame();
frame.setIgnoreRepaint(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new myPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
myPanel game = new myPanel();
game.start();
}