Coordinate Out Of Bounds Exception With BufferedImage - java

Right now i am trying to make a game. I am having problems with loading my images. To do so I have to give an image to the removeImageBackground(BufferedImage img, Color tc) method in my Main class. Basically what this method does is take the image specified in the parameters (img). What happens next is it goes through the image with some for statements and if it finds a pixel who's color matches the color specified in the parameters (tc) it changes that pixel to be transparent. I have no problem with this but then what happens next in this method is the image is then expanded (this has to be done because my game has 8-bit graphics). anyway it makes a new bufferedimage named outImg. I have 4 nested for statements after that. The first 2 cycle through the original img image and the last 2 cycle through the new outImg image. What this does is reads the original img image while writing 5x5 pixel squares into the new outImg image in the corresponding locations. But it's at this line of code that I have a problem. I keep getting arrayindexoutofboundsexceptions. I tried putting in System.out.println() statements to try to debug, but I can't seem to figure out what's wrong. Here's the part of my code where I'm having problems, along with my error messages and my debug results:
My removeImageBackground method from my Main Class:
//removed the background of the given image with the given transparent color
public static BufferedImage removeImageBackground(BufferedImage img, Color tc) {
System.out.println("Method Fired:Main.removeImageBackground(BufferedImage img, Color tc)"); //debug
//remove the background
for(int y = 0; y < img.getHeight(); y++) {
for(int x = 0; x < img.getWidth(); x++) {
Color c = new Color(img.getRGB(x, y));
if(c == tc) {
c = new Color(c.getRed(), c.getGreen(), c.getBlue(), 255);
}
img.setRGB(x, y, c.getRGB());
}
}
//expand the image
BufferedImage outImg = new BufferedImage(img.getWidth() * graphicsScale, img.getHeight() * graphicsScale, BufferedImage.TYPE_INT_ARGB);
System.out.println("outImg height=" + outImg.getHeight());
System.out.println("outImg width=" + outImg.getWidth());
for(int y = 0; y < img.getHeight(); y++) {
System.out.println("for y=" + y);
System.out.println("img height=" + img.getHeight());
for(int x = 0; x < img.getWidth(); x++) {
System.out.println("for x=" + x);
System.out.println("img width=" + img.getWidth());
for(int y2 = 0; y2 < graphicsScale; y++) {
for(int x2 = 0; x2 < graphicsScale; x++) {
outImg.setRGB((x * graphicsScale) + x2, (y * graphicsScale) + y2, img.getRGB(x, y));
}
}
}
}
return outImg;
}
My entire Gale Class (Which is specified in My error messages):
package entity;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import main.Main;
public class Gale extends Player {
//variables
private static BufferedImage downStand;
private static BufferedImage leftStand;
private static BufferedImage rightStand;
private static BufferedImage upStand;
private static BufferedImage downWalk;
private static BufferedImage leftWalk;
private static BufferedImage rightWalk;
private static BufferedImage upWalk;
private static String objectName = "Gale";
//constructors
//used ONLY when loading
public Gale() throws IOException {
System.out.println("Constructor Fired:Gale()"); //debug
downStand = Main.removeImageBackground(ImageIO.read(new File(Main.filePath + Main.directory + Main.resourceFile + Main.directory + objectName + Main.directory + "DownStand.jpg")), Main.transparentColor);
leftStand = Main.removeImageBackground(ImageIO.read(new File(Main.filePath + Main.directory + Main.resourceFile + Main.directory + objectName + Main.directory + "LeftStand.jpg")), Main.transparentColor);
rightStand = Main.removeImageBackground(ImageIO.read(new File(Main.filePath + Main.directory + Main.resourceFile + Main.directory + objectName + Main.directory + "RightStand.jpg")), Main.transparentColor);
upStand = Main.removeImageBackground(ImageIO.read(new File(Main.filePath + Main.directory + Main.resourceFile + Main.directory + objectName + Main.directory + "UpStand.jpg")), Main.transparentColor);
downWalk = Main.removeImageBackground(ImageIO.read(new File(Main.filePath + Main.directory + Main.resourceFile + Main.directory + objectName + Main.directory + "DownWalk.jpg")), Main.transparentColor);
leftWalk = Main.removeImageBackground(ImageIO.read(new File(Main.filePath + Main.directory + Main.resourceFile + Main.directory + objectName + Main.directory + "LeftWalk.jpg")), Main.transparentColor);
rightWalk = Main.removeImageBackground(ImageIO.read(new File(Main.filePath + Main.directory + Main.resourceFile + Main.directory + objectName + Main.directory + "RightWalk.jpg")), Main.transparentColor);
upWalk = Main.removeImageBackground(ImageIO.read(new File(Main.filePath + Main.directory + Main.resourceFile + Main.directory + objectName + Main.directory + "UpWalk.jpg")), Main.transparentColor);
}
//to be used for anything else
public Gale(int x, int y) {
System.out.println("Constructor Fired:Gale(int x, int y)"); //debug
}
//methods
//returns the images
public BufferedImage getDownStand() {
System.out.println("Method Fired:Gale.getDownStand()"); //debug
return downStand;
}
public BufferedImage getLeftStand() {
System.out.println("Method Fired:Gale.getLeftStand()"); //debug
return leftStand;
}
public BufferedImage getRightStand() {
System.out.println("Method Fired:Gale.getRightStand()"); //debug
return rightStand;
}
public BufferedImage getUpStand() {
System.out.println("Method Fired:Gale.getUpStand()"); //debug
return upStand;
}
public BufferedImage getDownWalk() {
System.out.println("Method Fired:Gale.getDownWalk()"); //debug
return downWalk;
}
public BufferedImage getLeftWalk() {
System.out.println("Method Fired:Gale.getLeftWalk()"); //debug
return leftWalk;
}
public BufferedImage getRightWalk() {
System.out.println("Method Fired:Gale.getRightWalk()"); //debug
return rightWalk;
}
public BufferedImage getUpWalk() {
System.out.println("Method Fired:Gale.getUpWalk()"); //debug
return upWalk;
}
}
My Debug Results:
Method Fired:Main.removeImageBackground(BufferedImage img, Color tc)
outImg height=250
outImg width=125
for y=0
img height=50
for x=0
img width=25
My Error Messages:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Coordinate out of bounds!
at sun.awt.image.ByteInterleavedRaster.getDataElements(ByteInterleavedRaster.java:318)
at java.awt.image.BufferedImage.getRGB(BufferedImage.java:888)
at main.Main.removeImageBackground(Main.java:101)
at entity.Gale.<init>(Gale.java:28)
at main.Main.load(Main.java:186)
at main.Main.main(Main.java:69)
That's pretty much it. My main method just calls on my load method. And my load method just calls on my Gale() constructor. So there shouldn't be a problem in either of those.
Someone please help me fix this. I'm really excited to get this game finished and this is becoming a very big problem for me since it is preventing me from loading everything.

