java flicker with resizing and need general code examination

Started by
1 comment, last by solinent 15 years, 5 months ago
I'm learning how to write 2d graphics and gaming using Developing Games In Java, 2003 and converting the full screen apps to japplet as I go. I seem to learn more in depth this way. I originally started using canvas and did not have these problems with flickering on resize of japplet and flicker when another window is moved over the japplet. I think it is due to a repaint being called when either of those are done. With the canvas awt I had used bufferStradegy which allowed me to tell it to show the image when I wanted it to vs using repaint in swing. How can I get more control on swing repaint (reduce flicker on resize and windows over applet) Any code snippets and advise for code would be greatly appreciated. (I learn well but I'm not fully versed in 2D graphics design). I have searched many threads and googled alot while converting from full screen to canvas, and then ultimately jpanel for a screen. Cross Forum: http://www.java-forums.org/java-2d/13391-flicker-resizing-need-general-code-examination.html#post43853 In-action http://thefreeweed.com/worm/testJapplet.html //Random questions Is there anyway to do the thread.sleep in the gameloop a differnt way and is my thread for gamecore implemented correctly? GamePanel //game loop in gamecore on purpose
Quote: package bounce2; import java.awt.*; import javax.swing.*; import java.awt.image.BufferedImage; /** * * @author Mr. Freeweed */ class GamePanel extends JPanel { BufferedImage bImage = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB); boolean iCheck = true; Dimension e; public Graphics2D getTheGraphics() { if (iCheck || bImage == null) { bImage = (BufferedImage) createImage(e.width, e.height); iCheck = false; } return (Graphics2D)bImage.createGraphics(); } public void gameRender() { repaint(); } protected void paintComponent(Graphics g) { Graphics2D g2D = (Graphics2D)g; //super.paintComponent(g2D); g2D.drawImage(bImage,0,0,null); } public void setPreferredSize(Dimension d) { e = (Dimension)d; } public Dimension getPreferredSize() { return e; } }
GameCore
Quote: package bounce2; /** * * @author Mr. Freeweed */ //import java.awt.*; //import javax.swing.*; import java.awt.Graphics2D; import java.awt.Dimension; import java.awt.Container; import java.awt.BorderLayout; import javax.swing.JApplet; public abstract class GameCore extends JApplet implements Runnable { GamePanel gamePanel; private boolean stopped = false;/*True if the applet has been destroyed*/ public void init() { gamePanel = new GamePanel(); gamePanel.setPreferredSize(new Dimension(800, 600)); this.setSize(800,600); this.setLayout(new BorderLayout()); Container c=this.getContentPane(); c.add(gamePanel,BorderLayout.WEST); getRDone(); Thread t = new Thread(this); //setIgnoreRepaint(true); t.start(); } public void run() { long startTime = System.currentTimeMillis(); long currTime = startTime; //animation loop while(!stopped) { //Get time past long elapsedTime = System.currentTimeMillis()-currTime; currTime += elapsedTime; update(); //Update any sprites or other graphical objects update(elapsedTime); //Handle Drawing Graphics2D g = gamePanel.getTheGraphics(); update(g); draw(g); gamePanel.gameRender(); //Dispose of graphics context g.dispose(); try { Thread.sleep(10); } catch (InterruptedException ex) { } } } public void update(Graphics2D g) { g.setColor(g.getBackground()); g.fillRect(0,0,getWidth(),getHeight()); } //this was awt canvas method public void update() { } public void destroy() { stopped = true; super.destroy(); } //Initialize image loading before thread start public abstract void getRDone(); //Update any sprites, images, or primitives public abstract void update(long elapsedTime); //Subclasses should override this method to do any drawing public abstract void draw(Graphics2D g); public int dGetWidth() { return gamePanel.getWidth(); } public int dGetHeight() { return gamePanel.getHeight(); } }
Advertisement
(Fubarable)
Quote:have you tried using a Swing Timer and not Thread.sleep? Also, can you post a small class that uses your abstract GameCore class and can demonstrate just what your problem is?


I'm using images (which arn't mine) the exact program I'm using is in the link above for viewing.

I will look up swing timer

Quote:Sprite and animation classes are from the book and not my original code.



Here is the rest of the code

using abstract gamecore in begingame.java
Quote:
package bounce2;

