Java game won't read image file - java

For some reason, my program can't find an image. I've tried absolutely everything and made sure the file path is exact. It worked fine in my previous game but now it just won't find the image at all.
Entity class
package Entities;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Entity
{
public double x, y, width, height, dx, dy;
public BufferedImage image;
public Entity(String s)
{
try
{ //error occurs here
image = ImageIO.read(getClass().getResourceAsStream(s));
}
catch (IOException e)
{
e.printStackTrace();
}
width = image.getWidth();
height = image.getHeight();
}
public void update()
{
x += dx;
y += dy;
}
public void draw(Graphics2D g)
{
g.drawImage(image, (int)x, (int)y, null);
}
}
GamePanel class
package Main;
//import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import Entities.Entity;
#SuppressWarnings("serial")
public class GamePanel extends JPanel implements Runnable, KeyListener
{
public static final int WIDTH = 320;
public static final int HEIGHT = 240;
public static final int SCALE = 2;
//game thread
private Thread thread;
private boolean running;
private int fps = 60;
private long targetTime = 1000/fps;
//image
private BufferedImage image;
private Graphics2D g;
//test
public Entity e;
public GamePanel()
{
super();
setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setFocusable(true);
requestFocus();
}
public void addNotify()
{
super.addNotify();
if(thread == null)
{
thread = new Thread(this);
addKeyListener(this);
thread.start();
}
}
public void init()
{
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D) image.getGraphics();
running = true;
e = new Entity("Resources/Test/test.png");
}
#Override
public void keyPressed(KeyEvent key)
{
//p1.keyPressed(key.getKeyCode());
}
#Override
public void keyReleased(KeyEvent key)
{
//p1.keyReleased(key.getKeyCode());
}
#Override
public void keyTyped(KeyEvent arg0)
{
}
#Override
public void run()
{
init();
long start;
long elapsed;
long wait;
//game loop
while(running)
{
start = System.nanoTime();
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed/1000000;
if(wait < 0)
{
wait = 5;
}
try
{
Thread.sleep(wait);
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
private void drawToScreen()
{
Graphics g2 = getGraphics();
g2.drawImage(image, 0, 0, WIDTH * SCALE, HEIGHT * SCALE, null);
g2.dispose();
}
private void draw()
{
//e.draw(g);
}
private void update()
{
}
}
This is the error
Exception in thread "Thread-2" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(Unknown Source)
at Entities.Entity.<init>(Entity.java:19)
at Main.GamePanel.init(GamePanel.java:67)
at Main.GamePanel.run(GamePanel.java:93)
at java.lang.Thread.run(Unknown Source)

A path Resources/Test/test.png suggest a relative path from the location of the class reference used to try and load it.
Since you are using your Entity class to try and load the image, and Entity resides in the Entities package, this will generate an absolute path (from the context of the class path) of /Entities/Resources/Test/test.png, which is obviously incorrect.
Try using /Resources/Test/test.png instead (assuming the Resources resides at the top of the path tree, for example...
+ Resources
+ Test
- test.png
+ Entities
- Entity
+ Main
- GamePanel

Related

Java 2D Help improve scrolling image; remove tearing(?) make smooter etc

I am a hobbyist attempting to implement some classics in Java 2D. I have problems getting some background images to scroll properly. Main problem seems to be the occurence of what I believe is called Tearing, ie old parts of "frames" are displayed giving a flickering effect in some parts of the image. Google tells me that it is probably related to missing VSYNC in windowed Java applications, and that it is impossible/very difficult to fix completely. However before giving up I thought to try asking here.
I have assembeled the code below as a bare bone example to illustrate the problem.
Any help of improving this code to reduce the Tearing/flickering would be much appreciated.
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class ScrollTest {
private static int WIDTH = 320, HEIGHT = 240;
public static void main(String[] args) {
//System.setProperty("sun.java2d.opengl","True"); //Does not seem to make any difference
new ScrollTest().run(WIDTH, HEIGHT, 4, 1, "ScrollTest");
}
private boolean isRunning;
protected JFrame window;
protected Canvas canvas;
private BufferStrategy bs;
private int FPS = 100;
private long targetTime = 1000 / FPS;
protected int width;
protected int height;
protected float scale;
protected float aspect;
protected String title;
protected BufferedImage screenImage;
private BufferedImage bgImage;
private int bgTop;
private float offsetX;
public void run(int width, int height, float scale, float aspect, String title) {
this.width = width;
this.height = height;
this.scale = scale;
this.aspect = aspect;
this.title = title;
isRunning = false;
try {
init();
isRunning = true;
gameLoop();
}
finally {
lazilyExit();
}
}
public void init() {
canvas = new Canvas();
canvas.setPreferredSize(new Dimension((int)(width*scale), (int)(height*scale*aspect)));
window = new JFrame();
window.getContentPane().add(canvas);
window.setResizable(false);
window.setTitle(title);
window.pack();
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
canvas.createBufferStrategy(3);
bs = canvas.getBufferStrategy();
screenImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//bgImage = loadBImage("res/res_DoubleDragon/Area 1_C_crop.png");
try {
bgImage = toCompatibleImage(ImageIO.read(new URL("https://spritedatabase.net/files/arcade/603/Background/Area1.png")));
} catch (Exception ex) {
ex.printStackTrace();
}
bgTop = HEIGHT-bgImage.getHeight(null)+20;
}
public BufferedImage loadBImage(String filename)
{
try {
return toCompatibleImage(ImageIO.read(new File(filename)));
} catch (IOException e) {
System.out.println("Image file not found");
return null;
}
}
public void gameLoop() {
long timestamp;
long usedTime;
long sleepTime;
long elapsedTime=0;
while (isRunning)
{
timestamp = System.nanoTime();
update(elapsedTime);
System.out.println(elapsedTime);
Graphics2D g = (Graphics2D)screenImage.getGraphics();
draw(g);
g.dispose();
Graphics2D g2 = (Graphics2D) bs.getDrawGraphics();
g2.scale(scale,scale*aspect);
g2.drawImage(screenImage,0,0,null);
bs.show();
g2.dispose();
usedTime = System.nanoTime() - timestamp;
sleepTime = targetTime - usedTime / 1000000;
if(sleepTime < 0) sleepTime = 5;
try {
Thread.sleep(sleepTime);
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
elapsedTime=(System.nanoTime()-timestamp) / 1000000;
}
}
public void update(long elapsedTime) {
offsetX -= .05f*elapsedTime;
offsetX = Math.min(offsetX, 0);
offsetX = Math.max(offsetX, WIDTH - bgImage.getWidth(null));
}
public void draw(Graphics2D g) {
g.setColor(Color.BLACK);
g.fillRect(0, 0, WIDTH, HEIGHT);
g.drawImage(bgImage, Math.round(offsetX), bgTop, null);
}
public void stop() {
isRunning = false;
}
/**
Exits the VM from a daemon thread. The daemon thread waits
2 seconds then calls System.exit(0). Since the VM should
exit when only daemon threads are running, this makes sure
System.exit(0) is only called if neccesary. It's neccesary
if the Java Sound system is running.
*/
public void lazilyExit() {
Thread thread = new Thread() {
public void run() {
// first, wait for the VM exit on its own.
try {
Thread.sleep(2000);
}
catch (InterruptedException ex) { }
// system is still running, so force an exit
System.exit(0);
}
};
thread.setDaemon(true);
thread.start();
}
private static final GraphicsConfiguration GFX_CONFIG = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
public static BufferedImage toCompatibleImage(BufferedImage image) {
/*
* if image is already compatible and optimized for current system settings, simply return it
*/
if (image.getColorModel().equals(GFX_CONFIG.getColorModel())) {
return image;
}
System.out.println("incompatible image");
// image is not optimized, so create a new image that is
final BufferedImage new_image = GFX_CONFIG.createCompatibleImage(image.getWidth(), image.getHeight(), image.getTransparency());
// get the graphics context of the new image to draw the old image on
final Graphics2D g2d = (Graphics2D) new_image.getGraphics();
// actually draw the image and dispose of context no longer needed
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
// return the new optimized image
return new_image;
}
}

how do I make this java awt/ swing animation work?

I'm pretty new to java coding, but i know the basic structures of how to code. I am not familiar with awt/swing, and don't know what my error is.
Background: I searched up ways to animate with java, found zetcode tutorials.
I copy/pasted their code, and tested the program, to make sure it works. the JFrame opened, but nothing drew. Maybe this is a system compatibility error? if so, how would I fix it?
these are the two separate classes:
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.JFrame;
public class ThreadAnimationExample extends JFrame {
public ThreadAnimationExample() {
initUI();
}
private void initUI() {
add(new Board());
setResizable(false);
pack();
setTitle("Star");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame ex = new ThreadAnimationExample();
ex.setVisible(true);
}
});
}
}
This is the main class.
Board.java
package com.zetcode;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Board extends JPanel
implements Runnable {
private final int B_WIDTH = 350;
private final int B_HEIGHT = 350;
private final int INITIAL_X = -40;
private final int INITIAL_Y = -40;
private final int DELAY = 25;
private Image star;
private Thread animator;
private int x, y;
public Board() {
initBoard();
}
private void loadImage() {
ImageIcon ii = new ImageIcon("star.png");
star = ii.getImage();
}
private void initBoard() {
setBackground(Color.BLACK);
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
setDoubleBuffered(true);
loadImage();
x = INITIAL_X;
y = INITIAL_Y;
}
#Override
public void addNotify() {
super.addNotify();
animator = new Thread(this);
animator.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
drawStar(g);
}
private void drawStar(Graphics g) {
g.drawImage(star, x, y, this);
Toolkit.getDefaultToolkit().sync();
}
private void cycle() {
x += 1;
y += 1;
if (y > B_HEIGHT) {
y = INITIAL_Y;
x = INITIAL_X;
}
}
#Override
public void run() {
long beforeTime, timeDiff, sleep;
beforeTime = System.currentTimeMillis();
while (true) {
cycle();
repaint();
timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;
if (sleep < 0) {
sleep = 2;
}
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
System.out.println("Interrupted: " + e.getMessage());
}
beforeTime = System.currentTimeMillis();
}
}
}
When I run the program, I get a blank black window. The program is supposed to draw a star. Here is what it is supposed to look like.

