Java 2d game tiled map clipping? - java

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
}

Related

Iterative Deepening using recursion bug

This is iterative deepening search and I want to keep track of the nodes generated before the goal state. I am using RUNNING_TIME as a counter and then assign it to each node in the tree. The thing is, because o recursion RUNNING_TIME is incremented more than once and the value is not valid anymore. Hence, I get a RUNNING_TIME for BFS which is better than this one which theoretically doesn't make sense (only worst case scenario). Do you have any idea how I should increment this value in my methods? I sincerely have no idea, thanks.
public void IDS() {
Grid startNode = new Grid(initState, A, B, C, agent);
for(int depth = 0; depth < Integer.MAX_VALUE; depth ++) {
Grid found = DLS(startNode, depth);
if(found != null) {
retracePath(found);
return;
}
}
}
public Grid DLS(Grid current, int depth) {
RUNNING_TIME ++;
current.nodesGeneratedBefore = RUNNING_TIME;
if(depth == 0 && current.checkGoalState()) {
return current;
}
if(depth > 0) {
for(Grid neighbor : current.getNeighbors(current)) {
Grid found = DLS(neighbor, depth - 1);
if(found != null) {
return found;
}
}
}
return null;
}
EDIT: Also I forgot to mention that I get the correct path to the destination, but only the "RUNNING_TIME" variable is wrongly incremented.
0 0 0 0
0 0 0 0
0 0 0 -1
1 2 3 0
Number of nodes generated by now 4680622
0 0 0 0
0 0 0 0
0 0 -1 0
1 2 3 0
Number of nodes generated by now 6297726
0 0 0 0
0 0 0 0
0 -1 0 0
1 2 3 0
Number of nodes generated by now 7106272
0 0 0 0
0 0 0 0
0 2 0 0
1 -1 3 0
Number of nodes generated by now 7760396
0 0 0 0
0 0 0 0
0 2 0 0
-1 1 3 0
Number of nodes generated by now 7837602
0 0 0 0
0 0 0 0
-1 2 0 0
0 1 3 0
Number of nodes generated by now 7837603
0 0 0 0
0 0 0 0
2 -1 0 0
0 1 3 0
Number of nodes generated by now 7842162
0 0 0 0
0 0 0 0
2 1 0 0
0 -1 3 0
Number of nodes generated by now 7848122
0 0 0 0
0 0 0 0
2 1 0 0
0 3 -1 0
Number of nodes generated by now 7849095
0 0 0 0
0 0 0 0
2 1 -1 0
0 3 0 0
Number of nodes generated by now 7849096
0 0 0 0
0 0 -1 0
2 1 0 0
0 3 0 0
Number of nodes generated by now 7849097
0 0 0 0
0 -1 0 0
2 1 0 0
0 3 0 0
Number of nodes generated by now 7849111
0 0 0 0
0 1 0 0
2 -1 0 0
0 3 0 0
Number of nodes generated by now 7849125
0 0 0 0
0 1 0 0
-1 2 0 0
0 3 0 0
Number of nodes generated by now 7849127

Java 2d array adding one to element error

On the program I am working on I have to find a letter pair contained in an unspecified amount of input. If two consecutive English letters that are the same, case-insensitive, are found, then I add one to an element within my 2d array that is 26 rows by 26 columns. Here is my code:
import java.util.Scanner;
public class Freq{
private static final int ROWS = 26;
private static final int COLS = 26;
private static int[] [] alphabet = new int[ROWS][COLS];
public static void main(String[] args) {
String line;
Scanner userInput = new Scanner(System.in);
while(userInput.hasNextLine()) {
line = userInput.nextLine();
processLine(line);
}
printArray();
}
public static void processLine(String line) {
line = line.toUpperCase();
for(int i = 0; i < alphabet.length; i++) {
for(int j = 0; j < alphabet[i].length; j++) {
for (int a = 0; a < line.length() - 1; a++) {
char firstLetter = line.charAt(a);
char secondLetter = line.charAt(a + 1);
if (firstLetter == secondLetter) {
alphabet[firstLetter - 65][secondLetter - 65] += 1;
}
}
}
}
}
public static void printArray() {
for (int b = 0; b < alphabet.length; b++) {
for (int c = 0; c < alphabet[b].length; c++){
System.out.print(alphabet[b][c] + " ");
}
System.out.println();
}
}
}
However when I run my program and input "aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz"
this is what happens:
aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz
676 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 676 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 676 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 676 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 676 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 676 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 676 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 676 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 676 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 676 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 676 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 676 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 676 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 676 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 676 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 676 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 676 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 676 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 676 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 676 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 676 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 676 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 676 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 676 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 676 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 676
I believe they are being added in the correct location, but why is my program adding 676 to the index and not just adding 1? Any help is greatly appreciated. Thank you!
Your processLine() method does not make much sense. First, you should only be iterating over the input string, and not the entire 2D array, i.e.:
public static void processLine(String line) {
line = line.toUpperCase();
for (int a=0; a < line.length() - 1; a++) {
char firstLetter = line.charAt(a);
char secondLetter = line.charAt(a + 1);
if (firstLetter == secondLetter) {
alphabet[firstLetter - 65][secondLetter - 65] += 1;
}
}
}
Second, your 2D array will only ever have entries on the diagonal, because you only ever make assignments where the two characters are the same for both dimensions. So you could just use a 1D array:
private static int[] alphabet = new int[ROWS];
public static void processLine(String line) {
line = line.toUpperCase();
for (int a=0; a < line.length() - 1; a++) {
char firstLetter = line.charAt(a);
char secondLetter = line.charAt(a + 1);
if (firstLetter == secondLetter) {
alphabet[firstLetter - 65] += 1;
}
}
}
What your are doing is that you are adding value from that position on matrix with 1 instead if you want 1 at that place just assign it
Replace this line
alphabet[firstLetter - 65][secondLetter - 65] += 1;
with this
alphabet[firstLetter - 65][secondLetter - 65] = 1;
or change your processLine method to this
public static void processLine(String line) {
line = line.toUpperCase();
for (int a = 0; a < line.length() - 1; a++) {
char firstLetter = line.charAt(a);
char secondLetter = line.charAt(a + 1);
if (firstLetter == secondLetter) {
alphabet[firstLetter - 65][secondLetter - 65] += 1;
}
}
}
hope this answer your question