import java.awt.*;
import java.awt.geom.*;
import java.net.*;
/**
*
* @author Mr. Freeweed
*/
public class begingame extends GameCore {

private static final long DEMO_TIME = 10000;
private static final long FADE_TIME = 1000;
private static final int NUM_SPRITES = 3;

private Image bgImage;
private Sprite sprites[];
URL base;
MediaTracker mt;

public void init() {
super.init();
}

public void getRDone() {
loadImages();
}

public void update(long elapsedTime) {
for (int i = 0; i < NUM_SPRITES; i++) {

Sprite s = sprites;

// check sprite bounds
if (s.getX() < 0.) {
s.setVelocityX(Math.abs(s.getVelocityX()));
}
else if (s.getX() + s.getWidth() >=
dGetWidth())
{
s.setVelocityX(-Math.abs(s.getVelocityX()));
}
if (s.getY() < 0) {
s.setVelocityY(Math.abs(s.getVelocityY()));
}
else if (s.getY() + s.getHeight() >=
dGetHeight())
{
s.setVelocityY(-Math.abs(s.getVelocityY()));
}

// update sprite
s.update(elapsedTime);
}
}


public void draw(Graphics2D g) {
// draw background
g.drawImage(bgImage, 0, 0, null);

AffineTransform transform = new AffineTransform();
for (int i = 0; i < NUM_SPRITES; i++) {
Sprite sprite = sprites;

// translate the sprite
transform.setToTranslation(sprite.getX(),
sprite.getY());

// if the sprite is moving left, flip the image
if (sprite.getVelocityX() < 0) {
transform.scale(-1, 1);
transform.translate(-sprite.getWidth(), 0);
}

// draw it
g.drawImage(sprite.getImage(), transform, null);
}


}





public void loadImages() {
// initialize the MediaTracker
mt = new MediaTracker(this);

// tell the MediaTracker to kep an eye on this image, and give it ID 1;
// load images
bgImage = loadImage("Images/background.jpg");
mt.addImage(bgImage,1);
Image player1 = loadImage("Images/player1.png");
mt.addImage(player1,2);
Image player2 = loadImage("Images/player2.png");
mt.addImage(player2,3);
Image player3 = loadImage("Images/player3.png");
mt.addImage(player3,4);

try {
mt.waitForAll();
}
catch (InterruptedException e) {}
// when the applet gets here then the images is loaded.

// create and init sprites
sprites = new Sprite[NUM_SPRITES];
for (int i = 0; i < NUM_SPRITES; i++) {
Animation anim = new Animation();
anim.addFrame(player1, 250);
anim.addFrame(player2, 150);
anim.addFrame(player1, 150);
anim.addFrame(player2, 150);
anim.addFrame(player3, 200);
anim.addFrame(player2, 150);
sprites = new Sprite(anim);

// select random starting location
sprites.setX((float)Math.random() *
(dGetWidth() - sprites.getWidth()));
sprites.setY((float)Math.random() *
(dGetHeight() - sprites.getHeight()));

// select random velocity
sprites.setVelocityX((float)Math.random() - 0.5f);
sprites.setVelocityY((float)Math.random() - 0.5f);
}
}


private Image loadImage(String fileName) {

try {
// getDocumentbase gets the applet path.
base = getDocumentBase();
}
catch (Exception e) {}

// Here we load the image.
// Only Gif and JPG are allowed. Transparant gif also.
return getImage(base, fileName);
}
}


Sprite
Quote:package bounce2;

import java.awt.Image;

public class Sprite {

private Animation anim;
// position (pixels)
private float x;
private float y;
// velocity (pixels per millisecond)
private float dx;
private float dy;

/**
Creates a new Sprite object with the specified Animation.
*/
public Sprite(Animation anim) {
this.anim = anim;
}

/**
Updates this Sprite's Animation and its position based
on the velocity.
*/
public void update(long elapsedTime) {
x += dx * elapsedTime;
y += dy * elapsedTime;
anim.update(elapsedTime);
}

/**
Gets this Sprite's current x position.
*/
public float getX() {
return x;
}

/**
Gets this Sprite's current y position.
*/
public float getY() {
return y;
}

/**
Sets this Sprite's current x position.
*/
public void setX(float x) {
this.x = x;
}

/**
Sets this Sprite's current y position.
*/
public void setY(float y) {
this.y = y;
}

/**
Gets this Sprite's width, based on the size of the
current image.
*/
public int getWidth() {
return anim.getImage().getWidth(null);
}

/**
Gets this Sprite's height, based on the size of the
current image.
*/
public int getHeight() {
return anim.getImage().getHeight(null);
}

/**
Gets the horizontal velocity of this Sprite in pixels
per millisecond.
*/
public float getVelocityX() {
return dx;
}

/**
Gets the vertical velocity of this Sprite in pixels
per millisecond.
*/
public float getVelocityY() {
return dy;
}

/**
Sets the horizontal velocity of this Sprite in pixels
per millisecond.
*/
public void setVelocityX(float dx) {
this.dx = dx;
}

/**
Sets the vertical velocity of this Sprite in pixels
per millisecond.
*/
public void setVelocityY(float dy) {
this.dy = dy;
}

/**
Gets this Sprite's current image.
*/
public Image getImage() {
return anim.getImage();
}
}


animation
Quote:package bounce2;

import java.awt.Image;
import java.util.ArrayList;

/**
The Animation class manages a series of images (frames) and
the amount of time to display each frame.
*/
public class Animation {

private ArrayList frames;
private int currFrameIndex;
private long animTime;
private long totalDuration;


/**
Creates a new, empty Animation.
*/
public Animation() {
frames = new ArrayList();
totalDuration = 0;
start();
}


/**
Adds an image to the animation with the specified
duration (time to display the image).
*/
public synchronized void addFrame(Image image,
long duration)
{
totalDuration += duration;
frames.add(new AnimFrame(image, totalDuration));
}


/**
Starts this animation over from the beginning.
*/
public synchronized void start() {
animTime = 0;
currFrameIndex = 0;
}


/**
Updates this animation's current image (frame), if
neccesary.
*/
public synchronized void update(long elapsedTime) {
if (frames.size() > 1) {
animTime += elapsedTime;

if (animTime >= totalDuration) {
animTime = animTime % totalDuration;
currFrameIndex = 0;
}

while (animTime > getFrame(currFrameIndex).endTime) {
currFrameIndex++;
}
}
}


/**
Gets this Animation's current image. Returns null if this
animation has no images.
*/
public synchronized Image getImage() {
if (frames.size() == 0) {
return null;
}
else {
return getFrame(currFrameIndex).image;
}
}


private AnimFrame getFrame(int i) {
return (AnimFrame)frames.get(i);
}


private class AnimFrame {

Image image;
long endTime;

public AnimFrame(Image image, long endTime) {
this.image = image;
this.endTime = endTime;
}
}
}

I don't get any flickering with that demo, what do you mean by japplet resize?

Sorry, I'm not well versed in which cases applets will get resized.

This topic is closed to new replies.

Advertisement