Recently I've been trying to make a little game for my learning purpose but I got stuck. I was able to generate a map from a .txt file but then it seems to paint it sideways?
this is my map loaded which reads from a text file and add them to an ArrayList.
Width is 20 Height is 10. Same thing applies in my map 20 lines wide 10 down.
public void loadMap(String name) {
try {
this.name = name;
FileInputStream file_stream = new FileInputStream(name);
DataInputStream in = new DataInputStream(file_stream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
map = new Tile[WIDTH][HEIGHT];
String line;
int y = 0;
while ((line = br.readLine()) != null) {
String[] tokens = line.split(" ");
for (int x = 0; x < WIDTH; x++) {
boolean f = false;
if (Integer.parseInt(tokens[x]) == 1)
f = true;
Tile tile = new Tile(y, x, f, Integer.parseInt(tokens[x]));
tiles.add(tile);
map[x][y] = tile;
System.out.println("adding tile (x: " + x + " y: " + y + ") " + f + " " + Integer.parseInt(tokens[x]));
}
y++;
}
in.close();
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "The map: " + name + " was not found.");
e.printStackTrace();
}
}
This is the draw method for the map
public void paint(Graphics2D g) {
for (Tile t : getTiles()) {
t.draw(g);
//g.draw(t.getBounds());
}
}
Here is an example map
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
The way it paints the map is basically a vertical version of this instead of the correct way like it is above. I have tried messing with the numbers within the mapLoaded (width, height) and switching the x and y around but nothing seems to work. Please help
You simply need to change Tile tile = new Tile(y, x, f, Integer.parseInt(tokens[x])); to
Tile tile = new Tile(x, y, f, Integer.parseInt(tokens[x]));.
Everytime you're making a new Tile, you're switching x and y which is causing your problems.
Related
I am trying for hours to print DFS trace (including when you get stuck and you have to backtrack) but my output is always missing a 0 and having double numbers
My input matrix is like this
0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 0
0 1 0 0 1 0 1 0
1 0 1 0 0 1 0 0
0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0
0 0 1 0 0 1 0 0
0 0 0 0 0 1 1 0
My output is like this
0 0 1 0 2 2 4 4 5 2 6 3 7
But it should be like this
0 1 0 2 4 5 4 2 6 2 0 3 7
My algoritem is this one
public void DFSDriver(int[][] adjMatrix)
{
int[] visitMatrix = new int[adjMatrix[0].length];
DftRecursive(adjMatrix, visitMatrix, 0); //Visit all nodes you can
//Visit the ones you cannot because they are separate
for(int i = 0; i < adjMatrix.length; i++) {
if(visitMatrix[i] != 1) {
DftRecursive(adjMatrix, visitMatrix, i); //Visit the ones you cannot because they are separate
}
}
}
public void DftRecursive(int[][] srcMatrix, int[] visitMatrix, int vertex)
{
visitMatrix[vertex] = 1;
System.out.print(vertex + " ");
for (int neighbour = 0; neighbour < srcMatrix[0].length; neighbour++)
{
if (srcMatrix[vertex][neighbour] == 1 && visitMatrix[neighbour] == 0)
{
System.out.print(vertex + " "); //If I don't print this DFS by itself works fine, but I want to print this because I want to backtrack when I get stuck
DftRecursive(srcMatrix, visitMatrix, neighbour);
}
}
}
Hope someone can figure out what I am doing wrong here (the problem is that I also need to print the backtracking, printing only DFS is fine, but backtracking is harder to do)
exchanging the print line and the DftRecursive line.
like this:
if (srcMatrix[vertex][neighbour] == 1 && visitMatrix[neighbour] == 0)
{
DftRecursive(srcMatrix, visitMatrix, neighbour);
System.out.print(vertex + " ");
}
Solving problem of 8 queens i am actually stuck in how to access the diagonals of a particular cell to set it to 1 when placing a queen. There is simple logic for the cells which are in vertical or horizontal of the selected cell where queen has to be placed.
Here is the code of my function to set the cells for the queen to 1 which that queen can attack.
static int[][] SetPos(int csp[][],int row,int col){
int count = 0, n = csp.length;
for (int i = 0; i < csp.length; i++) {
for (int j = 0; j < csp.length; j++) {
if(i==row || j==col){
csp[i][j]=1;
}
if(row==col && i==j){
//csp[row][col]=1;
csp[i][j]=1;
}
if(row+count==i && col+count==j){
csp[i][j]=1;
}
}
count++;
}
return csp;
}
How can this condition be improved:
if(row+count==i && col+count==j){
csp[i][j]=1;
}
So that i get result for cell(5,5) as :
1 0 0 0 0 1 0 0
0 1 0 0 0 1 0 0
0 0 1 0 0 1 0 0
0 0 0 1 0 1 0 1
0 0 0 0 1 1 1 0
1 1 1 1 1 1 1 1
0 0 0 0 1 1 1 0
0 0 0 1 0 1 0 1
not like this :
1 0 0 0 0 1 0 0
0 1 0 0 0 1 0 0
0 0 1 0 0 1 0 0
0 0 0 1 0 1 0 0
0 0 0 0 1 1 0 0
1 1 1 1 1 1 1 1
0 0 0 0 0 1 1 0
0 0 0 0 0 1 0 1
Backtracking is not the concern right now.
Your condition
if(row==col && i==j){
//csp[row][col]=1;
csp[i][j]=1;
}
should only work if row==col.
Otherwise you will only get the horizontal and vertical numbers.
If you want to mark the diagonals starting from row and col, this code should work:
if(i-j==row-col){ //diagonal up_left to down_right
csp[i][j]=1;
}
if(i+j==row+col) { //diagonal down_left to up_right
csp[i][j]=1;
}
I´m reading a simple jpg image with Java and printing out a 2d array of the pixel data.
If I have the entire image black I get what I expect:
This is the 10x20 black image
And the result:
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
However if I draw a white line on the first row of the image I'm getting 1's in a place I don´t expect:
The other image:
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1 1 1 //Why??
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
This is my code:
byte[][]pixels;
BufferedImage image;
public ImageProcessor(File f) throws IOException{
image = ImageIO.read(f);
//Bitmap bMap = BitmapFactory.decodeFile(f.getAbsolutePath()); // Si es jpg
pixels = new byte[image.getWidth()][];
for (int x = 0; x < image.getWidth(); x++) {
pixels[x] = new byte[image.getHeight()];
for (int y = 0; y < image.getHeight(); y++) {
pixels[x][y] = (byte) (image.getRGB(x, y));
}
}
}
public void printPixelMatrix(){
for (int i = 0; i < image.getHeight(); i++) {
for (int j = 0; j < image.getWidth(); j++) {
System.out.print(" "+pixels[j][i] + " ");
}
System.out.print("\n");
}
}
I don't use Java so I'm going on general computer graphics knowledge...
1) Firstly, You might want to set a type for your buffered image (ie: 4 byte where you have 1 byte for each component of R + G + B + Alpha). Something like BufferedImage.TYPE_INT_ARGB.
2) I don't get why you try to put the result of image.getRGB(x, y) into a byte. From Java docs it seems getRGB(x, y) returns an array not a single number and even then, that number would have combined all A-R-G-B as one but a byte can only hold one component's value as max amount (up to 255, but a color int could be like 4278254335 spread over 4 bytes).
suggested solution : Instead of bytes (and strides?), just scan the pixels and get an int of the pixel value. Then print those values. Black = 0 and also White = 4278254335. I think I got the Hex format code okay below, so that should show as : Black = FF000000 and then White = FFFFFFFF.
I think your final code should work something like as shown below. Please fix any mistakes (I put comments so you see what I am trying to do). That should give you the expected colours of the black, or black with white line, in the expected positions :
//# load your old one as usual
image = ImageIO.read(f);
//# Create a new bufferdImage with type (will draw old into this) //also consider TYPE_INT_RGB
BufferedImage newImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
//# Then draw original into new type...
Graphics2D g = newImage.createGraphics();
g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
g.dispose(); //needed or not???
//# Doing the For-loop
int imgW = image.getWidth();
int imgH = image.getHeight();
int pixels[][] = new int[imgW][imgH]; //create a 2D array
//# Fill Array : for each [x] pos we read down /column
//# so that we fill [y] with those pixel values
for (int x = 0; x < imgW; x++)
{
//On each X pos we scan all Y pixels in that column
for (int y = 0; y < imgH; y++)
{
int col = image.getRGB(x, y);
pixels[x][y] = col;
//printPixelARGB( col ); //if you need this format instead of printPixelMatrix
}
}
//# To Print output
public void printPixelMatrix()
{
for (int i = 0; i < image.getHeight(); i++)
{
for (int j = 0; j < image.getWidth(); j++)
{
//System.out.print(" " + pixels[j][i] + " ");
int c = pixels[j][i]; //get integer that was stored in the array
String HexVal = Integer.toHexString( c ) //giveshex value like AARRGGBB
System.out.print(" " + HexVal + " ");
}
System.out.print("\n");
}
}
//# Another helper function to print pixel values
//# print out example blue : argb: 255, 0, 0, 255
public void printPixelARGB(int pixel)
{
int alpha = (pixel >> 24) & 0xff;
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel) & 0xff;
System.out.println("ARGB : " + alpha + ", " + red + ", " + green + ", " + blue);
}
Java doesn't have unsigned types, so your "white" pixels, which are the maximum value (0xff), are interpreted as negative 1.
Presumably your positive 1s are a compression artifact.
I suspect you are getting an artifact from JPEG quantization. JPEG compresses square blocks of pixels, not individual pixels.
See if there is a way to change your quantization tables. If you make them all 1 values, this should go away. Some encoders use "quality" settings for this. Use the highest quality setting.
I am making a scrolling game in Java , I would like a clarification on one point.
I do not save the game level in any structure java , I just read a file ( . gif )
which I modified in a way that :
I use the color decryption to parse through every pixel to pixel and place where the
object meets the requirements that I have established .
for example:
.
.
.
int w = image.getWidth(); //store the dimensions of the level image.
int h = image.getHeight();
for(int x = 0; x < w; x++){
for(int y = 0; y < h; y++){ //check every single pixel with this nested loop
int pixel = image.getRGB(x, y); //get the pixel's rgb value
TYPE_INT_ARGB formatint red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel) & 0xff;
if(red == 255 && green == 255 && blue == 0)
controller.addPlayer((float)x, (float)y);
else if(red == 255 && green == 255 && blue == 255)
controller.addTerrain(x, y);
}
as you can see i don't save the level in any structure, but I just scan the image file that represents it.
is a good idea to do it this way?
Naturally i store all objects with the controller class where i create an arrayList that contains all game 's objects .
You could make a .txt file and create a map like this:
20
10
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 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 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0
the 0 would represent air and the 1 a walkable tile. the first value is the map width and the second the map height.
I also recommend you to use a 2d array to store the map information. Now you can read the txt file with a BufferedReader. Hope this code below helps
private final int TILE_SIZE = 30;
private int[][] blocks;
private void loadMap(File file) {
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
mapWidth = Integer.parseInt(reader.readLine());
mapHeight = Integer.parseInt(reader.readLine());
blocks = new int[mapHeight][mapWidth];
for(int col = 0; col < mapHeight; col ++) {
String line = reader.readLine();
String[] tokens = line.split(" ");
for(int row = 0; row < numBlocksRow; row++) {
blocks[col][row] = Integer.parseInt(tokens[row]);
}
}
reader.close();
} catch(Exception e) {
e.printStackTrace();
}
}
private void render(Graphics2D g) {
for(int col = 0; col < mapHeight; col ++) {
for(int row = 0; row < numBlocksRow; row++) {
int block = blocks[col][row];
Color color;
if(block == 1) {
color = Color.white;
} else {
color = Color.black;
}
g.fillRect(row * TILE_SIZE, col * TILE_SIZE, TILE_SIZE, TILE_SIZE);
}
}
}
Well I've created a simple tile map loading, from .txt file & then drawing.
25
15
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
So if the current tile is 1, it will be a green block.
Now the game window looks like this (ignore yellow dots at top):
(source: gyazo.com)
Okay everything is fine and great, but now can you see the red box? that's the character, and when it walks, I don't want it to go over the gates (any green block).
How can I do that?
My attempt:
private void makeClips() {
int[][] tiledMap = this.map.getMap();
for (int i = 0; i < this.map.getHeight(); i++) {
for (int j = 0; j < this.map.getWidth(); j++) {
if (tiledMap[i][j] == 1) {
clips.add(new Clip(j * 30, i * 30, 0, 0));
System.out.println("Added clip: " + j + " " + i + " " + (j + 30) + " " + (i + 30));
}
}
}
}
That should create an array of clips, so we can check if player's next walk equals to the clips coordinates, but I've had problems with setting the clip x, y like what will it's position be.
The 30 is the tile size, so each block will be 30 width 30 height sized.
And then in the walking method i've done this:
for (Clip clip : clips) {
if (myPlayer.getX() + x >= clip.getFirstX() && myPlayer.getX() + x <= clip.getSecX()
&& myPlayer.getY() + y >= clip.getFirstY() && myPlayer.getY() + y <= clip.getSecY()) {
System.out.println("Bad");
return;
}
}
But I don't know, this is 100% incorrect, mostly the coordinate calculating part.
What would you do in this case?
This is the drawing part for map:
private void renderMap(Graphics2D g) {
int[][] tiledMap = this.map.getMap();
for (int i = 0; i < this.map.getHeight(); i++) {
for (int j = 0; j < this.map.getWidth(); j++) {
int currentRow = tiledMap[i][j];
if (currentRow == 1) {
g.setColor(Color.green);
}
if (currentRow == 0) {
g.setColor(Color.black);
}
g.fillRect(0 + j * map.getTileSize(), 0 + i * map.getTileSize(),
map.getTileSize(), map.getTileSize());
g.setColor(Color.yellow);
for (Clip clip : clips) {
g.fillRect(clip.getFirstX(), clip.getFirstY(), 2, 2);
}
}
}
}
What can I do?
Why not do a check every time you move your player on the tile you want to move him onto.
Lets assume the player is at (0,0) on this small map.
0 0 1
0 0 0
0 0 0
We will try and move him to the right twice. The first time will work as at the position (1,0) the tile is equal to 0. The second time we try this the tile at (2,0) will return 1 and the player won't move.
if (tiledMap[player.getX() + 1)[player.getY()] == 1) {
//do nothing
} else {
//move player
}