Java 2d Array Logic Error

UPDATE AT BOTTOM:
I am creating a program with a 2d array. The array has 26 rows, and 26 columns. I am searching, one line at a time, for case-insensitive two-letter pairs, such as: "AA","AB","AC","AD", etc. If I find a letter pair, I add one to it's corresponding index in the array. The first letter determines the row, and second letter determines the column. For example this is how it is supposed to run:
aa
ab
ac
ad
ba
bb
bc
za
zb
zc
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
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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 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
My program is able to do above, however when I input:
AABBAACCAA
AA
4 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
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
1 0 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 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
I want the upper-left most number that currently says 4, to say 2. In other words, I want any particular letter pair to be only counted once per line. So If I input AAAAAAAAAAA, I want to only add one to alphabet[0][0]
Here is my code:
import java.util.Scanner;
public class Freq{
private static final int ROWS = 26;
private static final int COLS = 26;
private static int[] [] alphabet = new int[ROWS][COLS];
public static void main(String[] args) {
String line;
Scanner userInput = new Scanner(System.in);
while(userInput.hasNextLine()) {
line = userInput.nextLine();
processLine(line);
}
printArray();
}
public static void processLine(String line) {
line = line.toUpperCase();
for(int a = 0; a < line.length() - 1; a++) {
char firstLetter = line.charAt(a);
char secondLetter = line.charAt(a + 1);
alphabet[firstLetter - 65][secondLetter - 65] += 1;
}
}
public static void printArray() {
for (int b = 0; b < alphabet.length; b++) {
for (int c = 0; c < alphabet[b].length; c++){
System.out.print(alphabet[b][c] + " ");
}
System.out.println();
}
}
}
Any help is appreciated.
UPDATE: The top row of my array represents these two-letter pairs:
AA AB AC AD AE AF AG AH AI AJ AK AL AM AN AO AP AQ AR AS AT AU AV AW AX AY AZ
The second row represents these two-letter pairs:
BA BB BC BD BE BF BG BH BI BJ BK BL BM BN BO BP BQ BR BS BT BU BV BW BX BY BZ
etc.
The string: "This is a test" has these letter pairs: TH, HI, IS, IS, TE, ES, ST. These are all the letter pair occurrences in that string. However, I want to count each letter pair only once, so for my purposes, I want to record that string as having these letter pairs: TH, HI, IS, TE, ES, ST. Note the IS is not listed twice as I am only looking for one occurrence per line of input
This means if I enter on one line:
AAAAAAAAAAAA
I only want to add 1 to the first element in my array. So I would want the top row of my array to look like this:
1 0 0 0 0 0 0...
However, if I input the string "AAAAAAAAAAAA" on multiple lines like this:
AA
AA
AA
AA
AA
AA
AA
Then I want to add 6 to the first element of my array. Because AA occurred 6 different times on 6 different lines So I would want the top row of my array to look like this:
6 0 0 0 0 0 0...
Just put a condition in here:
for (int a=0; a < line.length() - 1; a++) {
char firstLetter = line.charAt(a);
char secondLetter = line.charAt(a + 1);
if (alphabet[firstLetter - 65][secondLetter - 65] == 0) { // Put it here
alphabet[firstLetter - 65][secondLetter - 65] = 1;
}
}
The following implementation adds a two dimensional boolean array called visited which keeps track of whether a given pair of letters has been seen for the current line. If we come across a pair of letters, for a given line, which we have not seen before, then we add one to the total for that cell. But seeing the same pair again in the current line will be ignored and the total won't move up. After consuming each line, we reset the visited array to false for every pair so that it can be reused with the proceeding line.
public class Freq {
private static final int ROWS = 26;
private static final int COLS = 26;
private static int[][] alphabet = new int[ROWS][COLS];
private static boolean[][] visited = new boolean[ROWS][COLS];
public static void main(String[] args) {
String line;
Scanner userInput = new Scanner(System.in);
while (userInput.hasNextLine()) {
clearVisited();
line = userInput.nextLine();
processLine(line);
}
printArray();
}
public static void clearVisited() {
for (int r=0; r < visited.length; r++) {
for (int c=0; c < visited[r].length; c++){
visited[r][c] = false;
}
}
}
public static void processLine(String line) {
line = line.toUpperCase();
for (int i=0; i < line.length()-1; i++) {
char firstLetter = line.charAt(i);
char secondLetter = line.charAt(i + 1);
if (!visited[firstLetter-65][secondLetter-65]) {
alphabet[firstLetter - 65][secondLetter - 65] += 1;
visited[firstLetter-65][secondLetter-65] = true;
}
}
}
}

Reading Pixel Data From JPG Image

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.

Java Tiled map is painting sideways

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.

Categories