I'm trying to make a function which separates a pictures into areas by taking each pixel and search recursively
if any of it's 8 nighbors are similar (by comparing their hue value) and then painting over them with the same color.
I started simple in (0,0) and tried to "travel" recursivley to any similar pixel and painting them all in red until i get stuck.
It worked fine on a 55x55 picture but when i tried 300x55 i got the famous StackOverflow exception.
Travel function (after some edits, addad boolean matrix to flag visited pixels):
private static void area( int x, int y){
//img and visited[][] are global variables
int height = img.getHeight();
int width = img.getWidth();
visited[x][y] = true;
int color = img.getRGB(x,y); // store before painting
// if(img.getRGB(x,y) != Color.RED.getRGB())
img.setRGB(x, y, Color.RED.getRGB());
// else
// return;
//spread to 8 directions clockwise
//top
if ((y - 1) >= 0)
if(!visited[x][y-1] && hsbSimilarity(color,img.getRGB(x,y - 1)))
area( x, y - 1);
//top right
if ((x + 1) < width && (y - 1) >= 0)
if(!visited[x+1][y-1] && hsbSimilarity(color, img.getRGB(x + 1,y - 1)))
area( x + 1, y - 1);
//right
if((x + 1) < width)
if(!visited[x+1][y] && hsbSimilarity(color, img.getRGB(x + 1,y)))
area( x + 1, y);
//bot right
if((x + 1) < width && (y + 1) < height)
if(!visited[x+1][y+1] && hsbSimilarity(color, img.getRGB(x + 1,y + 1)))
area(x + 1, y + 1);
//bot
if((y + 1) < height)
if(!visited[x][y+1] && hsbSimilarity(color, img.getRGB(x,y + 1)))
area(x, y + 1);
//bot left
if((x - 1) >= 0 && (y + 1) < height)
if(!visited[x-1][y+1] && hsbSimilarity(color, img.getRGB(x - 1,y + 1)))
area(x - 1, y + 1);
//left
if((x - 1) >= 0)
if(!visited[x-1][y] && hsbSimilarity(color, img.getRGB(x - 1,y)))
area( x - 1, y);
//top left
if((x - 1) >= 0 && (y - 1) >= 0)
if(!visited[x-1][y-1] && hsbSimilarity(color, img.getRGB(x - 1,y - 1)))
area(x - 1, y - 1);
}
Comparison function:
private static boolean hsbSimilarity( int rgb1, int rgb2){
Color color1 = new Color(rgb1);
Color color2 = new Color(rgb2);
float[] hsb1 = new float[3];
float[] hsb2 = new float[3];
color1.RGBtoHSB(color1.getRed(), color1.getGreen(), color1.getBlue(), hsb1);
color2.RGBtoHSB(color2.getRed(), color2.getGreen(), color2.getBlue(), hsb2);
int hue1 = (int)(hsb1[0] * 360);
int hue2 = (int)(hsb2[0] * 360);
int hueDistance = Math.abs(hue1 - hue2);
return hueDistance < 5 || hueDistance > 355 ; //circle concept where 0 equals to 360
}
It seems that you have a cycle problem. This means your code may literally be running in circles (eg. 0|0 0|1 0|0 etc., or sth. alike). Also this is not size related, so I'm pretty sure that everything would be fine for a massive noise picture as how everything would be horibble for a completly red one. To avoid this issue I'd suggest not going back to pixels you already checked on, so maby try populating a list containing the pixels you already visited and then check if the one you are going to travel to is already inside there, and if it is don't go there.
Related
I was working on an animation on processing.
But, I have a question about the code below:
So, you can see on the output, the ball is going everywhere on the window. I want to make a barrier for the ball. The ball can pass from the middle but if it hit the line it goes somewhere with the speed of (int)random(1, 3).
How to make that?
Here is a picture of what I would like to achieve:
One way to do this is to check for collision when the ball passes through the middle, specifically when the ball's velocity would make y pass from < height/2 to > height/2.
Something like this:
if (((y < height/2 && y+dirY > height/2) || (y > height/2 && y+dirY < height/2)) && (x < width/2-middle || x > width/2+middle)){
dirY = (int) random (1,3);
dirX = (int) random (1,3);
}
(A more appropriate solution would be to create the collision when the edge of the ball passes the barrier, but I'll leave that up to you)
I'm not going to write code, but I'll tell you how to calculate it, it's not that hard.
Taken a circle, we know the center and the radius.
Taken a line we know the startpoint and endpoint.
The line intersects the circle if the distance from them center to startpoint or endpoint is smaller than radius (e.g. point is inside circle)
A line intersects circle if startpoint X is on the left of center (sX < cX), endpoint X on the right (eX > cX), and the distance between their Y and the center Y is less than radius (cY - sY < r)
Note that this really applies only in your simple case with a horizontal line. Normally is better to really work with vectors calculations to determine distance from center to line for example. That would allow you to work with diagonal lines etc.
For your toy model, the easiest way to handle collisions is considering a collision zone. So,
Establish the collision zone limits x1, x2, y1, y2. When the center of the ball enters this zone, collision rules apply.
Consider elastic collisions: your ball only collides with an horizontal line, so only the vertical component of the velocity can be affected, and it never looses speed.
Consider to test your toy model with a good bunch of initial conditions, so you can discover any artifacts due to the smallness of your model, the values you are using, and so on. (I have modified the initial position of the ball for a random initial position, run the model several times to see how it behaves under different initial conditions).
int dirX = (int)random(1, 3);
int dirY = (int)random(1, 3);
//int x = 20, y = 20;
int middle = 20;
int x = (int)random(20, 180);
int y = (int)random(20, 80);
int x1, x2, y1, y2;
void setup() {
size(200,200);
// collision zone limits
x1 = (width/2 - middle) + 20/2 - 1; // 89
x2 = (width/2 + middle) - 20/2 + 1; // 111
y1 = height/2 - 20/2 + 1; // 91
y2 = height/2 + 20/2 - 1; // 109
}
void draw() {
background(255);
ellipse(x, y, 20, 20);
line(0, height/ 2, width/2 - middle, height/2); // (0, 100, 80, 100)
line(width/2 + middle, height/2, width, height/2); // (120, 100, 200, 100)
x += dirX;
y += dirY;
if (x > width || x < 0)
dirX *= -1;
if (y > height || y < 0)
dirY *= -1;
if ((x < x1 && y > y1 && y < height/2 && dirY > 0) || // upper left and going down
(x < x1 && y > height/2 && y < y2 && dirY < 0) || // lower left and going up
(x > x2 && y > y1 && y < height/2 && dirY > 0) || // upper right and going down
(x > x2 && y > height/2 && y < y2 && dirY < 0)) // lower right and going up
dirY *= -1;
}
For a more complex model, you could consider more sophisticated situations as, for example, the backwards collision due to the ends of the lines, the collision of the contour of the ball with the lines, etc.
I have a 6x6 array of numbers:
int[][] multi = new int[][]{
{4, 2, 3, 2, 5, 1},
{2, 5, 5, 4, 1, 1},
{2, 4, 6, 7, 2, 4},
{2, 1, 2, 3, 4, 3},
{3, 5, 1, 4, 5, 2},
{1, 2, 1, 4, 1, 2}
};
If my starting position is multi[2][3]. How can I find the diagonal edges of the array relative to that value? For example, at point multi[2][3] the value is 7. The diagonal should be points multi[0][1], multi[0][5], multi[4][5], and multi[5][0]. Here is what my code currently does:
if (LocationValue == 7) {//find possible moves
//There should be 4 potential moves
ArrayList<Point> Moves = new ArrayList<Point>();
Point DMove;
for (int i = 0; i < multi.length; i++) {
DMove = new Point(x + i, y + i);
Moves.add(new Point(DMove));
}
for (int i = 0; i < multi.length; i++) {
DMove = new Point(x - i, y + i);
Moves.add(new Point(DMove));
}
for (int i = 0; i < multi.length; i++) {
DMove = new Point(x - i, y - i);
Moves.add(new Point(DMove));
}
for (int i = 0; i < multi.length; i++) {
DMove = new Point(x + i, y - i);
Moves.add(new Point(DMove));
}
ArrayList<Point> AlmostFinalMoves = FindPossibleMoves(Moves); //eliminate impossible moves
ArrayList<Point> FinalMoves = FindSideMoves(AlmostFinalMoves, x, y); //Get bishop moves
System.out.println("Possible Moves: " + FinalMoves);
}//End of IF
This method then eliminates the impossible values:
public static ArrayList<Point> FindPossibleMoves(ArrayList<Point> AllMoves) {
ArrayList<Point> FinalMoves = new ArrayList<Point>();
for (int i = 0; i < AllMoves.size(); i++) {
if (AllMoves.get(i).getX() >= 0 && AllMoves.get(i).getX() <= 5 && AllMoves.get(i).getY() >= 0 && AllMoves.get(i).getY() <= 5) {
FinalMoves.add(AllMoves.get(i));
}
}
return FinalMoves;
}
Lastly, this method eliminates all the moves that aren't on the edges of the array.
public static ArrayList<Point> FindSideMoves(ArrayList<Point> AllPossibleMoves, int xloc, int yloc) {
ArrayList<Point> AlmostFinalSideMoves = new ArrayList<Point>();
ArrayList<Point> FinalSideMoves = new ArrayList<Point>();
for (int i = 0; i < AllPossibleMoves.size(); i++) {
if (AllPossibleMoves.get(i).getX() == 0) {
if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 1 || AllPossibleMoves.get(i).getY() == 2 || AllPossibleMoves.get(i).getY() == 3 || AllPossibleMoves.get(i).getY() == 4 || AllPossibleMoves.get(i).getY() == 5) {
AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
}
}
if (AllPossibleMoves.get(i).getX() == 5) {
if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 1 || AllPossibleMoves.get(i).getY() == 2 || AllPossibleMoves.get(i).getY() == 3 || AllPossibleMoves.get(i).getY() == 4 || AllPossibleMoves.get(i).getY() == 5) {
AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
}
}
if (AllPossibleMoves.get(i).getX() == 1) {
if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 5) {
AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
}
}
if (AllPossibleMoves.get(i).getX() == 2) {
if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 5) {
AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
}
}
if (AllPossibleMoves.get(i).getX() == 3) {
if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 5) {
AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
}
}
if (AllPossibleMoves.get(i).getX() == 4) {
if (AllPossibleMoves.get(i).getY() == 0 || AllPossibleMoves.get(i).getY() == 5) {
AlmostFinalSideMoves.add(AllPossibleMoves.get(i));
}
}
}
for (int i = 0; i < AlmostFinalSideMoves.size(); i++) {//Check to see if any possible moves match the original location. If so, do not include in list
if (AlmostFinalSideMoves.get(i).getX() == xloc && AlmostFinalSideMoves.get(i).getY() == yloc) {
//Do Nothing!
} else {
FinalSideMoves.add(AlmostFinalSideMoves.get(i));
}
}
return FinalSideMoves;
}
Running this program results in the following which is not correct.
Possible Moves: [java.awt.Point[x=0,y=3], java.awt.Point[x=0,y=5], java.awt.Point[x=2,y=5], java.awt.Point[x=4,y=5], java.awt.Point[x=5,y=3], java.awt.Point[x=5,y=0], java.awt.Point[x=2,y=0], java.awt.Point[x=0,y=1]]
What is the simplest way to find the diagonals of any random point in a square 2D array? Also, suggestions on how to streamline my code would be greatly appreciated.
Thanks!
A number is on an edge of a square if one of the indices is equal to 0, or the length/height of the array. Assuming the array is already a square (you can do the check yourself):
int length = grid.length;
int height = grid[0].length;
Assuming you have the x and y coordinates of the original point:
List<Point> findPossibleMoves(int x, int y) {
int length = grid.length;
int height = grid[0].length;
int originalX = x;
int originalY = y;
//add (1, 1), (-1, 1), (-1, -1), (1, -1) to the original position until you reach an edge
}
But wait, do we really need a loop? What if we just straight up add a certain value to the x and y points to reach the edge in 1 step? How do we do that?
Take (2, 3) for example (value = 7 in your array). To find the (0, 0) corner, we use this logic:
x = 2 is closer to 0 than y is closer to 0 so we get (x - x, y - x) = (0, 1)
this applies if y is closer to 0 than x: (x - y, y - y) = (x - y, 0)
Take this and apply to say, the (length, height) corner:
(y = 3) is closer to (height = 5) than (x = 2) to (length = 5) so we get (x + (height - y), (y + (height - y)) = (4, 5)
All 4 corners translated to code would be:
List<Point> findPossibleMoves(int x, int y) {
List<Point> pointList = new ArrayList<Point>();
int length = grid.length;
int height = grid[0].length;
pointList.add(new Point(x - Math.min(x, y), y - Math.min(x, y)));
pointList.add(new Point(x + Math.min(length - x, y), y - Math.min(length - x, y)));
pointList.add(new Point(x - Math.min(x, height - y), y + Math.min(x, height - y)));
pointList.add(new Point(x + Math.min(length - x, height - y), y + Math.min(length - x, height - y)));
return pointList;
}
Which can be cleaned up to:
List<Point> findPossibleMoves(int x, int y) {
List<Point> pointList = new ArrayList<Point>();
int length = grid.length;
int height = grid[0].length;
int to00 = Math.min(x, y);
int toL0 = Math.min(length - x, y);
int to0H = Math.min(x, height - y);
int toLH = Math.min(length - x, height - y);
pointList.add(new Point(x - to00, y - to00));
pointList.add(new Point(x + toL0, y - toL0));
pointList.add(new Point(x - to0H, y + to0H));
pointList.add(new Point(x + toLH, y + toLH));
return pointList;
}
I'd do it much more directly. As long as we're supposing that multi is regular, not ragged, we don't even need to know beforehand what its dimensions are. It doesn't even need to be square.
For example, this approach is a much more succinct version of yours:
if (LocationValue == 7) {
int maxRow = multi.length - 1;
int maxColumn = multi[0].length - 1;
int[][] directions = { { 1, 1 }, { 1, -1 }, { -1, 1}, { -1, -1 } };
ArrayList<Point> finalMoves = new ArrayList<>();
for (int[] direction : directions) {
int x1 = x;
int y1 = y;
// Proceed in the current direction until we reach an edge
while (true) {
int x2 = x1 + direction[0];
int y2 = y1 + direction[1];
if ((x2 < 0) || (x2 > numColumns)
|| (y2 < 0) || (y2 > numRows)) {
// Moving in farther would take the piece off the board
break;
} else {
x1 = x2;
y1 = y2;
}
}
finalMoves.add(new Point(x1, y1));
}
// ...
}
Note in particular that we can know which points are on an edge very easily (as shown). You can wrap the given condition in a method if you prefer, but there's not much to it. Either way, there's no special need to create Points that we know are not on an edge, or to engage in two rounds of filtering, or any of that stuff.
Note also that I have DRYed out your code by introducing the directions array. The operations you perform to handle each direction are the same, but for the increments (+1 or -1) for the two axes. The elements of direction capture those differences, removing the need for repetitious code.
Finally, do note that if the initial position is on an edge then two of the computed "moves" will leave the piece at its initial position, and if the initial position is in a corner then three of the moves will leave it in the same place. You can eliminate those, if you wish, by testing x1 and / or y1 before adding a move to finalMoves. Of course, if you do that then the result will sometimes contain fewer than four moves.
I am trying to zoom an image twice using bilinear interpolation, but it's not working.It is giving errors like division by 0 , out of range value(the output color has exceeded 255). Here is my code :
int red1,green1,blue1;
int red2,green2,blue2;
int red3,green3,blue3;
int red4,green4,blue4;
int redf,greenf,bluef;
int x1,y1,x2,y2,x,y;
int a,b,c,d;
int var[][]=new int[4][4];
int inv[][]=new int[4][4];
//int cons[][]=new int[1][4];
//int col[][]=new int[1][4];
for(int i=0;i<height*2;i++)
{
//l=0;
for(int j=0;j<width*2;j++)
{
Color color=new Color(img.getRGB((int)(j/2),(int)(i/2)));
red=color.getRed();
green=color.getGreen();
blue=color.getBlue();
x=(int)(j/2);
y=(int)(i/2);
x1=(int)(j/2)+1;
y1=(int)(i/2)+1;
x2=(int)(j/2)-1;
y2=(int)(i/2)-1;
if(x1<0 || x1>=width || y1<0 || y1>=height)
{
//System.out.println("Yes");
red1=0;
green1=0;
blue1=0;
}
else
{
Color c1=new Color(img.getRGB(x1,y1));
red1=c1.getRed();
green1=c1.getGreen();
blue1=c1.getBlue();
}
if(x2<0 || x2>=width || y2<0 || y2>=height)
{
//System.out.println("Yes2");
red2=0;
green2=0;
blue2=0;
}
else
{
Color c2=new Color(img.getRGB(x2,y2));
red2=c2.getRed();
green2=c2.getGreen();
blue2=c2.getBlue();
}
if(x1<0 || x1>=width || y2<0 || y2>=height)
{
red3=0;
green3=0;
blue3=0;
}
else
{
Color c3=new Color(img.getRGB(x1,y2));
red3=c3.getRed();
green3=c3.getGreen();
blue3=c3.getBlue();
}
if(x2<0 || x2>=width || y1<0 || y1>=height)
{
red4=0;
green4=0;
blue4=0;
}
else
{
Color c4=new Color(img.getRGB(x2,y1));
red4=c4.getRed();
green4=c4.getGreen();
blue4=c4.getBlue();
}
if(x1<=0 || x1>width)
x1=0;
if(x2<=0 || x2>width)
x2=0;
if(y1<=0 || y1>height)
y1=0;
if(y2<=0 || y2>height)
y2=0;
var[0][0]=x1;
var[0][1]=y1;
var[0][2]=x1*y1;
var[0][3]=1;
var[1][0]=x2;
var[1][1]=y2;
var[1][2]=x2*y2;
var[1][3]=1;
var[2][0]=x1;
var[2][1]=y2;
var[2][2]=x1*y2;
var[2][3]=1;
var[3][0]=x2;
var[3][1]=y1;
var[3][2]=x2*y1;
var[3][3]=1;
inv=invert(var);
a=inv[0][0]*red1+inv[0][1]*red2+inv[0][2]*red3+inv[0][3]*red4;
b=inv[1][0]*red1+inv[1][1]*red2+inv[1][2]*red3+inv[1][3]*red4;
c=inv[2][0]*red1+inv[2][1]*red2+inv[2][2]*red3+inv[2][3]*red4;
d=inv[3][0]*red1+inv[3][1]*red2+inv[3][2]*red3+inv[3][3]*red4;
redf=a*x+b*y+c*x*y+d;
a=inv[0][0]*green1+inv[0][1]*green2+inv[0][2]*green3+inv[0][3]*green4;
b=inv[1][0]*green1+inv[1][1]*green2+inv[1][2]*green3+inv[1][3]*green4;
c=inv[2][0]*green1+inv[2][1]*green2+inv[2][2]*green3+inv[2][3]*green4;
d=inv[3][0]*green1+inv[3][1]*green2+inv[3][2]*green3+inv[3][3]*green4;
greenf=a*x+b*y+c*x*y+d;
a=inv[0][0]*blue1+inv[0][1]*blue2+inv[0][2]*blue3+inv[0][3]*blue4;
b=inv[1][0]*blue1+inv[1][1]*blue2+inv[1][2]*blue3+inv[1][3]*blue4;
c=inv[2][0]*blue1+inv[2][1]*blue2+inv[2][2]*blue3+inv[2][3]*blue4;
d=inv[3][0]*blue1+inv[3][1]*blue2+inv[3][2]*blue3+inv[3][3]*blue4;
bluef=a*x+b*y+c*x*y+d;
System.out.println(redf+" "+greenf+" "+bluef);//prints the value
Color nc=new Color(redf,greenf,bluef);
img1.setRGB(j, i, nc.getRGB());
}
}
Kindly help . I am trying to zoom by 2 , and using 4 neighbours(bilinear approach)
Sorry for being a bit late but for Bilinear Interpolation what you need to do is interpolation the results of two different interpolations. Basically it would look something like:
newX = x - 0.5
a1 = newX - (int) (newX)
newY = y - 0.5
a2 = newY - (int) (newY)
Red1 = getRed((int) (x - 0.5), (int) (y - 0.5))
Red2 = getRed((int) (x + 0.5), (int) (y - 0.5))
Red3 = getRed((int) (x - 0.5), (int) (y + 0.5))
Red4 = getRed((int) (x + 0.5), (int) (y + 0.5))
newRed = lerp(lerp(Red1, Red2, a1), lerp(Red3, Red4, a1), a2)
This could, of course be repeated for green and blue.
X and Y in this are source coords, so if you wanted to find the color at (3, 5) of your new image you would run this on (1.5, 2.5) aka your original coords divided by your scaling factor (2).
In case you don't know lerp() is generaly just
lerp(x, y, a)
return x * (1 - a) + y * a;
but if cycles really matter to you or you have a primitive FPU or any number of other special case the less precise
return a + f * (b - a);
can work.
*
Edit:
Since we're in java I've just used
(int)
to signify rounding down but it doesn't actually have to be an int there.
So I have a project for class I am working on in which you have to create a GUI box filled with circles, except the middle 50% of the screen cannot be filled with circles. Also, the red color value of each circle scales linearly from top to bottom of the screen, 0 at the top, 255 at the bottom. Here is what it should look like:
Here's what I have. I tried doing 255/500 (500 is the height) in order to get a scaling factor which I would then use to multiply all my y coordinates by in order to get the specified red value and it worked. The answer to 255 / 500 is 0.51 and when I used 0.51 instead of y * (255 / getHeight()); it worked. I need it to work with any dimensions of the frame, however, so the 0.51 doesn't work. For some reason the y * (255 / getHeight()) does not work, it appears to be returning 0 as the circles are various shades of blue and green. What can i do to fix this?
The code I have:
public class NewJComponent1 extends JComponent {
public void paintComponent(Graphics g) {
int count = 0;
int diameter = 0;
Random rand = new Random();
while (count < 5000) {
int x = rand.nextInt(getWidth() + 1);
int y = rand.nextInt(getHeight() + 1);
int greenValue = rand.nextInt(256);
int blueValue = rand.nextInt(256);
diameter = rand.nextInt(21) + 10;
int redValue = y * (255 / getHeight());
Color random = new Color (redValue, greenValue, blueValue);
if ((x < (getWidth() / 4) && y <= (getHeight() - diameter))
|| ((x > (getWidth() * .75) && (x < getWidth() - diameter)) && y <= (getHeight() - diameter))
|| (x <= (getWidth() - diameter) && y < (getHeight() / 4))
|| (x <= (getWidth() - diameter) && ((y > (getHeight() * .75)) && (y <= getHeight() - diameter)))){
g.setColor(random);
g.fillOval(x, y, diameter, diameter);
count++;
}
}
System.out.println(getHeight());
System.out.println(getWidth());
}
}
I tried various iterations of the redValue code, swapping order, making a double and typecasting to int, and various other things but I couldn't get it to work. I'm sure its a small mistake that is messing everything up, but anyways thank you for the help regardless. I am using Android Studio, not sure if that really would impact anything.
Replace this line
int redValue = y * (255 / getHeight());
with
int redValue = (int) Math.round(y * (255.0 / (double) getHeight()));
Just changing redValue to an double wouldn't change the fact that 255/getHeight() is integer division.
I'm building a game and I have a system for loading images into the game, but returning them to the screen as blocks.
The two main colors I use in the map as of now are: 0x000000 (Black) and 0x9EEDFF (Light Blue). I have this system in which I return a certain block to the screen with a certain color.
if (blocks[x + (y * width] == 0x000000) return VoidBlock.block;
if (blocks[x + (y * width] == 0x9EEDFF) return IceBlock.block;
When I first ran it, it didn't work. All I got was an empty abyss. :/
But, what I did was I managed to output the colors of the blocks and I got these very strange numbers: -6361601 for black and -16777216 for light blue. I attempted to decode them via online with decimal to hexadecimal converters, but nothing seemed to give me my color. It gave me like, 134861234 or something, and it didn't really help a lot.
So, my question is, how does Java get that number and how I can ensure that my above code will match it? Right now, the only code that's running my program is:
if (blocks[x + (y * width] == -6361601) return VoidBlock.block;
if (blocks[x + (y * width] == -16777216) return IceBlock.block;
Thanks in advance.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public void loadLevel(String pathway) {
try {
BufferedImage image = ImageIO.read(Level.class.getResource(pathway));
int image_width = image.getWidth();
int image_height = image.getHeight();
pixels = new int[image_width * image_height];
image.getRGB(0, 0, width, height, pixels, 0, width);
} catch (IOException exc) {
exc.printStackTrace();
}
}
That was my loadImage() method for taking the image and converting it to that. Now, here's my generateLevel() method:
public void generateLevel() {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
blocks[x + (y * width)] = pixels[x + (y * width)];
System.out.println(blocks[x + (y * width)]);
}
}
}
It all comes together in this method:
public Block getBlock(int xPos, int yPos) {
if (xPos < 0 || xPos >= width || yPos < 0 || yPos >= height) return EmptyBlock.block;
if (blocks[xPos + (yPos * width)] == -6361601) return StoneBrickBlock.block;
//if (blocks[xPos + (yPos * width)] == 0x9EEDFF) return StoneBlock.block;
//if (blocks[xPos + (yPos * width)] == 2) return LavaBlock.block;
if (blocks[xPos + (yPos * width)] == -16777216) return IceStoneBrickBlock.block;
return EmptyBlock.block;
}
OK, -16777216 corresponds to alpha = 255, red = 0, green = 0, blue = 0. You almost certainly don't care about the alpha, so you should ignore it when you do your comparison.
So you could write
if (blocks[x + (y * width)] & 0xFFFFFF == 0x000000)
which checks whether the value is "black plus some alpha".
Likewise, -6361601 corresponds to alpha = 255, plus your "light blue" (9EEDFF). So the same trick will work there too.
if (blocks[x + (y * width)] & 0xFFFFFF == 0x9EEDFF)
It seems your only issue was your need to ignore the alpha value.