With my current code I have a character that loads in a sprite sheet for the animation. My problem arises when I run the code. The game runs fine except that the player is loading/cycling sprites way too fast. I believe this stems from the overall game timing/update. I should state that the game is working through an applet. I gathered some information on SwingerWorkers, but I don't know how to manipulate it to my needs. If someone could take a look at my code and let me know what I could do, I'd appreciate it.
Player constructor:
public Player(Image pic, ImageObserver IO){
positionX=200;
positionY=200;
destinationX=(int)positionX;
destinationY=(int)positionY;
speed = 2.3;
girlImage=pic;
this.io=IO;
width=120;
height=100;
//this.playerImage=playerImage;
// Gets each sprite
BufferedImage img = createImage();
for(int j=0;j<4;j++)
{
for(int i = 0; i < frameCount; i++) {
girlAll[j][i] = girl[j].getSubimage(imgWidth*i, 0, imgWidth, imgHeight);
}//end of for
}//end of for
}
// Image loader
private BufferedImage createImage(){
//BufferedImage bufferedImage;
try {
girl[0] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_northeast_walk.png"));
girl[1] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_northwest.png"));
girl[2] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_southeast.png"));
girl[3] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_southwest.png"));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Draw method:
public void draw(Graphics g){
//g.drawImage(girlImage, (int)positionX,(int) positionY,io);
picNum = (picNum + 1) % frameCount;
pics = girlAll[x];
if (x==0)
g.drawImage(pics[picNum], (int) (positionX), (int) (positionY), io);
if (x==1)
g.drawImage(pics[picNum], (int) (positionX), (int) (positionY), io);
if (x==2)
g.drawImage(pics[picNum], (int) (positionX), (int) (positionY), io);
if (x==3)
g.drawImage(pics[picNum], (int) (positionX), (int) (positionY), io);
}
SwingWorker attempt:
SwingWorker worker = new SwingWorker<BufferedImage[], Void>() {
public BufferedImage[] doInBackground(){
//BufferedImage bufferedImage;
try {
girl[0] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_northeast_walk.png"));
girl[1] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_northwest.png"));
girl[2] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_southeast.png"));
girl[3] = ImageIO.read(new File("C:/Users/blutuu/Documents/Marlin/UD/Workspace S13/MoD/src/female_player_southwest.png"));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public void loadImg() {
doInBackground();
for(int j=0;j<4;j++)
{
for(int i = 0; i < frameCount; i++) {
girlAll[j][i] = girl[j].getSubimage(imgWidth*i, 0, imgWidth, imgHeight);
}//end of for
}//end of for
}
};
}
Runs game (from 'Game' class):
public void init(){
//Execute a job on the event-dispatching thread:
//creating this applet's GUI.
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception e) {
System.err.println("createGUI didn't successfully complete");
}
}
Thread handling:
private void gameStuff(){
try {Thread.sleep(sleepTime);}
catch (InterruptedException e) {}
mouseClicked=false;
}
Game rendering:
public void update (Graphics g)
{
// initialize buffer
if (dbImage == null)
{
dbImage = createImage (this.getSize().width, this.getSize().height);
dbg = dbImage.getGraphics ();
}
// clear screen in background
dbg.setColor (getBackground ());
dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);
// draw elements in background
//dbg.setColor (getForeground());
paint (dbg);
// draw image on the screen
g.drawImage (dbImage, 0, 0, this);
}
Another rendering method:
private void hud(Graphics g){
g.setColor(Color.orange);
g.fillRect(300, 0, 500, 80);
g.fillRect(200, 0, 100, 80);
//SHOVEL IMAGE AND BUTTON
g.drawImage(shovelImage, 520,0,this);
g.setColor(Color.black);
g.drawRect(520, 0, 60, 80);//show boundaries
if(mouseClicked && new Rectangle(520, 0, 60, 80).contains(mx,my))
toolSelected=1; //sets tool selected to shovel
//ROCKS IMAGE AND BUTTON
g.drawImage(rocksImage, 600,0, this);
g.drawRect(600, 0, 60, 80);//show boundaries
if(mouseClicked && new Rectangle(600, 0, 60, 80).contains(mx,my))
toolSelected=2; //sets tool selected to shovel
//JACKHAMMER IMAGE AND BUTTON
g.drawImage(jackHammerImage, 680,0, this);
g.drawRect(680, 0, 60, 80);//show boundaries
if(mouseClicked && new Rectangle(680, 0, 60, 80).contains(mx,my))
toolSelected=3; //sets tool selected to shovel
if(timer.getAngle()<360){
timer.draw(g);
}
if(timer.getAngle()==360){
raining=true;
timer.reset();
addDrops();
roundNum++;
puddles();
}
drawProgressBar(g);
if(toolSelected == 1)
{
Message = "Native Delaware plants";
Message2 = "are good";
}
else if(toolSelected == 2)
{
Message = "Rocks with Runoff";
Message2 = " ";
}
else if(toolSelected == 3)
{
Message = "Permeated Driveways";
Message2 = "help with excesse water";
}
else{
Message = "Play On";
Message2 = " ";
}
g.drawString("Round "+roundNum, 350, 30);
g.drawString(Message, 205, 40);
g.drawString(Message2, 205, 55);
drawTiles(g);
}
update(Graphics g)
for Swing GUI's. That was used for AWT, but for Swing is not appropriate. The graphics tutorials will tell you this.paint(...)
or paintComponent(...)
directly. For more details, check out the basic Swing drawing tutorial and also a more advanced article on Painting in AWT and Swing.For example:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class SpriteAnimationApplet extends JApplet {
private static final String SPRITE_SHEET_SPEC = "http://www.funorb.com/img/images/game/"
+ "central/dev_diary/sprite_sheet_full.gif";
private static final int SPRITE_ROWS = 8; // an 8 x 8 sprite sheet
@Override
public void init() {
try {
final Icon[] icons = SpriteIO.getSprites(SPRITE_SHEET_SPEC, SPRITE_ROWS);
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
SpriteAnimationPanel spritePanel = new SpriteAnimationPanel(icons);
getContentPane().add(spritePanel);
spritePanel.startAnimation();
}
});
} catch (InvocationTargetException e) {
e.printStackTrace();
System.exit(-1);
} catch (InterruptedException e) {
e.printStackTrace();
System.exit(-1);
} catch (MalformedURLException e) {
e.printStackTrace();
System.exit(-1);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
}
class SpriteIO {
public static Icon[] getSprites(String spriteSheetSpec, int spriteRows)
throws MalformedURLException, IOException {
Icon[] icons = new Icon[spriteRows * spriteRows];
URL spriteSheetUrl = new URL(spriteSheetSpec);
BufferedImage spriteSheet = ImageIO.read(spriteSheetUrl);
double wD = (double) spriteSheet.getWidth() / spriteRows;
double hD = (double) spriteSheet.getHeight() / spriteRows;
int w = (int) wD;
int h = (int) hD;
for (int i = 0; i < spriteRows; i++) {
for (int j = 0; j < spriteRows; j++) {
int x = (int) (i * wD);
int y = (int) (j * hD);
BufferedImage img = spriteSheet.getSubimage(x, y, w, h);
icons[j * spriteRows + i] = new ImageIcon(img);
}
}
return icons;
}
}
@SuppressWarnings("serial")
class SpriteAnimationPanel extends JPanel {
private static final int TIMER_DELAY = 200;
private Icon[] icons;
private JLabel animationLabel = new JLabel();
public SpriteAnimationPanel(Icon[] icons) {
this.icons = icons;
setLayout(new BorderLayout());
add(animationLabel );
}
public void startAnimation() {
Timer spriteTimer = new Timer(TIMER_DELAY, new ActionListener() {
private int iconIndex = 0;
@Override
public void actionPerformed(ActionEvent arg0) {
animationLabel.setIcon(icons[iconIndex]);
iconIndex++;
iconIndex %= icons.length;
}
});
spriteTimer.start();
}
}