Why my tick(); method being called, but not my render(); method is the question here.
So, I have a class that holds my updating and my rendering here:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
public class MapI extends Map {
int players = 8, islands = 8;
private int dimAm, irAm, golAm, emAm;
#Override
public void tick() {
while(irAm < 48) {
tickIr();
}
while(dimAm < 4) {
tickDim();
}
}
public void tickDim() {
try {
Thread.sleep(20000);
} catch(InterruptedException e) {
e.printStackTrace();
}
dimAm += 1;
System.out.println(dimAm + " diamonds");
}
public void tickIr() {
try {
Thread.sleep(2000);
} catch(InterruptedException e) {
e.printStackTrace();
}
irAm += 1;
System.out.println(irAm + " iron");
}
#Override
public void render(Graphics g) {
g.setFont(new Font("Arial", Font.BOLD, 12));
g.setColor(Color.BLACK);
g.fillRect(30, 10, 50, 50); // dim gen(s)
g.drawString(dimAm + "", 41, 29);
g.setColor(Color.CYAN);
g.fillRect(40, 20, 30, 30);
g.setColor(Color.YELLOW);
g.fillRect(30, 100, 50, 50); // yellow base
}
}
Here's the Map class:
import java.awt.Graphics;
public abstract class Map {
protected int players, islands;
public abstract void tick();
public abstract void render(Graphics g);
}
What is happening is, when my run() method in my Game class is called, it has a while(running), and inside that loop is where I specify to render and update:
public void run(){
init();
while(running){
render();
tick();
}
stop();
}
public synchronized void start(){
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop(){
if(!running)
return;
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
With this, I should both render and update, but, as of right now, all that goes on is updates. I think that my problem might come with
#Override
public void tick() {
while(irAm < 48) {
tickIr();
}
while(dimAm < 4) {
tickDim();
}
}
, which is inside of MapI. What I think is happening is nothing else will render until none of these loops are still running, but then again, I don't know how to bypass that.
My GameAspect class that houses the render method is here:
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import blaze.game.gfx.Assets;
import blaze.game.maps.MapI;
public class GameAspect implements Runnable {
private Display display;
public int width, height;
public String title;
private boolean running = false;
private Thread thread;
private BufferStrategy bs;
private Graphics g;
private MapI map1;
public GameAspect(String title, int width, int height){
this.width = width;
this.height = height;
this.title = title;
map1 = new MapI();
}
private void init(){
display = new Display(title, width, height);
Assets.init();
}
private void tick(){
map1.tick();
}
private void render(){
bs = display.getCanvas().getBufferStrategy();
if(bs == null){
display.getCanvas().createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
//Clear Screen
g.clearRect(0, 0, width, height);
//Draw Here!
map1.render(g);
//End Drawing!
bs.show();
g.dispose();
}
public void run(){
init();
while(running){
render();
tick();
}
stop();
}
public synchronized void start(){
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop(){
if(!running)
return;
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Related
Please read the latest update down below
So I am trying to make a brick breaker game and while everything works in terms of gameplay I am having trouble adding a menu system. Basically this is how my code works
public class Game extends Canvas implements Runnable{
public Graphics g;
private Menu menu;
protected Ball ball;
protected Player player;
protected BufferedImage image;
protected BufferStrategy bufferStrategy;
protected Thread thread;
protected JFrame frame;
protected volatile boolean running, gameOver;
private enum STATE{
MENU,
GAME,
ABOUT,
OPTIONS,
};
private STATE State = STATE.MENU;
public Game(){
//Set the Jframe
}
private void init()
{
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
requestFocus();
menu = new Menu();
//init everything else aswell
}
public void update()
{
//Update every moving object
}
#Override
public void run()
{
init();
long initialTime = System.nanoTime();
double timePerFrame = 1000000000/FPS;
double delta = 0;
int ticks = 0;
long timer = 0;
while (running)
{
long currentTime = System.nanoTime();
long elapsedTime = currentTime - initialTime;
delta += elapsedTime/timePerFrame;
timer += elapsedTime;
if (delta >= 1)
{
update();
delta--;
ticks++;
}
render();
initialTime = currentTime;
if (timer >= 1000000000)
{
currentFPS = ticks;
ticks = 0;
timer = 0;
}
}
stop();
}
And when I render everything that is in the STATE GAME it works just fine but when I try to add an else if statement that does menu.draw(g) it all falls apart and I just get a blank frame
Here is how I render
public void render()
{
bufferStrategy = getBufferStrategy();
if (bufferStrategy == null)
{
createBufferStrategy(3);
return;
}
g = bufferStrategy.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
g.setColor(BG_COLOR);
g.fillRect(0, 0, WIDTH, HEIGHT);
if(State == STATE.GAME){
player.draw(g);
ball.draw(g);
blockController.draw(g); **THESE WORK JUST FINE**
}
else if(State == STATE.MENU){
menu.draw(g); **DOES NOT WORK**
}
bufferStrategy.show();
g.dispose();
}
And my Menu class has no difference in terms of the draw method
public class Menu implements GUI
{
#Override
public void draw(Graphics g) {
g.setFont(new Font("arial", Font.BOLD, 50));
g.setColor(Color.black);
g.drawString("MENU", Game.WIDTH / 2, 100);
}
}
Any idea why this might be happening I am doing the same render litteraly but keep getting
Exception in thread "Thread-0" java.lang.ClassCastException: class sun.java2d.NullSurfaceData cannot be cast to class sun.java2d.d3d.D3DSurfaceData error or g is null error
How can I fix this?
UPDATE ----------------------------------
The menu.draw() in the render works when I remove the lines
g.setFont(new Font("arial", Font.BOLD, 50));
g.setColor(Color.black);
g.drawString("MENU", Game.WIDTH / 2, 100);
And instead add something like
g.setColor(Color.CYAN);
g.fillRect(5, 5, 200, 200);
This does work but why the setfont, setColor and drawString don't work I don't understand I wanted to add buttons aswell but they don't work either. Is it because I set the entire frame with a rectangle in the render with the line g.fillRect(0, 0, WIDTH, HEIGHT); but then can I add objects like paddle,ball,bricks but not a string or a button?
The following example seems to work fine.
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setVisible(true);
}
});
}
public class TestPane extends Canvas {
private Thread thread;
private volatile boolean render = false;
public TestPane() {
}
#Override
public void addNotify() {
super.addNotify();
start();
}
#Override
public void removeNotify() {
super.removeNotify();
stop();
}
protected void start() {
if (thread != null) {
render = false;
try {
thread.join();
} catch (InterruptedException ex) {
}
}
render = true;
thread = new Thread(new Runnable() {
#Override
public void run() {
while (render) {
render();
try {
Thread.sleep(16);
} catch (InterruptedException ex) {
}
}
}
});
thread.start();
}
protected void stop() {
render = false;
if (thread == null) {
return;
}
try {
thread.join();
} catch (InterruptedException ex) {
}
thread = null;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
private Menu menu = new Menu();
protected void render() {
BufferStrategy strategy = getBufferStrategy();
if (strategy == null) {
createBufferStrategy(3);
strategy = getBufferStrategy();
}
if (strategy == null) {
return;
}
do {
// The following loop ensures that the contents of the drawing buffer
// are consistent in case the underlying surface was recreated
do {
// Get a new graphics context every time through the loop
// to make sure the strategy is validated
Graphics graphics = strategy.getDrawGraphics();
graphics.setColor(Color.BLACK);
graphics.fillRect(0, 0, getWidth(), getHeight());
menu.render(graphics, getSize());
graphics.dispose();
// Repeat the rendering if the drawing buffer contents
// were restored
} while (strategy.contentsRestored());
// Display the buffer
strategy.show();
// Repeat the rendering if the drawing buffer was lost
} while (strategy.contentsLost());
}
}
public class Menu {
public void render(Graphics g, Dimension bounds) {
// This is probably going to cost you a lot of
// performance and it might be better to
// pre-create the font instead
g.setFont(new Font("Arial", Font.BOLD, 50));
g.setColor(Color.WHITE);
String text = "MENU";
FontMetrics fm = g.getFontMetrics();
g.drawString("MENU", (bounds.width - fm.stringWidth(text)) / 2, (bounds.height / 2) - fm.getAscent());
}
}
}
If you continue to have issues, continue providing a runnable example which demonstrates your issue
When i try to set value to BufferedImage called dinoImage in Dino.java in a constructor i just get a blank screen every time (second picture) because repaint() is not being called, but if i set it to null it is working just fine but without this image (first picture).
No exceptions, everything seems fine in this code, this problem appears when i try to set value to this field using static method getImage of Resource.java which uses this line of code ImageIO.read(new File(path)) and it causes that repaint() is not being called, i guess this line causes such weird behavior but i dont know how to solve it.
Main.java
public class Main {
public static void main(String[] args) {
GameWindow gameWindow = new GameWindow();
gameWindow.startGame();
}
}
GameWindow.java
public class GameWindow extends JFrame {
private GameScreen gameScreen;
public GameWindow() {
super("Runner");
setSize(1000, 500);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameScreen = new GameScreen();
add(gameScreen);
}
public void startGame() {
gameScreen.startThread();
}
}
GameScreen.java
public class GameScreen extends JPanel implements Runnable, KeyListener {
private Thread thread;
public static final double GRAVITY = 0.1;
public static final int GROUND_Y = 300;
private Dino dino;
public GameScreen() {
thread = new Thread(this);
dino = new Dino();
}
public void startThread() {
thread.start();
}
#Override
public void run() {
while(true) {
try {
Thread.sleep(20);
dino.updatePosition();
repaint();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// g.clearRect(0, 0, getWidth(), getHeight());
g.setColor(Color.RED);
g.drawLine(0, GROUND_Y, getWidth(), GROUND_Y);
dino.draw(g);
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("Key Pressed");
dino.jump();
}
#Override
public void keyReleased(KeyEvent e) {
System.out.println("Key Released");
}
}
Dino.java
public class Dino {
private double x = 100;
private double y = 100;
private double speedY = 0;
private BufferedImage dinoImage;
public Dino() {
dinoImage = getImage("data/dino.png");
}
public void updatePosition() {
if(y + speedY >= GROUND_Y - 100) {
speedY = 0;
y = GROUND_Y - 100;
} else {
speedY += GRAVITY;
y += speedY;
}
}
public void jump() {
if(y == GROUND_Y - 100) {
speedY = -5;
y += speedY;
}
}
public void draw(Graphics g) {
g.setColor(Color.BLACK);
g.drawRect((int)x, (int)y, 100, 100);
g.drawImage(dinoImage, (int)x, (int)y, null);
}
}
Resource.java
public class Resource {
public static BufferedImage getImage(String path) {
BufferedImage image = null;
try {
image = ImageIO.read(new File(path));
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
}
setSize(1000, 500);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameScreen = new GameScreen();
add(gameScreen);
Swing components need to be added to the frame BEFORE the frame is made visible. Otherwise the panel has a size of (0, 0) and there is nothing to paint.
The code should be something like:
gameScreen = new GameScreen();
add(gameScreen);
setSize(1000, 500);
setVisible(true);
Currently, I have a line which moves from the bottom of the screen to the top where it disappears. I would like to have the line continuously moving inside my applet so it does not disappear. But the applet has to be moving in other words it has to update its position. Or the line has to move without exceeding the boundaries of the applet.
StartingClass
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.net.URL;
public class StartingClass extends Applet implements Runnable {
Wall wall = new Wall();
private Image image;
private Graphics second;
#Override
public void init() {
setSize(400, 600);
setBackground(Color.BLACK);
setFocusable(true);
}
#Override
public void start() {
Thread thread = new Thread(this);
thread.start();
}
#Override
public void run() {
while (true) {
wall.update();
try {
repaint();
Thread.sleep(17);
// System.out.println("test");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void update(Graphics g) {
if (image == null) {
// System.out.println(this.getHeight());
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
g.setColor(Color.RED);
for (int i = 0; i <= 100; i += 5) {
g.fillOval(189, wall.getPositionY() + i, wall.getCircleWidth(), wall.getCircleHeight());
}
}
}
Wall
public class Wall {
final int GAMESPEED = 2;
final int circleWidth = 15;
final int circleHeight = 15;
int positionY = 600;
public void update() {
positionY -= GAMESPEED;
}
public int getPositionY() {
return positionY;
}
public int getCircleWidth() {
return circleWidth;
}
public int getCircleHeight() {
return circleHeight;
}
public void setPositionY(int positionY) {
this.positionY = positionY;
}
}
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) {
}
}
I am trying to get an animation using a spritesheet in JFrame. The problem is the once loaded, the image doesn't change. It only shows the first image.
I have searched a lot and tried almost all the advice but can't get it to work.
By the way, getSprite has a return type of Image.
When I do everything in JFrame, only one image is shown. When I do it in separate class extending JPanel, I get only a white Window.
Update 1: Thanks to andrew, got JFrame working. Fixed my old part too. Here's the working code at ideone
Update 2:
Here's my version with timer.
class TestSpriteSheet extends JFrame{
//same old variables
public TestSpriteSheet(){
//same old stuff goes here before this
add(new PanelSprite(this, ss));
this.setVisible(true);
}
}
class PanelSprite extends JPanel{
private long runningTime = 0;
private int fps = 3;
private boolean stop = false;
private SpriteSheetManager ss;
private TestSpriteSheet temp;
public PanelSprite(TestSpriteSheet test, SpriteSheetManager sm){
ss = sm;
temp = test;
setSize(180,180);
setLayout(new BorderLayout()); init();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
long time = 5000;
animate_with_gfx(g, time);
}
public void init(){
Timer t = new Timer((int)(1000/fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!stop) {
repaint();
} else {
((Timer)e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int)(1000/fps));
t.start();
}
public void animate_with_gfx(Graphics g, long time){
if(runningTime <= time){
try {
System.out.println(runningTime); //Checking if this part works
int x = 0; int y = 0;
g.drawImage(ss.getSprite(x, y), 40, 40, null);
x++; y++; runningTime+=(1000/fps);
}catch (Exception ex) {
ex.printStackTrace();
}
}
else{
stop = true;
}
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
long time = 5000; int fps = 3;
boolean stop = false;
Timer t = new Timer((int)(1000/fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!stop) {
animate_with_gfx(g, time, fps, stop);
repaint();
} else {
((Timer)e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int)(1000/fps));
t.start();
System.exit(0);
}
This part is entirely wrong, since the paintComponent() method is called whenever the JRE thinks the view needs repainting. So definitely remove the System.exit(0);!
Then the Timer needs a single instance, to be started once. That would best be done in the constructor or an init() type method.
It might look something like this:
private int fps = 3;
private boolean stop = false;
public void paintComponent(Graphics g){
super.paintComponent(g);
long time = 5000;
animate_with_gfx(g, time, fps, stop);
}
/** Called from constructor.. */
public void init(){
Timer t = new Timer((int)(1000/fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!stop) {
repaint();
} else {
((Timer)e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int)(1000/fps));
t.start();
}
Update
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import javax.swing.*;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
class SpriteSheetManager {
private BufferedImage spriteSheet;
int cols;
int rows;
public SpriteSheetManager() {
setSpriteSheet();
}
public void setSpriteSheet() {
try {
spriteSheet = ImageIO.read(
new URL("http://s8.postimg.org/vso6oed91/spritesheet.png"));
setColsAndRows(3, 3);
} catch (IOException e) {
e.printStackTrace();
}
}
public BufferedImage getSpriteSheet() {
return spriteSheet;
}
public void setColsAndRows(int cols, int rows) {
this.cols = cols;
this.rows = rows;
}
public Image getSprite(int x, int y) {
Image sprite = null;
try {
sprite = spriteSheet.getSubimage(
x * spriteSheet.getWidth() / cols,
y * spriteSheet.getHeight() / rows,
spriteSheet.getWidth() / cols,
spriteSheet.getHeight() / rows);
} catch (Exception e) {
e.printStackTrace();
}
return sprite;
}
}
class Ideone {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestSpriteSheet();
}
});
}
}
class TestSpriteSheet extends JFrame {
private static final long serialVersionUID = 1L;
private SpriteSheetManager ss;
public TestSpriteSheet() {
super("Testing SpriteSheets");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLayout(new BorderLayout());
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
System.exit(0);
}
});
ss = new SpriteSheetManager();
add(new PanelSprite(this, ss));
pack();
setSize(200, 200);
this.setVisible(true);
}
}
class PanelSprite extends JPanel {
private long runningTime = 0;
private int fps = 10;
private boolean stop = false;
private SpriteSheetManager ss;
private TestSpriteSheet temp;
private Timer t;
int count = 0;
long time = 50000;
public PanelSprite(TestSpriteSheet test, SpriteSheetManager sm) {
ss = sm;
temp = test;
init();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
animate_with_gfx(g);
}
public void init() {
t = new Timer((int) (1000 / fps), new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!stop) {
repaint();
} else {
((Timer) e.getSource()).stop();
}
}
});
t.setRepeats(true);
t.setDelay((int) (1000 / fps));
t.start();
}
public void animate_with_gfx(Graphics g) {
if (runningTime <= time) {
Image img = ss.getSprite((count % 9) % 3, (count % 9) / 3);
g.drawImage(img, 40, 40, this);
count++;
runningTime += (1000 / fps);
} else {
stop = true;
}
}
}