Within my program, I have the following code:
package io.github.AdmiralSbs.DiceWars;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Scanner;
public class HexDisplay extends JPanel {
private static final long serialVersionUID = 1L;
public static final int SIZE = 200;
private int height;
private int width;
private Hex[][] hex;
private BufferedImage myImage;
private Graphics drawer;
public HexDisplay(File f) throws IOException {
Scanner key = new Scanner(f);
int[] temp = commaSplit(key.nextLine());
height = temp[0];
width = temp[1];
hex = new Hex[width][height];
for (int w = 0; w < width; w++) {
for (int h = 0; h < height; h++) {
//temp = commaSplit(key.nextLine());
if (h % 2 == 0)
hex[w][h] = new Hex((int) (SIZE * (w + 0.5)),
(int) (SIZE * (h + 0.5)), SIZE);
else
hex[w][h] = new Hex((int) (SIZE * (w + 1.5)),
(int) (SIZE * (h + 0.5)), SIZE);
System.out.println(hex[w][h].getX() + " " + hex[w][h].getY());
}
}
key.close();
starting();
ImageIO.write(myImage, "jpg", new File("outPic.jpg"));
}
public void starting() {
setPreferredSize(new Dimension(400,400));
setLayout(new FlowLayout());
myImage = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
drawer = myImage.getGraphics();
drawer.setColor(Color.BLUE);
drawer.fillRect(0, 0, 400, 400);
drawStuff(drawer);
repaint();
}
public int[] commaSplit(String s) {
String[] str = s.split(",");
int[] ret = new int[str.length];
for (int i = 0; i < str.length; i++) {
ret[i] = Integer.parseInt(str[i]);
}
return ret;
}
public void paintComponents(Graphics g) {
g.drawImage(myImage, 0, 0, this);
System.out.println("Painted");
}
public void drawStuff(Graphics g) {
for (int w = 0; w < width; w++) {
for (int h = 0; h < height; h++) {
hex[w][h].draw(g);
}
}
System.out.println("Drew");
revalidate();
repaint();
paintComponents(g);
}
}
What I would expect to happen is for the frame that contains this JPanel to display the image, but it does not. All System.out.println() methods are called as expected, and I am able to save the image as a .jpg file. However, the image is not displayed in the GUI. What can be done?
You have a typo:
// v
public void paintComponents(Graphics g) {
It should be paintComponent.
And should contain a call to super method:
super.paintComponent(g);
as the first line in the method
Related
this is my first time asking a question on stack overflow.
I've been following this tutorial on making a 2D game with java and have come across a problem...
When run my program it renders my sprite sheet very weirdly:
My JFrame:
his JFrame:
I have no Idea what is causing this problem but here is my code. i'm sorry if it is too long.
game.java:
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
import com.leekman.game.gfx.screen;
import com.leekman.game.gfx.spriteSheet;
public class Game extends Canvas implements Runnable{
private static final long serialVersionUID = 1L;
public boolean running = false;
public static final int WIDTH = 160;
public static final int HEIGHT = WIDTH / 12 * 9;
public static final int SCALE = 3;
public static final String NAME = "Game";
private JFrame frame;
public int tickCount = 0;
private BufferedImage img = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt)img.getRaster().getDataBuffer()).getData();
private screen scrn;
public Game() {
setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
frame = new JFrame(NAME);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(this, BorderLayout.CENTER);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void init() {
scrn = new screen(WIDTH, HEIGHT, new spriteSheet("/Sprite_sheet.png"));
}
private synchronized void start() {
running = true;
new Thread(this).start();
}
private synchronized void stop() {
running = false;
}
#Override
public void run() {
long lastTime = System.nanoTime();
double NSpertick = 1000000000D / 60D;
int ticks= 0;
int frames = 0;
long lastTimer = System.currentTimeMillis();
double unproccesedTime = 0;
init();
while (running) {
long now = System.nanoTime();
unproccesedTime += (now - lastTime) / NSpertick;
lastTime = now;
boolean shouldRender = true;
while (unproccesedTime >= 1) {
ticks++;
tick();
unproccesedTime -= 1;
shouldRender = true;
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (shouldRender) {
frames++;
render();
}
if (System.currentTimeMillis() - lastTimer >= 1000) {
lastTimer += 1000;
System.out.println(frames+", "+ticks);
frames = 0;
ticks = 0;
}
}
}
public void tick() {
tickCount++;
for (int i = 0; i < pixels.length; i++) {
pixels[i] = i + tickCount;
}
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
scrn.render(pixels, 0, WIDTH);
Graphics g = bs.getDrawGraphics();
g.setColor(Color.BLACK);
g.drawRect(0, 0, getWidth(), getHeight());
g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
g.dispose();
bs.show();
}
public static void main(String[] args) {
new Game().start();
}
}
spriteSheet.java:
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class spriteSheet {
public String path;
public int width;
public int height;
public int[] pixels;
public spriteSheet(String path) {
BufferedImage image = null;
try {
image = ImageIO.read(spriteSheet.class.getResourceAsStream(path));
} catch (IOException e) {
e.printStackTrace();
}
if (image == null) {
return;
}
this.path = path;
this.height = image.getHeight();
this.width = image.getWidth();
pixels = image.getRGB(0, 0, width, height, null, 0, width);
for (int i = 0; i < pixels.length; i++) {
pixels[i] = (pixels[i] & 0xff) / 64;
}
for (int i = 0; i < 8; i++) {
System.out.println(pixels[i]);
}
}
}
screen.java:
public class screen {
public static final int MAP_WIDTH = 64;
public static final int MAP_WIDTH_MASK = MAP_WIDTH - 1;
public int[] tiles = new int[MAP_WIDTH * MAP_WIDTH];
public int[] colours = new int[MAP_WIDTH * MAP_WIDTH * 4];
public int Xoffset = 0;
public int Yoffset = 0;
public int height;
public int width;
public spriteSheet sheet;
public screen(int width, int height , spriteSheet sheet) {
this.height = height;
this.width = width;
this.sheet = sheet;
for (int i = 0; i < MAP_WIDTH * MAP_WIDTH; i++) {
colours[i * 4 + 0] = 0xff00ff;
colours[i * 4 + 1] = 0x00ffff;
colours[i * 4 + 2] = 0xffff00;
colours[i * 4 + 3] = 0xffffff;
}
}
public void render(int[] pixels, int offset, int row) {
for (int yTile = Yoffset >> 3; yTile <= (Yoffset + height) >> 3; yTile++) {
int yMin = yTile * 8 - Yoffset;
int yMax = yMin + 8;
if (yMin < 0) {
yMin = 0;
}
if (yMax > height) {
yMax = height;
}
for (int xTile = Xoffset >> 3; xTile <= (Xoffset + width) >> 3; xTile++) {
int xMin = xTile * 8 - Xoffset;
int xMax = xMin + 8;
if (xMin < 0) {
xMin = 0;
}
if (xMax > width) {
xMax = width;
}
int tileIndex = (xTile & (MAP_WIDTH_MASK)) + (yTile & (MAP_WIDTH_MASK)) * MAP_WIDTH;
for (int y = yMin; y < yMax; y++) {
int sheetpix = y + ((y + Yoffset) & 7) * sheet.width + ((xMin + Xoffset) & 7);
int tilepix = offset + xMin + y * row;
for (int x = xMin; x < xMax; x++) {
int colour = tileIndex * 4 + sheet.pixels[sheetpix++];
pixels[tilepix++] = colours[colour];
}
}
}
}
}
}
Any help would be very much appreciated, thanks!!
Im searching for an algorythem to get the location of a hexagon in a grid.
I found this one but it doesnt seam to work:
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
grid[i][j] = new Hexagon(x+(j*((3*Hexagon.S)/2)), y+((j%2)*Hexagon.A)+(2*i*Hexagon.A));
}
}
The output is kind of strange:
output
This is the window-creating class(just a test class):
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Grid extends JPanel {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
int width = 2;
int height = 4;
int x = 100;
int y = 100;
Hexagon[][] grid = new Hexagon[width][height];
JFrame f = new JFrame();
Container cp = f.getContentPane();
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
grid[i][j] = new Hexagon(x+(j*((3*Hexagon.S)/2)), y+((j%2)*Hexagon.A)+(2*i*Hexagon.A));
cp.add(grid[i][j]);
}
}
f.setLayout(null);
f.setBounds(100, 100, 300, 300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
The Hexagon.java class:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import javax.swing.JButton;
public class Hexagon extends JButton {
public static final int S = 50;
public static final int A = (int) (Math.sqrt(3)*(S/2));
private static final long serialVersionUID = 1L;
private final int x, y;
private final Polygon shape;
public Hexagon(int x, int y) {
this.x = x;
this.y = y;
this.shape = initHexagon();
setSize(2*S, 2*A);
setLocation(x-S, y-A);
setContentAreaFilled(false);
}
private Polygon initHexagon() {
Polygon p = new Polygon();
p.addPoint(x+(S/2), y-A);
p.addPoint(x+S, y);
p.addPoint(x+(S/2), y+A);
p.addPoint(x-(S/2), y+A);
p.addPoint(x-S, y);
p.addPoint(x-(S/2), y-A);
return p;
}
protected void paintComponent(Graphics g) {
g.setColor(Color.BLACK);
g.drawPolygon(this.shape);
}
protected void paintBorder(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(4));
g2.drawPolygon(this.shape);
}
public boolean contains(int x, int y) {
return this.shape.contains(x, y);
}
}
As i said, this class worked just fine using non-rectangular shapes.
There was no clipping or such.
You've posted your definition of Hexagon too late, so I copy-pasted a modified version of a similar class from my collection of code snippets.
Here is one way to generate a hexagonal grid:
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JComponent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.GridLayout;
import java.util.function.*;
public class Hexagons extends JPanel {
private static final long serialVersionUID = 1L;
/** Height of an equilateral triangle with side length = 1 */
private static final double H = Math.sqrt(3) / 2;
static class Hexagon {
final int row;
final int col;
final double sideLength;
public Hexagon(int r, int c, double a) {
this.row = r;
this.col = c;
this.sideLength = a;
}
double getCenterX() {
return 2 * H * sideLength * (col + (row % 2) * 0.5);
}
double getCenterY() {
return 3 * sideLength / 2 * row;
}
void foreachVertex(BiConsumer<Double, Double> f) {
double cx = getCenterX();
double cy = getCenterY();
f.accept(cx + 0, cy + sideLength);
f.accept(cx - H * sideLength, cy + 0.5 * sideLength);
f.accept(cx - H * sideLength, cy - 0.5 * sideLength);
f.accept(cx + 0, cy - sideLength);
f.accept(cx + H * sideLength, cy - 0.5 * sideLength);
f.accept(cx + H * sideLength, cy + 0.5 * sideLength);
}
}
public static void main(String[] args) {
final int width = 50;
final int height = 50;
final Hexagon[][] grid = new Hexagon[height][width];
for(int row = 0; row < height; row++) {
for(int col = 0; col < width; col++) {
grid[row][col] = new Hexagon(row, col, 50);
}
}
JFrame f = new JFrame("Hexagons");
f.getContentPane().setLayout(new GridLayout());
f.getContentPane().add(new JComponent() {
#Override public void paint(Graphics g) {
g.setColor(new Color(0xFF, 0xFF, 0xFF));
g.fillRect(0,0,1000,1000);
g.setColor(new Color(0,0,0));
final int[] xs = new int[6];
final int[] ys = new int[6];
for (Hexagon[] row : grid) {
for (Hexagon h: row) {
final int[] i = {0};
h.foreachVertex((x, y) -> {
xs[i[0]] = (int)((double)x);
ys[i[0]] = (int)((double)y);
i[0]++;
});
g.drawPolygon(xs, ys, 6);
g.drawString(
"(" + h.row + "," + h.col + ")",
(int)(h.getCenterX() - 15),
(int)(h.getCenterY() + 12)
);
}
}
}
});
f.setBounds(0, 0, 500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
try {
Thread.sleep(100);
} catch (Throwable e) {
} finally {
f.repaint();
}
}
}
It produces the following output:
Sorry for the lack of anti-aliasing. A few hints:
Height H of an equilateral triangle with unit side length is sqrt(3) / 2
The six offsets from the center are (0, +1), (H, +1/2), (H, -1/2), (0, -1), (-H, -1/2), (-H, +1/2), everything times side length.
Distance between rows is 1.5, distance between columns is 2 * H (times scaling constant = side length).
Every odd row is shifted by (0, H) (times scaling constant).
The position of (row,col)-th hexagon is (1.5 * row, 2 * H * (col + 0.5 * (row % 2))) (times constant).
If you want to rotate the hexagons such that two of their sides are horizontal, you have to flip rows and columns.
I am working on a program that I can use to present topics in front of my class. While MS Powerpoint and similar programs are nice, I feel like they are lacking in some areas. I am not trying to re-create these programs, I am only trying to make a program where I can type text into String arrays, add images, and position them all on the screen.
Currently my program opens a fullscreen dark window with a little X in the top left, which when clicked will close the program.
Here is the class file:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
static JFrame frame;
static MyPanel panel;
static MouseListener listener;
static final int letterWidth = 6;
static final int letterHeight = 9;
static final int letterRow = 10;
static final int letterCol = 11;
static final int letterNum = 110;
static String[] textA = {"Hello World,",
"Here is a test",
"of what I can do.",
"Isn't it neat?!"
};
static int textX = 100;
static int textY = 100;
public static void main(String[] args){
System.out.println("Welcome to Presenter");
System.out.println("Beginning loading");
frame = new JFrame();
panel = new MyPanel();
listener = new MouseListener(){
public void mouseClicked(MouseEvent arg0) {
if(arg0.getButton() ==MouseEvent.BUTTON1){
//Close button
int x = (int) MouseInfo.getPointerInfo().getLocation().getX();
int y = (int) MouseInfo.getPointerInfo().getLocation().getY();
if(x>20 && x<48 && y>20 && y<56){
frame.dispose();
System.exit(0);
}
}
}
public void mouseEntered(MouseEvent arg0) {}
public void mouseExited(MouseEvent arg0) {}
public void mousePressed(MouseEvent arg0) {}
public void mouseReleased(MouseEvent arg0) {}
};
frame.setUndecorated(true);
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setFocusable(true);
frame.add(panel);
frame.addMouseListener(listener);
System.out.println("");
System.out.println("Loading Complete");
}
public static class MyPanel extends JPanel{
private static final long serialVersionUID = 1L;
HashMap<String, BufferedImage> iLetters;
static BufferedImage exitButton = new BufferedImage(28, 36, BufferedImage.TYPE_INT_ARGB);
static BufferedImage letters = new BufferedImage(120, 198, BufferedImage.TYPE_INT_ARGB);
Scanner lightbulb;
static boolean point = false;
int x;
int y;
BufferedImage textBox;
int boxW, boxH;
public MyPanel(){
//pictures
File a = new File("Exit.png");
try { exitButton = ImageIO.read(a); } catch (IOException e) {e.printStackTrace();}
a = new File("Letters.png");
try { letters = ImageIO.read(a); } catch (IOException e) {e.printStackTrace();}
//letter index
try { lightbulb = new Scanner(new File("letters.txt")); } catch (FileNotFoundException e) {e.printStackTrace();}
System.out.println("Files Read");
//create letters
System.out.println("Beginning tiling");
iLetters = new HashMap<String, BufferedImage>();
BufferedImage[] pics = new BufferedImage[letterNum];
int count = 0;
for(int x=0; x<letterCol; x++){
for(int y=0; y<letterRow; y++){
pics[count] = new BufferedImage(letterWidth, letterHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D gr = pics[count++].createGraphics();
gr.drawImage(letters, 0, 0, letterWidth, letterHeight, letterWidth * y, letterHeight * x, letterWidth * y + letterWidth, letterHeight * x + letterHeight, null);
gr.dispose();
}
System.out.println("Row " + x + " tiled.");
}
System.out.println("Completed Tiling");
System.out.println("Beginning indexing");
int loc = 0;
String key = "";
while(lightbulb.hasNext()){
loc = lightbulb.nextInt()-1;
key = lightbulb.next();
iLetters.put(key, pics[loc]);
}
System.out.println("Indexing Complete");
System.out.println("Making Text Boxes");
makeTextBox(textA);
System.out.println("Text Boxes Made");
}
public void paintComponent(Graphics g){
super.paintComponent(g);
this.setBackground(new Color(0, 0, 10));
g.drawImage(exitButton, 20, 20, null);
// g.drawImage(iLetters.get("A"), 100, 100, null);
drawTexts(g);
}
public void drawTexts(Graphics g){
g.drawImage(textBox, textX, textY, textX+(boxW*2), textY+(boxH*2), null);
}
public int findLongest(String[] text){
int longest = 0;
for(int i=0; i<text.length; i++){
if(text[i].length() > longest)
longest = text[i].length();
}
return longest;
}
public void makeTextBox(String[] text){
int longest = findLongest(text);
boxW = (longest*6)+(longest-1);
boxH = (text.length*9)+(text.length-1);
textBox = new BufferedImage(boxW, boxH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = textBox.createGraphics();
char[] line;
int drawX = 0;
int drawY = 0;
for(int i=0; i<text.length; i++){
line = text[i].toCharArray();
for(int j=0; j<line.length; j++){
if(j<line.length-1){
g2d.drawImage(iLetters.get(line[j]), drawX, drawY, null);
drawX += letterWidth + 1;
}
else{
g2d.drawImage(iLetters.get(line[j]), drawX, drawY, null);
}
}
if(i<text.length-1){
drawY += letterHeight + 1;
}
else{
drawY += letterHeight;
}
}
g2d.dispose();
}
}
}
The rest of the files needed for it to run are here http://www.mediafire.com/?jq8vi4dm3t4b6
2 PNGs and 1 text file.
The program runs fine with no errors. The only problem is the drawTexts() method. When the method is called, the lines of text do not appear anywhere on screen, when they should be appearing at (100, 100) at 2x the size of the letters in the file.
It's been a while since I did graphics. I remember needing to call repaint() somewhere, but I cannot remember if I need it here, and if I do, where it goes.
Okay, this might take some time...
There are 10 columns and 11 rows, these are around the wrong way...
static final int letterRow = 10;
static final int letterCol = 11;
I don't think you understand what gr.drawImage(letters, 0, 0, letterWidth, letterHeight, letterWidth * y, letterHeight * x, letterWidth * y + letterWidth, letterHeight * x + letterHeight, null); is actually doing, what you really want is BufferedImage#getSubImage...
BufferedImage subimage = letters.getSubimage(letterWidth * x, letterHeight * y, letterWidth, letterHeight);
You're reading the Letters.png file in row/column order, but building the mapping as if it was in column/row order...
Instead of...
for (int x = 0; x < letterCol; x++) {
for (int y = 0; y < letterRow; y++) {
You should be using...
for (int y = 0; y < letterRow; y++) {
for (int x = 0; x < letterCol; x++) {
The lightbulb Scanner is not reading the file...I'm don't use Scanner that often, but when I changed it to lightbulb = new Scanner(new BufferedReader(new FileReader("letters.txt"))); it worked...
In your makeTextBox method you are trying to retrieve the image using a char instead of String, this means the lookup fails as the two keys are incompatible. You need to use something more like...
BufferedImage img = iLetters.get(Character.toString(line[j]));
Also, on each new line, you are not resting the drawX variable, so the text just keeps running off...In fact, I just re-wrote the loop to look more like...
for (int i = 0; i < text.length; i++) {
line = text[i].toCharArray();
for (int j = 0; j < line.length; j++) {
BufferedImage img = iLetters.get(Character.toString(line[j]));
g2d.drawImage(img, drawX, drawY, null);
if (j < line.length - 1) {
drawX += letterWidth + 1;
}
}
drawX = 0;
if (i < text.length - 1) {
drawY += letterHeight + 1;
} else {
drawY += letterHeight;
}
}
And yes, it could be simplified more, but little steps...
There might be a bunch of other things, but that should get you a step closer...
Hi guys i'm trying to create a draughts game in Java and am using JPanels to represent the squares, if I were to change the size of the panels how would I do so ? if I use a layout manager the squares are not big enough. At the moment i'm not using a layout manager to try and change the size, but the size doesnt seem to change - just stays at 1,1 pixel.
private void createSquares(){
for(int i = 0; i < 65; i++){
squares[i] = new JPanel();
squares[i].setLayout(null);
squares[i].setSize(20,20);
board.add(squares[i]);
}
}
You could always "borrow" an image or two online, and put that into your program. For example this code:
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class GetChessSquareImages {
public static final String PATH_TO_SQUARES = "http://www.colourbox.com/preview/" +
"4578561-622234-seamless-oak-square-chess-like-parquet-texture.jpg";
private static final int IMG_SIDE_COUNT = 4;
private static final double SCALE = 0.8;
private Map<SquareColor, List<Icon>> squareColorMap = new HashMap<SquareColor, List<Icon>>();
private Random random = new Random();
public void downloadImages() throws IOException {
URL lrgImgUrl = new URL(PATH_TO_SQUARES);
BufferedImage largeImg = ImageIO.read(lrgImgUrl);
int w = largeImg.getWidth() / IMG_SIDE_COUNT;
int h = largeImg.getHeight() / IMG_SIDE_COUNT;
for (int i = 0; i < IMG_SIDE_COUNT; i++) {
int x = (i * largeImg.getWidth()) / IMG_SIDE_COUNT;
for (int j = 0; j < IMG_SIDE_COUNT; j++) {
if (j != 1 && j != 2) {
int y = (j * largeImg.getHeight()) / IMG_SIDE_COUNT;
extractSubImg(largeImg, i, j, x, y, w, h);
}
}
}
}
private void extractSubImg(BufferedImage largeImg,
int i, int j, int x, int y, int w, int h) {
Image subImg = largeImg.getSubimage(x, y, w, h);
int width = (int) (w * SCALE);
int height = (int) (h * SCALE);
subImg = subImg.getScaledInstance(width, height, Image.SCALE_SMOOTH);
List<Icon> iconList = null;
if (i % 2 == j % 2) {
iconList = squareColorMap.get(SquareColor.LIGHT);
if (iconList == null) {
iconList = new ArrayList<Icon>();
squareColorMap.put(SquareColor.LIGHT, iconList);
}
} else {
iconList = squareColorMap.get(SquareColor.DARK);
if (iconList == null) {
iconList = new ArrayList<Icon>();
squareColorMap.put(SquareColor.DARK, iconList);
}
}
iconList.add(new ImageIcon(subImg));
}
public Icon getRandomIcon(SquareColor sqrColor) {
List<Icon> iconList = squareColorMap.get(sqrColor);
if (iconList == null) {
return null;
} else {
return iconList.get(random.nextInt(iconList.size()));
}
}
public static void main(String[] args) {
GetChessSquareImages getImages = new GetChessSquareImages();
try {
getImages.downloadImages();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
int side = 8;;
JPanel panel = new JPanel(new GridLayout(side , side));
for (int i = 0; i < side; i++) {
for (int j = 0; j < side; j++) {
SquareColor sqrColor = (i % 2 == j % 2) ? SquareColor.LIGHT : SquareColor.DARK;
Icon icon = getImages.getRandomIcon(sqrColor);
panel.add(new JLabel(icon));
}
}
JOptionPane.showMessageDialog(null, panel);
}
}
enum SquareColor {
DARK, LIGHT
}
returns this JPanel:
Then your square size will be based on the sizes of your ImageIcons. For example, I have scaled my squares back with a scale factor of 0.8 (the SCALE constant above) to make the grid a more reasonable size.
I have been working on a game via youtube tutorial, some of you may recognize it as the one presents by designsbyzephr and have run into an issue. I am fairly sure the code is correct as I have used the call before in a previous project. I am getting an array out of bounds exception even when using the full project source code posted on github. Any suggestions?
package Game;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
import GFX.Screen;
import GFX.SpriteSheet;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static final int WIDTH = 160;
public static final int HEIGHT = WIDTH / 12 * 9;
public static final int SCALE = 3;
public static final String NAME = "Game";
private JFrame frame;
public boolean running = false;
public int tickcount = 0;
private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
private Screen screen;
public Game() {
setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
frame = new JFrame(NAME);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(this, BorderLayout.CENTER);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void init() {
screen = new Screen(WIDTH, HEIGHT, new SpriteSheet("/Sprites/spritesheet.png"));
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
screen.render(pixels, 0, WIDTH);
Graphics g = bs.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.dispose();
bs.show();
}
public synchronized void start() {
running = true;
new Thread(this).start();
}
public synchronized void stop() {
running = false;
}
public void run() {
long lastTime = System.nanoTime();
double nsPerTick = 1000000000D / 60D;
int ticks = 0;
int frames = 0;
long lastTimer = System.currentTimeMillis();
double delta = 0;
init();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / nsPerTick;
lastTime = now;
boolean shouldRender = true;
while (delta >= 1) {
ticks++;
tick();
delta -= 1;
shouldRender = true;
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (shouldRender) {
frames++;
render();
}
if (System.currentTimeMillis() - lastTimer >= 1000) {
lastTimer += 1000;
frames = 0;
ticks = 0;
}
}
}
public void tick() {
tickcount++;
for (int i = 0; i < pixels.length; i++)
pixels[i] = i + tickcount;
}
public static void main(String[] args) {
new Game().start();
}
}
package GFX;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SpriteSheet {
public String path;
public int width;
public int height;
public int[] pixels;
public SpriteSheet(String path) {
BufferedImage image = null;
try
{
image = ImageIO.read(SpriteSheet.class.getResourceAsStream(path));
}
catch (IOException e)
{
e.printStackTrace();
}
if (image == null) return;
this.path = path;
this.width = image.getWidth();
this.height = image.getHeight();
pixels = image.getRGB(0, 0, width, height, null, 0, width);
for (int i = 0; i < pixels.length; i++) {
pixels[i] = (pixels[i] & 0xff) / 64;
}
for (int i = 0; i < 8; i++)
System.out.println(pixels[i]);
}
}
package GFX;
public class Screen {
public static final int MAP_WIDTH = 64;
public static final int MAP_WIDTH_MASK = MAP_WIDTH - 1;
public int[] tiles = new int[MAP_WIDTH * MAP_WIDTH];
public int[] colors = new int[MAP_WIDTH * MAP_WIDTH];
public int xOffset = 0;
public int yOffset = 0;
public int width;
public int height;
public SpriteSheet sheet;
public Screen(int width, int height, SpriteSheet sheet) {
this.width = width;
this.height = height;
this.sheet = sheet;
for (int i = 0; i < MAP_WIDTH * MAP_WIDTH; i++) {
colors[i * 4 + 0] = 0xff00ff;
colors[i * 4 + 1] = 0x00ffff;
colors[i * 4 + 2] = 0xffff00;
colors[i * 4 + 3] = 0x0000ff;
}
}
public void render(int[] pixels, int offset, int row) {
for (int yTile = yOffset >> 3; yTile <= (yOffset + height) >> 3; yTile++) {
int yMin = yTile * 8 - yOffset;
int yMax = yMin + 8;
if (yMin < 0)
yMin = 0;
if (yMin > height)
yMax = height;
for (int xTile = xOffset >> 3; xTile <= (xOffset + width) >> 3; xTile++) {
int xMin = xTile * 8 - xOffset;
int xMax = xMin + 8;
if (xMin < 0)
xMin = 0;
if (xMin > width)
xMax = width;
int tileIndex = (xTile & (MAP_WIDTH_MASK))
+ (yTile & (MAP_WIDTH_MASK)) * MAP_WIDTH;
for (int y = yMin; y < yMax; y++) {
int sheetPixel = ((y + yOffset) & 7) * sheet.width
+ ((xMin + xOffset) & 7);
int tilePixel = offset + xMin + y * row;
for (int x = xMin; x < xMax; x++) {
int color = tileIndex * 4 + sheet.pixels[sheetPixel++];
pixels[tilePixel++] = colors[color];
}
}
}
}
}
}
That is all the code so far. the error is as follows
Exception in thread "Thread-2" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(Unknown Source)
at GFX.SpriteSheet.(SpriteSheet.java:22)
at Game.Game.init(Game.java:54)
at Game.Game.run(Game.java:91)
at java.lang.Thread.run(Unknown Source)
it is in this line
image = ImageIO.read(SpriteSheet.class.getResourceAsStream(path));
your program cannot find file so it is returning null and a null pointer exception is thrown when you try and read from null
you need to make sure there is a file"/Sprites/spritesheet.png" relative to where you are running the program