I am trying to make a memory game with Java. The game is basically going to be some squares in a grid that is 4x4 at the moment just for testing purposes. I have created my Square class, and programmed what i want them to do in that class, and then created a square object in another Class that handles the "Normal Mode" of the game. Now since i have a 4x4 grid of squares I need to make 16 different Squares (Or at least that's what i'm thinking at the moment). I also need to draw the Squares in their corresponding place.
My Question: What is the most efficient way of creating 16 of these Square objects while still being able to manipulate them individually? (Sort of like each having their own name; Square, Square1, Square2, etc).
I am also using the Slick2D library.
As mentioned above, Square[][] squareGrid = new Square[4][4] is a good way to go about this;
then you can initialize all 16 of them using:
for (int i = 0; i < squareGrid.length; i++)
for(int j = 0; j < squareGrid[i].length; j++)
squareGrid[i][j] = new Square();
now each square automatically has its own unique (row, col) id.
for example,
squareGrid[1][2].callSomeFunctionInSquareClass();
can be used to manipulate the square at 2nd row, 3rd column.
This way you will avoid scanning through all the squares to get the one at a particular cell on the grid, thus making it much more efficient.
happy coding :)
You can try Square[][] grid = new Square[4][4]
I would use a Square[][] array, e.g. Square[][] squares = new Square[4][4], and then initialise it with all 16 Squares in two nested loops:
for (int x = 0; x < squares.length) x++)
for (int y = 0; y < squares[x].length; y++)
squares[x][y] = new Square(x, y);
Related
Is there any way in Java (Eclipse) to move a player object that is defined as an object on a matrix tile ?
So, the start position of the player object is (0,0). The playboard is a 12x12 matrix. The existing code that I have written works fine to create the player object (as mentioned, as an object on a matrix tile whereby the matrix is defined as [row,col] ).
I am looking to a method to start moving the player based on certain conditions. e.g. a button (I know how to create). So, the question is really how to start moving the player defined as an object on a matrix tile (PlayerPion in the code below).
Thanks in advance for your responses ;).
GamePanel() {
setLimits(BorderFactory.createLineBorder(Color.BLACK, GAP));
GridLayout layout = new GridLayout(GamePanel.getBoardRows(),
GamePanel.getBoardCols());
setLayout(layout);
for (int i = 0; i <PlayBoard.getBoardRows(); i++) {
for (int j = 0; j < PlayBoard.getBoardCols(); j++) {
int[][] matrixBoard = Board.getBoard();
int boardValue = matrixBoard[i][j];
switch(boardValue) {
case AA: add(new Tile(Color.WHITE));
add(new PlayerPion());
break;
(Code that is not relevant is not shown)
A sample of the playBoard (output from existing code):
enter image description here
Good evening everyone.
I've been messing a bit with isometric tile worlds and I have a few doubts about rendering the elements on it.
When I build a single height map I render it first and then add the diferent elements on top, and the displacement of the last seem right.
public void render(Graphics2D g2d) {
for(int i = 0; i < tileGrid.length; i++) {
Point isop = NeoMath.getInstance().cartToIso(i % yAmmount, i / yAmmount, GlobalDataStorage.tileWidth, GlobalDataStorage.tileHeight);
TileManager.getInstance().getTileByID(tileGrid[i]).render(g2d, isop.x, isop.y);
}
for(Entity entity : entityList) {
entity.render(g2d);
}
}
(The position of the entity is calculated inside it's update).
With this I have no problems as everything is rendered on the same height, the problem comes when I try to add other floors to it.
Let's say that I want it to have three heights. I have a list of list of tiles instead of the single array, and render every element on them:
public void render(Graphics2D g2d) {
int flag = 0;
for(int i = 0; i < tileGrid.size(); i++) {
Point isop = NeoMath.getInstance().cartToIso(i % yAmmount, i / yAmmount, GlobalDataStorage.tileWidth, GlobalDataStorage.tileHeight);
for(int k = 0; k < tileGrid.get(i).size(); k++) {
TileManager.getInstance().getTileByID(tileGrid.get(i).get(k)).render(g2d, isop.x, isop.y - (GlobalDataStorage.tileZ * k));
}
while(flag < currentList.size() &&
currentList.get(flag).getPosition().equals(new Point(i % yAmmount, i /
yAmmount))) {
currentList.get(flag).render(g2d);
flag++;
}
}
}
Where the currentList is the list of entities.
With this I have the problem that, when the entities move to a new position, they get overlaped by the tiles, as these are rendered after the entity, and the position of the entity does not change until it reached the destiny. I could change the position to the new one before rendering, but that implies that in the other axis the previous tile get rendered after the entity, making it disapear for a second due to the overlap.
This also mess when I try to draw selection rectangle as it get stuck behind the tiles being rendered. I don't want them to overlap the whole map so can't draw them after all the rendering has been done either.
Does someone know of another approach that I can try out?
Thank you beforehand.
Draw your entire floor layer in a first pass. Then in the second pass draw all walls and objects and moving entities.
I could change the position to the new one before rendering,
David Brevik, programmer on Diablo, mentions using this option in his GDC talk Diablo: A Classic Games Postmortem. It was his first "What Went Wrong" example!
Reference: https://www.youtube.com/watch?v=VscdPA6sUkc&t=20m17s
Turns out this is a classic hurdle in isometric games.
I am using slick for java since a few days and got a serious problem.
If i run a completely empty apllication (it just shows the fps) with a solution of 800x600 i get a fps count between 700 and 800.
If I now draw an array with 13300 entries as a grid of green and white rectangles, the fps drop to something around 70.
With more entries in the array it becomes really slow.
For example in a solution of 1024x768 and an array with 21760 entries the fps drop to 40.
How i draw a single entry:
public void draw(Graphics graphics){
graphics.setColor(new Color(getColor().getRed(), getColor().getGreen(), getColor().getBlue(), getColor().getAlpha()));
graphics.fillRect(getPosition().x, getPosition().y, getSize().x, getSize().y);
Color_ARGB white = new Color_ARGB(Color_ARGB.ColorNames.WHITE);
graphics.setColor(new Color(white.getRed(), white.getGreen(), white.getBlue(), white.getAlpha()));
}
And this is how I draw the complete array:
public void draw(Graphics graphics) {
for (int ix = 0; ix < getWidth(); ix++) {
for (int iy = 0; iy < getHeight(); iy++) {
getGameGridAt(ix, iy).draw(graphics);
}
}
}
In my opinion 21760 is not that much.
Is there anything wrong with my code or is slick just too slow to draw so much rectangles?
You only want to draw rectangles that are on the screen. If your screen bounds go from 0 to 1024 in the x direction and from 0 to 768 in the y direction, then you only want to loop through rectangles that are inside those bounds and then only draw those rectangles. I can't imagine you are trying to draw 21760 rectangles inside those bounds.
If you are, then try creating one static rectangle and then just try drawing that ONE in all of the different positions you need to draw it at rather than creating a new one every time. For example, in a game I am making, I might have 1000 tiles that are "grass" tiles, but all 1000 of those share the same static texture. So I only need to reference one image rather than each tile creating its own.
Each rectangle can still have a unique state. Just make your own rectangle class and have a static final Image that holds a 5*5 image. Each rectangle will use this image when it needs to be drawn. You can still have unique properties for each rectangle. For example, private Vector2f position, private boolean isAlive, etc
You're probably not going to be able to draw individual rectangles any faster than that.
Games that render millions of polygons per second do so using vertex buffer objects (VBO). For that, you'll probably need to code against the OpenGL API (LWJGL) itself, not a wrapper.
Not sure if Slick will allow it, but if this thing looks anything like a chessboard grid... you could draw just 4 rectangles, grab them and use the resulting image as a texture for your whole image. I'm not even a java programmer just trying to come up with a solution.
Since you're only repeatedly using just a few colors creating a new Color object for every single one is bound to be slow... use new only once for each different color used and store the re-usable colors somewhere in your class, than call the functions with those, constantly allocating and freeing memory is very slow.
And while this might not be as much a benefit as not using new each time but have you considered caching the results of all those function calls and rewriting code as
public void draw(Graphics graphics) {
int ixmax = getWidth();
int iymax = getHeight();
for (int ix = 0; ix < ixmax; ix++) {
for (int iy = 0; iy < iymax; iy++) {
getGameGridAt(ix, iy).draw(graphics);
}
}
}
Or if you'd prefer not to declare new variables
public void draw(Graphics graphics) {
for (int ix = getWidth() - 1; ix >= 0; ix--) {
for (int iy = getHeight() - 1; iy >= 0; iy--) {
getGameGridAt(ix, iy).draw(graphics);
}
}
}
Just noticed in another answer you have an integral size grid (5x5) ... in this case the fastest way to go about this would seem to be to draw each item a single pixel (you can do this directly in memory using a 2-dimensional array) and scale it to 500% or use it as a texture and draw a single rectangle with it the final size you desire ... should be quite fast. Sorry for all the confusion caused by previous answers, you should have said what you're doing more clearly from the start.
If scaling and textures are not available you can still draw in memory using something like this (written in c++, please translate it to java yourself)
for( int x = 0; x < grid.width(); x++ ) {
for( int y = 0; y < grid.height(); y++ ) {
image[x*5][y*5] = grid.color[x][y];
image[x*5][y*5 + 1] = grid.color[x][y];
image[x*5][y*5 + 2] = grid.color[x][y];
image[x*5][y*5 + 3] = grid.color[x][y];
image[x*5][y*5 + 4] = grid.color[x][y];
}
memcpy(image[x*5+1], image[x*5], grid.height() * sizeof(image[0][0]) );
memcpy(image[x*5+2], image[x*5], grid.height() * sizeof(image[0][0]) );
memcpy(image[x*5+3], image[x*5], grid.height() * sizeof(image[0][0]) );
memcpy(image[x*5+4], image[x*5], grid.height() * sizeof(image[0][0]) );
}
I'm not sure, but perhaps for graphics the x and y might be represented in the reversed order than used here, so change the code accordingly if it that's the case (you'll figure that out as soon as a few iterations run), also your data is probably structured a bit differently but I think the idea should be clear.
For a project I need to make a map in Java that a robot can navigate through. Preferably, I'd like to store the map in a 2D-array, but I don't know how to go from the 1 bit bitmap to an array in Java. Can you help me out?
You can use the ImageIO.read() method to load your bitmap in a BufferedImage instance. Then, call BufferedImage.getRGB(int x, int y) to get the color value of a particuliar pixel of your map.
Assuming a 10 by 10 grid, then you would create an array such as
Image[][] grid = new Image[10][10];
Then
for (int x = 0; X < grid.length; X++) {
for (int y = 0; y < grid[x].length; y++) {
grid[x][y] = theImageForThisPosition;
}
}
However, as you are storing 1 bit bitmaps, it would be much more efficient to store Color objects, rather than Image objects.
So I have some path generator which now works like this
http://www.openprocessing.org/visuals/?visualID=2615 (There is source; WQRNING - JAVA APPLET)
I want to create some 3D object using paths I generated so it locked in one of perspectives similar to what I get now in 2D.
So how do I dynamically construct 3D object by adding paths?
BTW: actually I ment algorithm like this http://www.derschmale.com/2009/07/20/slice-based-volume-rendering-using-pixel-bender/
So I want to create from such PATH (I do not want to use images and I do not want to use flash I want to use Java + OpenGl)
such 3d image (But note I want openGL Java and Path's))
I'm not sure I understand what you're after.
The example you supplied draws 2d paths, but merely uses z. scaling would have worked
in a similar way.
So How to dinamicly construct 3d
object by adding path's ?
Do you mean extruding/lathing an object, or replicating the scrunch sketch ?
Drawing a path is easy in processing, you just place vertex objects, in a for loop
between beginShape() and endShape() calls.
Here is the bit of code that does that in the example you've sent:
beginShape();
for (int p=0; p<pcount; p++){
vertex(Ring[p].position().x(),Ring[p].position().y());
}
endShape(CLOSE);
you can also call vertex(x,y,z)
I wanted to extrude a path a while back, here is my question in case it helps.
Basic sketch is uploaded here.
EDIT:
If you have an array of 2 polygons, you can just loop through them, and draw
using something similar to beginShape() and endShape(), GL_POLYGON might be handy.
e.g.
import processing.opengl.*;
import javax.media.opengl.*;
int zSpacing = 10;
PVector[][] slices;
void setup() {
size(600, 500, OPENGL);
slices = new PVector[3][3];
//dummy slice 1
slices[0][0] = new PVector(400, 200,-200);
slices[0][1] = new PVector(300, 400,-200);
slices[0][2] = new PVector(500, 400,-200);
//dummy slice 2
slices[1][0] = new PVector(410, 210,-200);
slices[1][1] = new PVector(310, 410,-200);
slices[1][2] = new PVector(510, 410,-200);
//dummy slice 3
slices[2][0] = new PVector(420, 220,-200);
slices[2][1] = new PVector(320, 420,-200);
slices[2][2] = new PVector(520, 420,-200);
}
void draw() {
background(255);
PGraphicsOpenGL pgl = (PGraphicsOpenGL) g; // g may change
GL gl = pgl.beginGL(); // always use the GL object returned by beginGL
for(int i = 0 ; i < slices.length; i ++){
gl.glColor3f(0, .15 * i, 0);
gl.glBegin(GL.GL_POLYGON);
for(int j = 0; j < slices[i].length; j++){
gl.glVertex3f(slices[i][j].x, slices[i][j].y,slices[i][j].z + (zSpacing * i));
}
gl.glEnd();
}
pgl.endGL();
}
The idea is you loop through each slice, and for each slice your loop through all its points. Obviously slices and the number of 3d vectors inside each slice is up to your data. Speaking of which, where does your data come from ?
If slices is not what your after volTron could come in handy:
volTron http://dm.ncl.ac.uk/joescully/voltronlib/images/s2.jpg
HTH,
George