Spritesheet problem
Porlus:
Hello, I've got a problem with a spritesheet I'm trying to make using Java 2D. I first load an external PNG into a BufferedImage using the ImageIO class and using a Sprite class I pass in the buffered spritesheet, where I want it in the frame (x, y), the top left hand point of the tile from the spritesheet that I want to extract (xOffset, yOffset) and the width and height of the tile.
The external PNG is just a spritesheet containing the characters a-z, 0-9 that I made in photoshop, with each tile being 20x20 pixels. I'll post the code so you can see exactly what I mean, but what the problem is, is that when a new character is drawn using the Component classes paint method, the previously rendered characters disappear.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Main
{
public static final int WIDTH = 300;
public static final int HEIGHT = 300;
private Screen screen;
public Main()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.setSize(WIDTH, HEIGHT);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
BufferedImage ss = null;
try
{
ss = ImageIO.read(new File("charSprite.png"));
}
catch(IOException e)
{
e.printStackTrace();
}
screen = new Screen(WIDTH, HEIGHT);
screen.loadImage(new Sprite(ss, 0, 0, 20, 20).getSprite(), 20, 20);
screen.loadImage(new Sprite(ss, 0, 0, 20, 20).getSprite(), 40, 40);
frame.add(screen);
}
public static void main(String[] args)
{
new Main();
}
}
Here's the Sprite class, for dissecting the tile from the spritesheet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.awt.image.BufferedImage;
public class Sprite
{
private BufferedImage sprite;
public Sprite(BufferedImage ss, int xOffset, int yOffset, int width, int height)
{
sprite = ss.getSubimage(xOffset, yOffset, width, height);
}
public BufferedImage getSprite()
{
return sprite;
}
}
Here's the screen class which holds the bufferedimage containing each element within the screen:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.awt.Component;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
public class Screen extends Component
{
private BufferedImage display = null;
private int[] pixels;
public Screen(int w, int h)
{
display = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
pixels = new int[w * h];
}
public void loadImage(BufferedImage im, int x, int y)
{
int[] p = im.getRGB(0, 0, im.getWidth(), im.getHeight(), null, 0, im.getWidth());
for(int y1 = 0; y1 < im.getHeight(); y1++)
{
for(int x1 = 0; x1 < im.getWidth(); x1++)
{
pixels[(y1 + y) * display.getWidth() + (x1 + x)] = p[y1 * im.getWidth() + x1];
}
}
display.setRGB(0, 0, display.getWidth(), display.getHeight(), pixels, 0, display.getWidth());
repaint();
}
public void paint(Graphics g)
{
g.drawImage(display, 0, 0, display.getWidth(), display.getHeight(), null);
}
}
I'm quite new to this and just trying to understand how swing works so any help would be appreciated. Thanks!
Paul
ra4king:
JFrame's ContentPane's default layout is BorderLayout, which uses 1 component for the center, and 1 component for each of the 4 sides. Calling JFrame.add(Component) adds it to the center component. Any further calls will replace the previous one. What you need is 1 component that you draw everything to.
Porlus:
Thanks for the reply. Yeah, I've just thought to add a screen class to keep a pixels by pixels reference of everything on the screen, then I can just pass in bufferedimages, extract their pixel arrays and then overlay the new image within a nested loop in the correct position.
I've updated my original post now to what I currently have and it seems to work perfectly, except the images only seem to appear roughly 50% of the time once the program is ran. If I minimize the program and maximize it again the images appear, though. Any idea what could be causing that?
GabrielBailey74:
Could be because you're only adding the Screen there once, you'd need to add a loop of somekind, than handle your paint method in there so it's constantly repainting.
Porlus:
I think it stays as it is until you clear the pixel array and update the screen buffer. I'll have to create a clear buffer method or something to clear that out. I think the problem lies around here in the main class:
1
ss = ImageIO.read(new File("charSprite.png"));
As when the pictures don't render, they both don't and likewise when they do. So that would suggest that it was a problem with the spritesheet I'm feeding into the sprite classes. Not really sure about a solution though.
Navigation
[0] Message Index
[#] Next page