I am trying to make a game where the player can only see in a small radius around them. i'm attempting to do this by covering a 500X500 display with 1X1 black pixels that i can set active or inactive. The problem is that using a standered for loop to add them takes a large amount of time when the program launches and it slows the entire thing down. Any Solutions?
the pix object takes two paramaters(int x, int y)
code
public ArrayList<Pix> pixs= new ArrayList<>();
for(int i = 0; i<=500; i++)
{
for(int ii = 0; ii<=500; ii++)
{
pixs.add(new Pix(ii,i));
}
}
You are constructing 250000 instances of your Pix class. That will take some time.
Consider having a 2 dimensional array of booleans instead. Where false means the pixel is black.
You don't need to initialize the values yourself as they will default to false.
boolean[][] pixs = new boolean[500][500];
You can iterate over the structure with this:
for (int x = 0; x < 500; x++) {
for (int y = 0; y < 500; y++) {
System.out.println(pixs[x][y]);
}
}
And you can set a particular pix with
int x = 232;
int y = 455;
pixs[x][y] = true;
Related
I have a school project, I have to build a Tetris Game.
So I began with the creation of my menu with the different level, when I click on one level i go to my second activity (the game area) and I have also created my custom block.
My problem is a visual issue, indeed I don't know what type of layout I have to use for my surface game (gridlayout, linearlayout, grid etc. ...).
And then how to affect my blocks custom in this surface game, in this layout?
See the result expected.
enter image description here
I'm not sure I understand what you want entirely but ill give it a shot from what i think you mean.
You should use a nested for loop to do it, if your array was int[10,20](not right syntax but i cant be bothered to count the actual size of your array).
you should go:
(pseudocode)
also assume your resolution is 100, 200
For(int i = 1 To 10){
For(int k = 1 To 20){
DrawSquare(i*10, k*10, "block type")
k = k + 1
}
i = i + 1
}
Then it will fill your 100, 200 area with the block type specified. Now if you want to load what block type you want freom the array you can just call the array in the block type.
DrawSquare(i*10, k*10, Array[i,k])
Obviously bear in mind that its all pseudocode to display the logic.
Hope this helps
Building on Valhalla's answer with a Java-specific example, it's still a bit unclear what you're asking, but assuming you want to initialise the grid to begin with you can use this code:
private final int columns = 10;
private final int rows = columns * 2;
private int[][] grid;
private void initialise() {
grid = new int[columns][rows];
for (int i = 0; i < columns; i++) {
for(int j = 0; j < rows; j++) {
grid[i][j] = 0;
}
}
}
And assuming that you have a block that starts at the top, and falls one square with each iteration provided there's nothing underneath, you can try this:
private void blockFall() {
// Start from 1 row above the bottom and parse upwards
// so a block won't drop right to the bottom on a single iteration
for (int i = 0; i < columns; i++) {
for(int j = rows - 2; j >= 0; j--) {
if (grid[i][j] > 0 && grid[i][j+1] == 0) {
grid[i][j+1] = grid[i][j];
grid[i][j] = 0;
}
}
}
}
I am trying to finish my code for an assignment I have, but I'm stuck on the last component. I need to create "stars" (small yellow square objects) in the "sky"... a grid of 5 rows of 10 stars. I am in a beginner java class, and I am supposed to being using methods such as star.moveHorizontal() or star.moveVertical(). All of the relevant posts I've searched for have been too complex or out of my comprehension.
I think that I would need to create an array? We haven't even covered that in class... And then have each "star" be x distance (the first star) + 30 units to the right. Then t continue that trend until there are 10 stars in a row. And then get four more rows of 10 stars.
Here is the code I've create for just one star (in the upper left of my window):
Square s1 = new Square();
s1.makeVisible();
s1.changeColor("yellow");
s1.changeSize(5);
s1.moveVertical(-100);
s1.moveHorizontal(-270);
Then I tried to create an array for a square class... I honestly have no idea if that's even legal.
Square[] starArray = new Square[10];
for ( int i=0; i<starArray.length; i++) {
starArray[i] = new Square();
But then I don't understand how I can call each star and make them appear... Please help. I feel so out of my depth. I've tried to research this and try new things for over 2.5 hours now. I will answer any questions you have to the best of my ability. Thank you
If you can make a single star appear and haven't learned about arrays yet, I don't think that is the answer your teacher is looking for. The point of an array is to be a container so you can reference the objects again. If you don't need to go back to the stars in the future, just create them and set their values in a loop.
// Set defaults for spacing and start positions
int horizontalStartPosition = 10;
int horizontalSpacing = 30;
int verticalStartPosition = 10;
int verticalSpacing = 30;
// Outer loop creates the 4 rows
for (int i = 0; i < 4; i++) {
// Inner loop creates each row
for (int j = 0; j < 10; j++) {
// Create the next star in the row
Square s = new Square();
s.makeVisible();
s.changeColor("yellow");
s.changeSize(5);
// Move the star to the correct vertical position for the current row
s.moveVertical(verticalStartPosition + i * verticalSpacing);
// Move the star to the correct horizontal spacing for the next star
s.moveHorizontal(horizontalStartPosition + j * horizontalSpacing);
}
}
You're on the right track. You can use a 2D array with 5 rows and 10 columns. Try something like this:
int numColumns = 10; //the number of columns in the array
int numRows = 5; // the number of rows in the array
Square[][] starArray = new Square[numRows][numColumns]; // the array itself
final int DIST_X = 10; //the distance between columns (use final because this value should not change)
final int DIST_Y = 10; // the distance between rows (use final because this value should not change)
int y = 0; // the initial row's vertical displacement
for ( int i=0; i<numRows; i++) {
int x = 0; // the initial columns horizontal displacement
for ( int j=0; j<numColumns; j++) {
starArray[i][j] = new Square(); //define the square
starArray[i][j].moveHorizontal(x); // move it x units horizontally
starArray[i][j].moveVertical(y); // move it y units vertically
starArray[i][j].makeVisible(); //show the square
x += DIST_X; //update your horizontal displacement so the next column shows up in the correct position
}
y += DIST_Y; //update your vertical displacement so the next row shows up in the correct position
}
Based on what I understand, you would want to call a method which would basically place a star in the grid for you.
I am not fully sure of what you mean, but here is what I can offer you:
You'll want to create a method for placing a star.
private static int X_SPACING = 30;
private static int Y_SPACING = 20;
public Square placeStar(int x, int y){
// This is the same code that you had before.
Square sq = new Square();
sq.changeColor("yellow");
sq.changeSize(5);
sq.moveVertical(-y); // Where Y is the distance from the TOP LEFT.
sq.moveHorizontal(-x);
return sq;
}
public ArrayList<Square> makeRow(int columnsAmount, int y, int startX){
ArrayList<Square> squares = new ArrayList<>();
for(int i = 0; i < columnsAmount; i++)
squares.add(placeStar(startX + (X_SPACING * i), y));
return squares;
}
public ArrayList<Square> makeGrid(int rowsAmount, int columnsAmount){
ArrayList<Square> rslt = new ArrayList<>();
for(int i = 0; i < rowsAmount; i++)
rslt.addAll(makeRow(columnsAmount, (i * Y_SPACING), 0);
return rslt;
}
Basically, calling "makeRow" should create a row of [rowsAmount] stars, which are all separated by [X_SPACING] pixels.
Then, makeGrid will call makeRow multiple times adjusting [y], and this will make you a grid. Feel free to adjust any value in the code.
EDIT: I've added a makeGrid function, and changed a few variables in the makeRow as I mistyped them. I made the functions return an ArrayList, but you shouldn't need them, only if your teachers later ask to modify them later, or something.
I hope this helps, don't hesitate to ask more questions.
Sneling.
public void fillWith(TileEntity tile){
for(int i = 0; i < this.height; i++){//for every x and y value
for(int j = 0; j < this.width; j++){
tile.x = j;
tile.y = i;
this.tiles.add(tile);
}
}
}
Okay so the above code is supposed to fill the level with a TileEntity tile. When I print out the x and y coords before the line "this.tiles.add(tile)", each tile has different coords. But when I print out the x and y coords of all of the tiles in the ArrayList "tiles", every single one is (9,9). They are all identical to the very last tile added to the arraylist. Thanks!
You keep adding the same object in your for-loop.
If you want to add different objects, you will need to create new instances using for example new TileEntity().
public void fillWith(){
TileEntity tile;
for(int i = 0; i < this.height; i++){//for every x and y value
for(int j = 0; j < this.width; j++){
tile = new TileEntity();
tile.x = j;
tile.y = i;
this.tiles.add(tile);
}
}
}
You are right that, in your code example, the values change every time you are in the loop, but because tile points to the same object every iteration, you will only change the x and y values within that object. (Java will not create a new object for you when you change x and/or y). When you add tile to the array this.tiles, it will reference the object you add - it will not make a copy of it.
All in all, tile and every object in your array will point to the same single instance of TileEntity.
You've succeeded in adding the same tile to the ArrayList 100 times. There's still only one object here, so the last update "wins": x = 9 and y = 9.
If you want different values, then you must add 100 different tile objects, each with their own distinct values.
You need to create new tile object each time in the loop,otherwise each time the existed tile pbject changes and remains with the last inserted values.
for(int j = 0; j < this.width; j++){
tile= new TileEntity();
tile.x = j;
tile.y = i;
this.tiles.add(tile);
}
I'm working on a project in which I'm trying to use histogram equalization to do something like going from this image
http://zerocool.is-a-geek.net/wp-content/uploads/2011/12/input-300x200.jpg
"http://zerocool.is-a-geek.net/wp-content/uploads/2011/12/hist_before.png"
to this image
http://zerocool.is-a-geek.net/wp-content/uploads/2011/12/output-300x200.jpg
"http://zerocool.is-a-geek.net/wp-content/uploads/2011/12/hist_after.png"
but I can't seem to figure it out.
This is my enhanced image code which should implement the same type of adjustment..
public void EnhancedImage (File fileName) {
double sumc = 0;
for(int r = 0; r < array.length; r++){
for(int c = 0; c < array[r].length; c++){
sumc = r+c;
if (sumc <= array[r][c]) {
sumc = array[r][c];
}
newc = Math.round(maxshade * ((double)sumc / pixtot));
array[r][c] = (int) (newc);
if (array[r][c] > 255) {
array[r][c] = 255;
}
}
}
The algorithm that i would like to use is below where maxShade is the maximum shade of the image (usually 255) sumc is the total number of pixels in the image with a value less than or equal to c and pixtot is the total number of pixels in the picture:
newc := round(maxShade * ((double)sumc / pixtot))
but im not sure if i did it right...currently my image just turns really dark.
Any help would be appreciated!! Thanks.
Also my pixtot routine:
pixtot = 0;
for(int y = 0; y < imageArray.length; y++)
for(int x = 0; x < imageArray[0].length; x++)
pixtot = x+y;
Your problem is here:
pixtot = x+y;
First, you want +=, not =. Second, this is adding up the indexes of the pixels, not the value of the pixels. You want something like
pixtot += imageArray[y][x];
You make the same conceptual error with sumc.
Edit:
There's lots of other problems with your code. If you want to stretch the dynamic range, you want to compute min and max, the minimum and maximum of all the pixel values, then compute each pixel value as value = maxshade * (value - min) / (max - min). That gives you a result pixel value of 0 if value==min and maxshade if value==max.
This doesn't really give you histogram equalization, however. For that you need to compute a histogram of the input pixel values and compute quantiles in that histogram to figure out the output values, it isn't easy.
I have the following method
public void multiArrayGrid(){
GRect[][] rect = new GRect[3][3];
int rWidth = 50;
int rHeight = 50;
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
rect[i][i] = new GRect(50,50);
add(rect[i][i], rWidth+50, rHeight+50);
rWidth+=50;
}
rHeight+=50;
rWidth = 50;
}
}
The above method is actually making a 3x3 grid of rect.
How do I access, for example, rect[0][0]?
The code indeed creates a 3x3 grid, but it fills only the main diagonal (0,0), (1,1), (2,2).
To access rect[0][0] you simply write exactly this expression, and you will get a GRect object or a null pointer. To modify a cell you write the same expression, this time on the left side of an assignment operator.
You did try this yourself, didn't you?