Really quickly...
for(int y2 = 0; y2 < graphicsScale; y++) {
for(int x2 = 0; x2 < graphicsScale; x++) {
You are incrementing x and y within your inner loop, which I believe you want to be incrementing x2 and y2
for(int y2 = 0; y2 < graphicsScale; y2++) {
for(int x2 = 0; x2 < graphicsScale; x2++) {
Original...
Scaled (4x)

Related

Java Applet: Why Is This Animation So Quick and How Can I Make It Slower

I am working on a Java Applet and just for bonus points, I wanted to see if I could animate the trajectory of what I made. I got it draw() function to animate how I wanted it to, but the animation is really quick and you can barely see it. I tried increasing the milliseconds in the threaded process, but it made no difference. Hopefully my question makes sense. I included my code below.
public class Slinkey extends Applet implements Runnable {
private static final long serialVersionUID = 4803949557086825455L;
private Thread animation;
private boolean stopSlinky;
#Override
public void start() {
stopSlinky = false;
animation = new Thread(this);
animation.start();
}
public void paint(Graphics g) { // This can probably be ignored.
Graphics2D g2 = (Graphics2D) g;
int x = 10;
int y = 10;
int w = 100;
int h = 100;
int k = 0;
int otherX = 0;
double xpos = 0, ypos = 10;
System.out.println(xpos + " " + ypos);
Ellipse2D.Double c1 = new Ellipse2D.Double(ypos, ypos, w, h);
for (k = 0; k < 155; k += 5) {
xpos = x + k;
ypos = getYStart(xpos);
System.out.println(xpos + " " + ypos);
c1.setFrame(xpos, ypos, w, h); // (10, 10) (1325, 650)
g2.draw(c1);
}
for (int i = 160; i < 775; i++) {
xpos = x + i;
otherX++;
ypos = getYMain(otherX);
if (ypos < 652) {
System.out.println("Y Coordinate: " + xpos + " " + ypos);
c1.setFrame(xpos, ypos, w, h);
g2.draw(c1);
}
}
for (int j = 775; j < 1325; j++) {
xpos = x + j;
otherX++;
ypos = (0.7) * (getYMain(otherX - 500) + 400);
if (ypos < 652) {
System.out.println("Y Coordinate: " + xpos + " " + ypos);
c1.setFrame(xpos, ypos, w, h);
g2.draw(c1);
}
}
}
public static double getYStart(double x) {
return (0.029) * (Math.pow(x - 10, 2) + 10);
}
public static double getYMain(double x) {
return ((0.005) * Math.pow(x - 350, 2) + 300);
}
#Override
public void run() {
while (true) {
if (stopSlinky) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void stop() {
stopSlinky = true;
animation = null;
}
}
(I know the code is very messy. I'm working on organizing it.)

JAVA Efficient way to draw bullets firing from character to mouse position?

I'm creating a 2d game and I wanted to implement shooting. However, bullets for some reason shoot only at a -45° angle. Provided below is my code. The if statement is also important and needs to know when the bullet goes out of range. I've looked up answers for the issue and none of them seem to work.
Also, .getEntity returns the JLabel of the entity.
public class Bullet extends Entity
{
private double speed, dmg, dist, vX, vY, xDest, yDest;
private double traveledDist = 0;
private JLabel bullet;
private String img;
public Bullet(double nSpeed, double nDmg, double xDest, double yDest, double nDistance, String img, double vX,
double vY)
{
super(80, 80, "res/img/bullet.png");
speed = nSpeed;
dmg = nDmg;
dist = nDistance;
this.xDest = xDest;
this.yDest = yDest;
this.img = img;
this.vX = vX;
this.vY = vY;
Image image = new ImageIcon("res/img/bullet.png").getImage().getScaledInstance(20, 20, Image.SCALE_DEFAULT);
ImageIcon imageicon = new ImageIcon(image);
JLabel bullet = new JLabel(imageicon);
bullet.setSize(80, 80);
bullet.setVisible(true);
}
public String toString()
{
return ("[Speed: " + speed + ", Damage: " + dmg + ", xDest: " + xDest + ", yDest: " + yDest + ", vX:" + vX
+ ", vY" + vY + ", Distance: " + dist + ", Traveled Distance: " + traveledDist + ", Image Path: " + img
+ "]");
}
public double getxDest()
{
return xDest;
}
public double getyDest()
{
return yDest;
}
public double getvX()
{
return vX;
}
public double getvY()
{
return vY;
}
public JLabel newBullet()
{
return bullet;
}
public double getSpeed()
{
return speed;
}
public double getDmg()
{
return dmg;
}
public double getDist()
{
return dist;
}
public String getImg()
{
return img;
}
public double getTraveledDist()
{
return traveledDist;
}
public void setTraveledDist(double nDist)
{
traveledDist = nDist;
}
}
private void fireBullet()
{
System.out.println("bullet");
double originX = lblCross.getX() - lblChar.getX();
double originY = lblCross.getY() - lblChar.getY();
double mouseX = MouseInfo.getPointerInfo().getLocation().getX();
double mouseY = MouseInfo.getPointerInfo().getLocation().getY();
double bulletVelocity = 1.0;
//mouseX/Y = current x/y location of the mouse
//originX/Y = x/y location of where the bullet is being shot from
double angle = Math.atan2(mouseX - originX, mouseY - originY);
double xVelocity = (bulletVelocity) * Math.cos(angle);
double yVelocity = (bulletVelocity) * Math.sin(angle);
Bullet tempBullet = new Bullet(((ProjectileWeapon) sWeapon).getProjectileSpeed(), sWeapon.getDamage(), 0, 0,
sWeapon.getRange() * 100, ("res/img/bullet.png"), xVelocity, yVelocity);
tempBullet.getEntity().setVisible(true);
room.add(tempBullet.getEntity());
room.repaint();
tempBullet.getEntity().setLocation(lblChar.getX(), lblChar.getY());
bullets.add(tempBullet);
}
private void updateBullet()
{
for (int i = 0; i < bullets.size(); i++)
{
bullets.get(i).getEntity().getY());
if (true)
{
System.out.println("updating" + bullets.get(i));
Bullet b = bullets.get(i);
b.getEntity().setLocation((int) (b.getEntity().getLocation().getX() + (b.getvX() * 10)),
(int) (b.getEntity().getLocation().getY() + (b.getvY() * 10)));
b.setTraveledDist(b.getTraveledDist() + 1);
room.repaint();
}
else
{
room.remove(bullets.get(i).getEntity());
bullets.remove(i);
room.repaint();
}
}
}
Your help is much appreciated.
Here's the code I ultimately used:
double theta = Math.atan2(destination.getY() - origin.getY(), destination.getX() -
origin.getX());
xVelocity = Math.cos(-theta);
yVelocity = -Math.sin(-theta);

Artifacts using midpoint displacement generation

I am trying to generate terrain for a simple game I'm making using midpoint displacement, and it's working well so far, but I keep getting weird artifacts that I don't see in most of the examples that I see online and I don't really know what is causing them. They look like this:
http://i.imgur.com/uuhfHPg.png
the mostly smooth generation seems to be littered with random and incredibly sudden changes in height. Is this normal or am I doing something wrong?
The class that I'm using to generate the heightmap looks like this:
package util;
import java.util.Random;
public class HeightmapGen {
private HeightmapGen(){}
//The size of the map will be 2^iterations + 1
public static int[][] genMap(int iterations, double roughness){
Random rand = new Random();
return genMap(iterations, roughness, rand.nextLong());
}
public static int[][] genMap(int iterations, double roughness, long seed){
Random r = new Random(seed);
double rConstant = Math.pow(2,-roughness);
double currRoughVal = 1.0;
int size = (int)Math.pow(2,iterations); //size needs to be a power of 2 + 1 - this size includes 0
int subSize = size; //the "working" size of the squares
int stride = subSize/2;
boolean oddline = false; //not entirely sure what this does either...
int[][] map = new int[size + 1][size + 1];
//initalize corners
//int init = r.nextInt();
//int init = 0;
//map[0][0] = map[0][size] = map[size][0] = map[size][size] = init;
map[0][0] = r.nextInt();
map[0][size] = r.nextInt();
map[size][0] = r.nextInt();
map[size][size] = r.nextInt();
while(stride != 0){
//the square part
for(int x = stride; x < subSize; x += stride){
for(int y = stride; y < subSize; y += stride){
map[x][y] = (int)(r.nextInt() * currRoughVal) + avgSquareVals(x, y, stride, map);
y += stride;
}
x += stride;
}
//the diamond part
//not entirely sure what oddline is for, but it seems nessicary
oddline = false;
for (int x = 0; x < subSize; x += stride){
oddline = (oddline == false);
for (int y = 0; y < subSize; y += stride){
if (oddline && y == 0){y += stride;}
map[x][y] = (int)(r.nextInt() * currRoughVal) + avgDiamondVals(x, y, stride, size, subSize, map);
//this wraps the map - i'm ignoring this for now
//if(x == 0){}
//if(y == 0){}
y += stride;
}
//not sure x doesn't need to be incremented, but it doesn't?
}
//reduce range and halve stride
currRoughVal *= rConstant;
stride /= 2;
}
return map;
}
private static int avgSquareVals(int x, int y, int stride, int[][] map){
return (map[x + stride][y + stride] +
map[x + stride][y - stride] +
map[x - stride][y + stride] +
map[x - stride][y - stride])/4;
}
private static int avgDiamondVals(int x, int y, int stride, int size, int subSize, int[][] map){
if(x == 0){
return (map[x + stride][y] +
map[x][y + stride] +
map[x][y - stride])/3;
}
else if(x == size){
return (map[x - stride][y] +
map[x][y + stride] +
map[x][y - stride])/3;
}
else if(y == 0){
return (map[x + stride][y] +
map[x - stride][y] +
map[x][y + stride])/3;
}
else if( y == size){
return (map[x + stride][y] +
map[x - stride][y] +
map[x][y - stride])/3;
}
else{
return (map[x + stride][y] +
map[x - stride][y] +
map[x][y + stride] +
map[x][y - stride])/4;
}
}
}
It's not perfect and parts of it I don't understand - it's based off of the code I found here: http://www.gameprogrammer.com/fractal.html

Compare two screenshots doesn't work correctly-java

i am trying to make two screenshots with 6 seconds difference, to see if there is some changes on the website.
But my code says me that the screenshots are always different, even if i test it without any changing on the screen.
what am i doing wrong?
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screensize = toolkit.getScreenSize();
Rectangle rectangle = new Rectangle(0,0,screensize.width,screensize.height);
Robot robot = new Robot();
BufferedImage image1 = robot.createScreenCapture(rectangle);
System.out.println("screenshot "+i+"");
Thread.sleep(6000);
BufferedImage image2 = robot.createScreenCapture(rectangle);
System.out.println("screenshot "+(i+10)+"");
int x1 = image1.getWidth();
int x2 = image2.getWidth();
if ( x1 != x2 ) {
System.out.println( "Widths are different: " + x1 + " != " + x2 );
return;
}
int y1 = image1.getHeight();
int y2 = image2.getHeight();
if ( y1 != y2 ) {
System.out.println( "Heights are different: " + y1 + " != " + y2 );
return;
}
for ( int x = 0; x < x1; x++ ) {
for ( int y = 0; y < y1; y++ ){
int p1 = image1.getRGB( x, y );
int p2 = image2.getRGB( x, y );
if ( p1 != p2 ) {
System.out.println("Pixel is different at x/y " + x + "/" + y + ": " + p1 + " != " + p2 );
return;
}
}
}
System.out.println( "Images are identical" );
I tried your code and my pixel is different because of a blinking cursor in Eclipse Console.
Then I had a problem with an animated icon (process explorer in task bar)
Finally it said Image identical.
Note : Mouse isn't part of the thing :
Creates an image containing pixels read from the screen. This image does not include the mouse cursor.

How to find variable g in this code?

How to find variable g in this code? I would like to draw line using fillRect from paintComponent.
Please help.
import java.awt.*;
import java.lang.String.*;
import java.util.Scanner;
import java.io.IOException;
import javax.swing.*;
class Test extends JPanel {
public static void main(String[] args) {
String x1;
String x2;
String y1;
String y2;
Scanner sc = new Scanner(System.in);
System.out.print("Podaj pierwsza wspolrzedna pierwszego punktu: ");
x1 = sc.nextLine();
System.out.print("Podaj druga wspolrzedna pierwszego punktu: ");
x2 = sc.nextLine();
System.out.print("Podaj pierwsza wspolrzedna drugiego punktu: ");
y1 = sc.nextLine();
System.out.print("Podaj druga wspolrzedna drugiego punktu: ");
y2 = sc.nextLine();
Test nowy = new Test();
DDA2 dda2 = new DDA2();
dda2.licz(x1, x2, y1, y2);
JFrame ramka = new JFrame();
ramka.setSize(300,300);
ramka.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ramka.getContentPane().add(new Test());
ramka.setVisible(true);
}
}
class DDA2 {
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.RED);
}
public void licz(String xx1, String xx2, String yy1, String yy2){
double dxx1 = Double.parseDouble(xx1);
double dxx2 = Double.parseDouble(xx2);
double dyy1 = Double.parseDouble(yy1);
double dyy2 = Double.parseDouble(yy2);
double dx = dxx2 - dxx1;
double dy = dyy2 - dyy1;
if (Math.abs(dx) >= Math.abs(dy))
{
double m = Math.abs(dx);
System.out.println("DX" + m);
}
else
{
// ALGORYTYM PRZYROSTOWY
double m = Math.abs(dy);
//System.out.println("DY" + m);
double x = dxx1;
double y = dyy1;
for (int i=1; i <= m; i++)
{
x = x + dx/m;
y = y + dy/m;
g.fillRect((int) x, (int) y, 1, 1);
}
}
System.out.println("Wspolrzednie punktu pierwszego to: " + "(" + dxx1 + "; " + dxx2 +")");
System.out.println("Wspolrzednie punktu drugiego to: " + "(" + dyy1 + "; " + dyy2 + ")");
}
}
You need to override the paintComponent(Graphics g) method in the class that extends the JPanel, i.e. your Test class. You wrote a paintComponent method in a class DDA2 but that does nothing.
In the paintComponent method you can then call:
g.fillRect(x, y, w, h);
In addition to what Vincent says, it looks like you want to have the fillRect taking place in your licz method. No problem. Simply call your licz method from the paintComponent method. (It's easiest to do this if your method is defined in the same class as the paintComponent method, by the way.)

Categories

Resources