Call recursion method java - java

I have defined a recursion method (at least I believe it is recursive) that returns void and want to call it in another method, but don't know how. I know it's very basic, but can someone please help? Thanks.
Recursive method:
private static void recursiveWhiteToBlack(BufferedImage image, int width, int height){
image.getRaster().setPixel(width,height, new int [] {0, 0, 0, 0, 0, 0});
int[][] neighbors = neighborsXY(width,height);
for(int i = 0; i<neighbors.length; i++){
int neighborX = neighbors[i][0];
int neighborY = neighbors[i][1];
int[] neighborColor = image.getRaster().getPixel(neighborX, neighborY, new int[] {0, 0, 0, 0, 0, 0});
if(neighborColor[0] == 1){
recursiveWhiteToBlack(image, neighborX, neighborY);
}
}
}
Calling it:
public static BufferedImage countObjects(BufferedImage image, BufferedImage original, ComponentPanel panel){
BufferedImage target = copyImage(image);
for(int width=1; width<image.getRaster().getWidth()-1; width++){ //Determine the dimensions for the width (x)
for(int height=1; height<image.getRaster().getHeight()-1; height++){ //Determine the dimensions for the height (y)
int[] pixel = image.getRaster().getPixel(width, height, new int[] {0, 0, 0, 0, 0, 0});
if(pixel[0] == 1){
none = recursiveWhitetoBlack(image, width, height); //HOW TO CALL IT HERE!!!//
}
System.out.println("countObjects method called");
return target;
}

You call it like this:
if(pixel[0] == 1){
recursiveWhitetoBlack(image, width, height);
}
since the method has no return type, there is no need for variable assignment.

Remove none = since your method returns void (actually means it does not return anything)
So this should look like :
if(pixel[0] == 1){
recursiveWhitetoBlack(image, width, height);
}
also note that none is not defined as a variable/member so it is invalid to use it.

This could be trouble. I'm not sure you have a true stopping condition. You'll know right away when you get an out of memory error.

Related

Java 2D array, possible to set individual size?

Quick question about Java 2D arrays; For my tile-based, top-down, 2D game (using swing) I use
a 2D array to create a map, like this
public int[][] createMap(){
return new int[][]{
{0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}};
}
I then use this in my gameComponents class where I draw the individual tiles unto the map, like this
protected void paintComponent(Graphics g){
super.paintComponent(g);
for (int row = 0; row < game.getMap().getWidth(); row++) {
for (int col = 0; col < game.getMap().getHeight(); col++) {
g.drawImage(tile.getTileImage().get(values()[game.getMap().getMapArray()[col][row]]), row * SIZE,
col * SIZE, this);
}
} }
(where size is the size of a tile)
This works, and it correctly draws each tile to the map as expected, however
this also causes a problem for collision detection. As you may have noted, while I do define the size between the tiles in draw method, it is not defined in the array at all. Which, as you'd imagine, raises issues when checking for collision as the drawn tile is not where the tile is in the 2D array (due to size offset).
This is the code I use for checking collision (of course, not working due to ArrayIndexOutofbounds).
public boolean collisionDetected(int xDirection, int yDirection, Game game, Player player){
for (int row = 0; row < game.getMap().getHeight() * 16; row ++){
for (int col = 0; col < game.getMap().getWidth() * 16; col++) {
System.out.println(col + xDirection + player.getPositionX());
if(game.getMap().getTile(col + xDirection + player.getPositionX() ,
row + yDirection + player.getPositionY()) == Tiles.GRASS ){
System.out.println("COLLISION DETECTED");
return true;
}
}
}
return false;
}
This method uses a method within the map class that returns the tile on that
specific coordinate, like this
public Tiles getTile(int col,int row){
return Tiles.values()[mapArray[col][row]];
}
And, of course, as the 2D array doesn't know of the size offset, it just throws
an arrayindexoutofbound.
My question is, is it possible to define a 2D map array with the size of a tile in-mind? I appreciate any help & input I can get, after-all I am here to learn!
Extra clarification: All the tiles are in an enum class (i.e AIR, GRASS, STONE...). Also worth noting that the player position is not bound by an array, I merely move it the amount of pixels I want it to move.
Thanks in advance!
This method uses a method within the map class that returns the tile on that specific coordinate, like this
public Tiles getTile(int col,int row){
return Tiles.values()[mapArray[col][row]];
}
So if you have a "coordinate", why do you call the parameters col/row?
If you have a 10x10 grid and each tile is 20 pixels then the grid size is 200x200 so you could have x/y values in the range 0-199
So if you have a coordinate of 25x35 you would simply calculate the row/col values as:
int row = 35 / 20;
int column = 25 / 20;
So your method would be something like :
public Tiles getTile(int x, int y)
{
int row = y / 20;
int column = x / 20;
return Tiles.values()[mapArray[row][column]];
}

Poor render performance in LibGDX with hexagonal map

So I am making a simple game using LibGDX which involes a 150*150 hexagonal map, and various types of cell, rocky, clear etc.
Problem is when i load the map, my computer almost completely freezes up and any movement thats supposed to be fluid (character moving, button highlights) take 5+ seconds longer than they should.
Here's the relevant code:
public void render(float deltY){
Gdx.gl.glClearColor(255, 255, 255, 100);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
polygonSpriteBatch.begin();
for (int j = 0; j < 150; j++) {
for (int i = 0; i < 150; i++) {
offset = i%2 == 0 ? multipleX/2 : 0;
if (mc.getMap().getRow(i).getTile(j).getTileType().equals(TileType.Rocky)) {
drawCell(Color.BLACK, j, i);}
if (mc.getMap().getRow(i).getTile(j).getTileType().equals(TileType.Clear)) {
drawCell(Color.LIGHT_GRAY, j, i);}
}
}
polygonSpriteBatch.end();
stage.draw();
}
private void drawCell(Color color, int x, int y) {
polySprite = new PolygonSprite(makePoints(color));
polySprite.setX(mc.getMap().getRow(y).getTile(x).getTilePosition().get_x() * multipleX + offset);
polySprite.setY(mc.getMap().getRow(y).getTile(x).getTilePosition().get_y() * multipleY);
polySprite.draw(polygonSpriteBatch);
}
public PolygonRegion makePoints(Color color){
side = 5;
h = CalculateH(side);
r = CalculateR(side);
multipleX = (float)Math.sqrt(3)*side;
multipleY = side+(side/2);
float[] points = { // vertices
x, y,
x+r, y+h,
x+r, y+side+h,
x,y+side+h+h,
x-r, y+side+h,
x-r, y+h};
return new PolygonRegion(new TextureRegion(getTexture(color)),points
, new short[] { //4 triangles using vertices to make hexagon
0, 1, 5,
1, 4, 2,
5, 1, 4,
2, 3, 4});
}
public Texture getTexture(Color color){
Pixmap pix = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
pix.setColor(color);
pix.fill();
textureSolid = new Texture(pix);
return textureSolid;
}
I'm new to coding and LibGDX so there's probably something stupid i'm doing. Is there any way to render the map once and only redraw the polygons if they change?
Thanks
Looking at your code, you are computing a square root for each cell, for each rendering pass.
So your code currently involves more than 22500 square root operations for each frame you render and is creating as many objects, that's quite a lot !
You should compute the points for your hexagons only once.

Faster way to redraw a bitmap in android?

I'm processing an image for OCR, and I need to change the color of a bunch of pixels in a bitmap. Is there a faster method than setPixel and getPixel? Currently I'm just doing a for loop with a method that checks the input vs a bunch of RGB values and returns true if there's a match. Thank you very much!
Bitmap img = myImage.copy(Bitmap.Config.ARGB_8888, true);;
for (int w = 0; w < img.getWidth(); w++) {
for (int h = 0; h < img.getHeight(); h++) {
int value = img.getPixel(w, h);
if (filter(value)) {
img.setPixel(w, h, Color.rgb(0, 0, 0));
} else img.setPixel(w, h, Color.rgb(255, 255, 255));
}
}
Just wanted to follow up and post code for if anyone finds this via search.
My code in the question was taking 3.4s on average, the code below using Gabe's advice is taking under 200ms. I also added a length variable because I read not calling array.length() every iteration could improve performance, but in testing there doesn't seem to be much of a benefit
int width = img.getWidth();
int height = img.getHeight();
int length = width * height;
int[] pixels = new int[width*height];
img.getPixels(pixels, 0, width, 0, 0, width, height);
for (int i = 0; i < length; i++) {
if (filter(pixels[i])) {
pixels[i] = Color.rgb(0, 0, 0);
} else pixels[i] = Color.rgb(255, 255, 255);
}
img.setPixels(pixels, 0, width, 0, 0, width, height);
You could always try to break up your image into quadrants/ a grid and assign each quadrant a separate thread.
I normally handle images with OpenCV on Jni. It is much faster than handling on Java. If you are not familliar with JNI, please reference this link. What is JNI Graphics or how to use it?
You can also divide image and then process with multi-threading!

Are there similar android methods of java getData().getPixels()?

I'm trying to use the following code of java to read image data on android. Since ImageIO is not supported, what are some ways I may use getData().getPixels()?
By changing BufferedImage into Bitmap, I can get all other codes working besides bi.getData().getPixels()?
Any method in the android library I may use to replace it?
In android Bitmap class:
public void getPixels (int[] pixels, int offset, int stride, int x, int y, int width, int height)
This method supports int[], but not double[]. I'm not familiar with image processing will they be different?
Thank you.
private double[] getImageData(String imageFileName) throws FaceRecError {
BufferedImage bi = null;
double[] inputFace = null;
try{
bi = ImageIO.read(new File(imageFileName));
}catch(IOException ioe){
throw new FaceRecError(ioe.getMessage());
}
if (bi != null){
int imageWidth = bi.getWidth();
int imageHeight = bi.getHeight();
inputFace = new double[imageWidth * imageHeight];
bi.getData().getPixels(0, 0, imageWidth, imageHeight,inputFace);
}
return inputFace;
}
This code is used for getting color of all pixels in Bitmap in android.This return array of color
Bitmap bitmap=BitmapFactory.decodeFile("file path");
int height=bitmap.getHeight();
int width=bitmap.getWidth();
int[] pixel=new int[height*width];
bitmap.getPixels(pixel, 0, width, 0, width, width, height);
So your color will be saved in pixel array. getPixels() have many parameter to customize which pixel color you want
Updated For Casting Integer array to double
public double[] getDoubleNumbers(int[] numbers)
//changed double to double[]
{double[] newNumbers = new double[numbers.length]; //changed 99 to numbers.length
for (int index = 0; index < numbers.length; index++)
newNumbers[index] = (double)numbers[index];
return newNumbers;
}
}

Java: Take the image from Graphics and turn it into a temporary BufferedImage

Hey guys I am making a 2D game and I have generating a random grassy background from 4 preset images. My problem is this, my game draws each image from an array which is created on game start using this code:
public static void createBackground() {
for(int x = 0; x < 640; x+= 32) {
for(int y = 0; y < 496; y+= 32) {
random = new Random();
int grassTex = random.nextInt(grassTextures.size());
grassPos.add(grassTextures.get(grassTex));
}
}
}
That works fine, but this is where the problem occurs. I am re-drawing every image that was put into that array using this:
public static void paintBackground(Graphics g) {
counter = 0;
for(int x = 0; x < 640; x+= 32) {
for(int y = 0; y < 496; y+= 32) {
random = new Random();
int grassTex = random.nextInt(grassTextures.size());
g.drawImage(grassPos.get(counter), x, y, null);
counter++;
}
}
}
This causes a drop in fps (It's not a lot, but it is noticeable). Is there anyway that I can draw all those grass images into one BufferedImage so that it is only one image that is being drawn? Or is there a more efficient way of doing this?
Thanks.
There is no way to take "the image from Graphics", as you ask, but it is not very hard to just create BufferedImage and then draw the image into it, instead. If anything, AWT's imaging model is quite complex, and you'll have to construct a couple of auxiliary data structures and stuff, but here's a template which creates 32-bit RGBA images:
private static final ComponentColorModel colormodel =
new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
new int[] {8, 8, 8, 8}, true, false,
ComponentColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE);
public static BufferedImage makeimage(int w, int h) {
WritableRaster buf = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h, 4, null);
return(new BufferedImage(colormodel, buf, false, null));
}
Once you have a BufferedImage as created by makeimage(), just call getGraphics() on it and paint to your heart's content.

Categories