Game Applet not running in 2D game (while loop)

I'm trying to set the dimensions for this game i want to create. The error is at while(running); I went over it for an hour but i can't seem to catch the error. I'm using NetbeansIDE also setPreserredSize (new Dimension(WIDTH, HEIGHT)); gives me an error, it is asking to Create a method " setPrefferedSize(java.awt.Dimension)"in.com.francesc.game.Game
private void setPreserredSize(Dimension dimension) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
when i run it i get this error
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - illegal start of type
at com.francescstudio.game.Game.<init>(Game.java:67)
at com.francescstudio.game.Start.main(Start.java:16)
Java Result: 1
heres all the code
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
/**
*
* #author francesc
*/
public class Game extends JPanel implements KeyListener, Runnable {
public static final long SerialVersionUID = 1L;
public static final int WIDTH = 400;
public static final int HEIGHT = 630;
public static final Font main = new Font("Bebas Nue Regular", Font.PLAIN, 28);
private Thread game;
private boolean running;
private BufferedImage Image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private long startTime;
private long elapse;
private boolean set;
public Game() {
setFocusable(true);
setPreserredSize (new Dimension(WIDTH, HEIGHT));
addKeyListener(this);
}
private void update() {
}
private void render() {
Graphics2D g = (Graphics2D) Image.getGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, WIDTH, HEIGHT);
// render board
g.dispose();
Graphics2D g2d = (Graphics2D) getGraphics();
g2d.drawImage(Image, 0, 0, null);
g2d.dispose();
}
#Override
public void run() {
}
int fps = 0, update = 0;
long fpsTimer = System.currentTimeMillis();
double nsPerUpdate = 1000000000.0 / 60;
// last update time in nano seconds
double then = System.nanoTime();
double unprocessed = 0;
while (running){
boolean shouldRender = false;
double now = System.nanoTime();
unprocessed += (now - then) / nsPerUpdate;
then = now;
// update queque
while (unprocessed >= 1) {
update++;
update();
unprocessed--;
shouldRender = true;
}
// render
if (shouldRender) {
fps++;
render();
shouldRender = false;
} else {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public synchronized start(){
if(running)return;
running = true;
game = new Thread (this, "game");
game.start();
}
public synchronized stop (){
if(!running) return;
running = false;
System.exit(0);
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
}
Your problem is while (running) {} isn't inside of a method, you defined it in the class where it will never get called.
EDIT:
Your code should look something a little more like this
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
/**
*
* #author francesc
*/
public class Game extends JPanel implements KeyListener, Runnable {
public static final long SerialVersionUID = 1L;
public static final int WIDTH = 400;
public static final int HEIGHT = 630;
public static final Font main = new Font("Bebas Nue Regular", Font.PLAIN, 28);
private Thread game;
private boolean running;
private BufferedImage Image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private long startTime;
private long elapse;
private boolean set;
public Game() {
setFocusable(true);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
addKeyListener(this);
}
private void update() {}
private void render() {
Graphics2D g = (Graphics2D) Image.getGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, WIDTH, HEIGHT);
// render board
g.dispose();
Graphics2D g2d = (Graphics2D) getGraphics();
g2d.drawImage(Image, 0, 0, null);
g2d.dispose();
}
#Override
public void run() {
int fps = 0, update = 0;
long fpsTimer = System.currentTimeMillis();
double nsPerUpdate = 1000000000.0 / 60;
// last update time in nano seconds
double then = System.nanoTime();
double unprocessed = 0;
while (running) {
boolean shouldRender = false;
double now = System.nanoTime();
unprocessed += (now - then) / nsPerUpdate;
then = now;
// update queque
while (unprocessed >= 1) {
update++;
update();
unprocessed--;
shouldRender = true;
}
// render
if (shouldRender) {
fps++;
render();
shouldRender = false;
} else {
try {
Thread.sleep(1);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public synchronized start(){
if(running)return;
running = true;
game = new Thread (this, "game");
game.start();
}
public synchronized stop (){
if(!running) return;
running = false;
System.exit(0);
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
}

Thread Animation Example not working

I was trying to follow these tutorials http://zetcode.com/tutorials/javagamestutorial/animation/ and none of the three examples on that page seem to be working for me. One of them uses a swing timer, one uses the utility timer, and the last and supposedly most effective and accurate according to the page uses a thread to animate.
I will show you the one using the thread, since it is the way that I think I will be doing thing's when using animation for making games.
ThreadAnimationExample.java (in the tutorial it is called star.java but obviously that wont work)
import java.awt.EventQueue;
import javax.swing.JFrame;
public class ThreadAnimationExample extends JFrame {
public ThreadAnimationExample() {
add(new Board());
setTitle("Star");
pack();
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame ex = new ThreadAnimationExample();
ex.setVisible(true);
}
});
}
}
Board.java (the main class)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Board extends JPanel
implements Runnable {
private final int B_WIDTH = 350;
private final int B_HEIGHT = 350;
private final int INITIAL_X = -40;
private final int INITIAL_Y = -40;
private final int DELAY = 25;
private Image star;
private Thread animator;
private int x, y;
public Board() {
loadImage();
initBoard();
}
private void loadImage() {
ImageIcon ii = new ImageIcon("star.png");
star = ii.getImage();
}
private void initBoard() {
setBackground(Color.BLACK);
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
setDoubleBuffered(true);
x = INITIAL_X;
y = INITIAL_Y;
}
#Override
public void addNotify() {
super.addNotify();
animator = new Thread(this);
animator.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
drawStar(g);
}
private void drawStar(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(star, x, y, this);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
private void cycle() {
x += 1;
y += 1;
if (y > B_HEIGHT) {
y = INITIAL_Y;
x = INITIAL_X;
}
}
#Override
public void run() {
long beforeTime, timeDiff, sleep;
beforeTime = System.currentTimeMillis();
while (true) {
cycle();
repaint();
timeDiff = System.currentTimeMillis() - beforeTime;
sleep = DELAY - timeDiff;
if (sleep < 0) {
sleep = 2;
}
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
System.out.println("Interrupted: " + e.getMessage());
}
beforeTime = System.currentTimeMillis();
}
}
}
If you are using Eclipse you should create a source folder and add that image to the source folder. Then you could use this:
ImageIcon ii = new ImageIcon( getClass().getResource("/imageName.png") );

How to fix bad Double-Buffering [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I tried following a double buffering tutorial, and I really don't know what I did wrong. It works before then before I did the tutorial, but there is still and occasional flicker here and there. I have two files Game and gameLoop
Game:
import java.awt.Graphics;
public class Game extends gameLoop
{
public void init()
{
setSize(854,480);
Thread th = new Thread(this);
th.start();
offscreen = createImage(854,480);
d = offscreen.getGraphics();
}
public void paint(Graphics g)
{
d.clearRect(0, 0, 854, 480);
d.drawImage(disk, x, y, this);
g.drawImage(offscreen , 0, 0, this);
}
public void Update(Graphics gfx)
{
paint(gfx);
}
}
gameLoop
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class gameLoop extends Applet implements Runnable, MouseListener, MouseMotionListener
{
public int x, y, counter, mouseX, mouseY;
public Image offscreen;
public Graphics d;
public boolean up, down, left, right, pressed;
public BufferedImage disk1, disk2, disk3, disk4, disk;
public int ballSpeedX = -6;
public int ballSpeedY = -3;
public void run()
{
x = 400;
y = 200;
try {
disk1 = ImageIO.read(new File("disk1.png"));
disk2 = ImageIO.read(new File("disk2.png"));
disk3 = ImageIO.read(new File("disk3.png"));
disk4 = ImageIO.read(new File("disk4.png"));
} catch (IOException e1) {
e1.printStackTrace();
}
while(true)
{
if(x >= (854 - 150))
{
ballSpeedX = ballSpeedX * -1;
}
if(y >= (480 - 140))
{
ballSpeedY = ballSpeedY * -1;
}
if(y < (0 - 10))
{
ballSpeedY = ballSpeedY * -1;
}
if(x < (0- 10))
{
ballSpeedX = ballSpeedX * -1;
}
x = x + ballSpeedX;
y = y + ballSpeedY;
counter ++;
if(counter >= 4)
counter = 0;
if(counter == 0)
disk = disk1;
if(counter == 1)
disk = disk2;
if(counter == 2)
disk = disk3;
if(counter == 3)
disk = disk4;
System.out.println(counter);
repaint();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseMoved(MouseEvent m) {}
public void mousePressed(MouseEvent m)
{
}
public void mouseReleased(MouseEvent m)
{
pressed = false;
}
public void mouseDragged(MouseEvent e) {
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
mouseX = (int)b.getX();
mouseY = (int)b.getY();
ballSpeedX = mouseX;
ballSpeedY = mouseY;
}
}
public void Update(Graphics gfx)
{
paint(gfx);
}
Should be lower case, as you're trying to override the update(Graphics g) method in the Applet.
So it should be
#Override
public void update(Graphics gfx)
{
paint(gfx);
}
As for changing the background, a background is simply a big rectangle that covers the screen and makes it a certain color. In your paint, you're doing clearRect, which clears the screen. Instead just switch that to fillRect after setting the color.
It might look something like
public void paint(Graphics g)
{
//setColor to whatever you want
//fillRect to cover the screen
}
When you're doing this though, one thing you have to remember is to not confuse your two graphics objects. As a concept, double buffering works by drawing to memory first (drawing it on an offscreen image) and then to the screen. You want to always draw onto this offscreen image, as it is much faster (and we lose the flicker).
So make sure you're doing imageGraphicsObject.setColor not screenGraphicsObject.setColor or imageGraphicsObject.fillRectnotscreenGraphicsObject.fillRect`. Otherwise you're no longer double-buffering.
There are a number of different types "double buffers". The basic is a simple off screen image that you update and this gets painted to the screen instead. If done right, painting the image is often faster then drawing graphics to the screen.
Another type is page flipping. That is, you have an active buffer which is always rendered to the screen and a off screen/scratch buffer which is what you actually render to. You then flip these buffers when you are ready to render the updates to the screen (this is closer to how film animation works).
The following example is a REALLY basic example of page flipping.
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.image.BufferedImage;
import static testdoublebuffer.TestDoubleBuffer.UPDATE;
public class AppletDoubleBuffer extends Applet {
private BufferedPane pane;
#Override
public void init() {
pane = new BufferedPane();
setLayout(new BorderLayout());
add(pane);
}
#Override
public void start() {
pane.start();
}
#Override
public void stop() {
pane.stop();
}
public class BufferedPane extends Panel {
private BufferedImage activeBuffer;
private BufferedImage scratch;
private boolean running = false;
public BufferedPane() {
}
public void start() {
if (!running) {
running = true;
Thread thread = new Thread(new MainLoop());
thread.setDaemon(true);
thread.start();
}
}
public void stop() {
running = false;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
public void invalidate() {
synchronized (UPDATE) {
activeBuffer = null;
scratch = null;
}
super.invalidate();
}
#Override
public void update(Graphics g) {
if (activeBuffer != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(activeBuffer, 0, 0, this);
g2d.dispose();
}
}
public class MainLoop implements Runnable {
private int delay = 1000 / 25;
private int x = 0;
private int velocity = 5;
private int size = 10;
public void update() {
x += velocity;
if (x + size >= getWidth()) {
x = getWidth() - size;
velocity *= -1;
} else if (x <= 0) {
x = 0;
velocity *= -1;
}
if (getWidth() > 0 && getHeight() > 0) {
synchronized (UPDATE) {
if (scratch == null) {
scratch = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
}
Graphics2D g2d = scratch.createGraphics();
int y = (getHeight() - size) / 2;
g2d.setBackground(Color.BLUE);
g2d.clearRect(0, 0, getWidth(), getHeight());
g2d.setColor(Color.RED);
g2d.fillOval(x, y, size, size);
g2d.dispose();
// Flip the buffers...
BufferedImage tmp = activeBuffer;
activeBuffer = scratch;
scratch = tmp;
}
}
}
#Override
public void run() {
while (running) {
long startTime = System.currentTimeMillis();
update();
repaint();
long duration = System.currentTimeMillis() - startTime;
if (duration < delay) {
try {
Thread.sleep(delay);
} catch (InterruptedException ex) {
}
}
}
}
}
}
}
I personally, would just skip using AWT and move to Swing which provides better/built in functionality for this type of thing.

Categories