Grid line collision checking - java

Lately I've been working on a grid line detection system, I know that there was an algorithm out there that did excactly what I wanted it to do, but I'm that kind of person who wants to make stuff themselves. ;)
So I've had some succes when checking with 1 line, but now that I use a grid of 20x20 to check the lines it doesn't work anymore.
The problem is found somewhere in the collision class I made for this system.
Somehow the numbers get out of the grid array and I don't know why
here is the code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
/**
*
* beschrijving
*
* #version 1.0 van 22-6-2016
* #author
*/
public class gridline extends JApplet {
// Begin variabelen
int[][] grid = new int[20][20];
int[] light = new int[2];
int[][] line = new int[2][2];
// Einde variabelen
public void init() {
Container cp = getContentPane();
cp.setLayout(null);
cp.setBounds(0, 0, 600, 600);
// Begin componenten
for (int a=0; a<20; a++) {
for (int b=0; b<20; b++) {
grid[a][b] = (int) (Math.random()*10);
} // end of for
} // end of for
line[0][0] = (int) (Math.random()*20);
line[0][1] = (int) (Math.random()*20);
line[1][0] = (int) (Math.random()*20);
line[1][1] = (int) (Math.random()*20);
light[0] = (int) (Math.random()*20);
light[1] = (int) (Math.random()*20);
// Einde componenten
} // end of init
//Custom classes
private boolean collide(int x1, int y1,int x2, int y2) {
boolean collide = true;
int tempx = x1 - x2;
int tempy = y1 - y2;
int sx = 0;
int sy = 0;
int x = 0;
int y = 0;
if (tempx == 0) {
tempx = 1;
sx = 1;
} // end of if
if (tempy == 0) {
tempy = 1;
sy = 1;
} // end of if
if (sx == 0) {
x = tempx + tempx/Math.abs(tempx);
} // end of if
else {
x = tempx;
} // end of if-else
if (sy == 0) {
y = tempy + tempy/Math.abs(tempy);
} // end of if
else {
y = tempy;
} // end of if-else
int absx = Math.abs(x);
int absy = Math.abs(y);
int nex = x/absx;
int ney = y/absy;
int off = 0;
float count = 0;
float step = 0;
if (absx != absy) {
if (absx == Math.min(absx,absy)) {
step = (float) absx/absy;
calc1: for (int a=0; a<absy; a++) {
count += step;
if (count > 1 && x1+off != x2) {
count -= 1;
off += nex;
} // end of if
if (grid[x1+off][y1+a*ney] == 9) {
collide = false;
break calc1;
} // end of if
} // end of for
} // end of if
else{
step = (float) absy/absx;
calc2: for (int a=0; a<absx; a++) {
count += step;
if (count > 1 && y1+off != y2) {
count -= 1;
off += ney;
} // end of if
if (grid[x1+a*nex][y1+off] == 9) {
collide = false;
break calc2;
} // end of if
} // end of for
}
} // end of if
else {
calc3: for (int a=0; a<absx; a++) {
if (grid[x1+a*nex][y1+a*ney] == 9) {
collide = false;
break calc3;
} // end of if
} // end of for
} // end of if-else
return collide;
}
private int length(int x1, int y1, int x2, int y2) {
double distance = Math.sqrt(Math.pow(x1-x2,2)+Math.pow(y1-y2,2));
return (int) distance;
}
// Begin eventmethoden
public void paint (Graphics g){
boolean draw = true;
Color col;
for (int a=0; a<20; a++) {
for (int b=0; b<20; b++) {
draw = collide(a,b,light[0],light[1]);
if (draw) {
int len = Math.max(255-length(a*30+15,b*30+15,light[0]*30+15,light[1]*30+15),0);
col = new Color(len,len,len);
g.setColor(col);
g.fillRect(a*30,b*30,30,30);
} // end of if
else{
col = new Color(0,0,0);
g.setColor(col);
g.fillRect(a*30,b*30,30,30);
}
} // end of for
} // end of for
}
// Einde eventmethoden
} // end of class gridline
I'll understand it if nobody wants to look through a code as big as this, but it could be helpful for your own projects and I'm completely okay with it if you copy and paste my code for your projects.
Many thanks in advace.

Related

Minesweeper draw number of nearby mines

I need to do a Minesweeper game. I have most of the methods down, but I cannot figure out a way to draw the number of mines around a given tile. I have a method that returns the number of mines around that tile, but no such method to actually display that number inside the tile in the game.
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.net.URL;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class MyPanel extends JPanel {
private static final long serialVersionUID = 3426940946811133635L;
private static final int GRID_X = 25;
private static final int GRID_Y = 25;
private static final int INNER_CELL_SIZE = 29;
private static final int TOTAL_COLUMNS = 9;
private static final int TOTAL_ROWS = 10; //Last row has only one cell
public int x = -1;
public int y = -1;
public int mouseDownGridX = 0;
public int mouseDownGridY = 0;
private ImageIcon icon;
private static char minefield[][];
public Color[][] colorArray = new Color[TOTAL_COLUMNS][TOTAL_ROWS];
public MyPanel() { //This is the constructor... this code runs first to initialize
if (INNER_CELL_SIZE + (new Random()).nextInt(1) < 1) { //Use of "random" to prevent unwanted Eclipse warning
throw new RuntimeException("INNER_CELL_SIZE must be positive!");
}
if (TOTAL_COLUMNS + (new Random()).nextInt(1) < 2) { //Use of "random" to prevent unwanted Eclipse warning
throw new RuntimeException("TOTAL_COLUMNS must be at least 2!");
}
if (TOTAL_ROWS + (new Random()).nextInt(1) < 3) { //Use of "random" to prevent unwanted Eclipse warning
throw new RuntimeException("TOTAL_ROWS must be at least 3!");
}
for (int x = 0; x < TOTAL_COLUMNS; x++) { //Top row
colorArray[x][0] = Color.LIGHT_GRAY;
}
for (int y = 0; y < TOTAL_ROWS; y++) { //Left column
colorArray[0][y] = Color.LIGHT_GRAY;
}
for (int x = 1; x < TOTAL_COLUMNS; x++) { //The rest of the grid
for (int y = 1; y < TOTAL_ROWS; y++) {
colorArray[x][y] = Color.LIGHT_GRAY;
}
}
minefield = new char [TOTAL_COLUMNS][TOTAL_ROWS];
}
Random rando = new Random();
public static int mines = 10;
public int flags = 10;
public static int flagged = 0;
public void paintComponent(Graphics g) {
super.paintComponent(g);
//Compute interior coordinates
Insets myInsets = getInsets();
int x1 = myInsets.left;
int y1 = myInsets.top;
int x2 = getWidth() - myInsets.right - 1;
int y2 = getHeight() - myInsets.bottom - 1;
int width = x2 - x1;
int height = y2 - y1;
//Paint the background
g.setColor(Color.LIGHT_GRAY);
g.fillRect(x1, y1, width + 1, height + 1);
//Draw the grid minus the bottom row (which has only one cell)
//By default, the grid will be 10x10 (see above: TOTAL_COLUMNS and TOTAL_ROWS)
g.setColor(Color.BLACK);
for (int y = 0; y <= TOTAL_ROWS - 1; y++) {
g.drawLine(x1 + GRID_X, y1 + GRID_Y + (y * (INNER_CELL_SIZE + 1)), x1 + GRID_X + ((INNER_CELL_SIZE + 1) * TOTAL_COLUMNS), y1 + GRID_Y + (y * (INNER_CELL_SIZE + 1)));
}
for (int x = 0; x <= TOTAL_COLUMNS; x++) {
g.drawLine(x1 + GRID_X + (x * (INNER_CELL_SIZE + 1)), y1 + GRID_Y, x1 + GRID_X + (x * (INNER_CELL_SIZE + 1)), y1 + GRID_Y + ((INNER_CELL_SIZE + 1) * (TOTAL_ROWS - 1)));
}
//Paint cell colors
for (int x = 0; x < TOTAL_COLUMNS; x++) {
for (int y = 0; y < TOTAL_ROWS; y++) {
if ((x == 0) || (y != TOTAL_ROWS - 1)) {
Color c = colorArray[x][y];
g.setColor(c);
g.fillRect(x1 + GRID_X + (x * (INNER_CELL_SIZE + 1)) + 1, y1 + GRID_Y + (y * (INNER_CELL_SIZE + 1)) + 1, INNER_CELL_SIZE, INNER_CELL_SIZE);
}
}
}
}
// Places the mines in the field
public void placeMines() {
int minesPlaced = 1;
while (minesPlaced <= mines) {
int x = rando.nextInt(TOTAL_COLUMNS);
int y = rando.nextInt(TOTAL_ROWS-1);
if (minefield[x][y] != '*') {
minefield[x][y] = '*';
minesPlaced++;
}
}
for (int i=0; i<9; i++) {
for (int j=0; j<9; j++) {
bombCheck(i, j);
if (bombCheck(i, j) == 1) {
System.out.println(i + "," + j); // for debugging purposes
}
}
}repaint();
}
//checks a tile, white if there were no mines
public void check (int x, int y) {
colorArray[x][y] = Color.WHITE ;
repaint();
}
// Checks whether this place in the field has a bomb (1) or not (0).
public int bombCheck(int x, int y) {
if (!(x == -1 || y == -1)) {
if (minefield[x][y] == '*') {
return 1;
}
else {
minefield[x][y] = 'c';
return 0;
}
}
else{
return 0;
}
}
// Checks for mines on the 8 other tiles around the target location and returns the number of mines there are.
public int minesAround(int x, int y) {
int mines = 0;
mines += bombCheck(x-1, y-1);
mines += bombCheck(x-1, y);
mines += bombCheck(x-1, y+1);
mines += bombCheck(x, y-1);
mines += bombCheck(x, y+1);
mines += bombCheck(x+1, y-1);
mines += bombCheck(x+1, y);
mines += bombCheck(x+1, y+1);
if (mines > 0) {
return mines;
}
else{
return 0;
}
}
//What I've come up with so far for drawing the number in the tile. Does not work.
public void draw (Graphics g, int n, int x, int y) {
super.paintComponent(g);
g.drawString("" + n + "", x, y);
}
//Recursive method
public void checkAround(int x, int y) {
int minx, miny, maxx, maxy;
check(x,y);
minx = (x <= 0 ? 0 : x - 1);
miny = (y <= 0 ? 0 : y - 1);
maxx = (x >= TOTAL_COLUMNS - 1 ? TOTAL_COLUMNS - 1 : x + 1);
maxy = (y >= TOTAL_ROWS - 2 ? TOTAL_ROWS - 2 : y + 1);
for (int i = minx; i < maxx; i ++) {
for (int j = miny; j <= maxy; j ++) {
if (bombCheck(i,j) == 0 && colorArray[i][j] != Color.WHITE) {
check(i,j);
if (minesAround(i,j) == 0) {
checkAround(i,j);
}
if (minesAround(i,j) == 1) {
draw(getGraphics(),1,i,j); // Does not work.
repaint();
}
}
}
}
}
//Flag
public int checkflag(int x, int y){
int status = 0;
if (!(x == -1 || y == -1)) {
if (colorArray[x][y] == Color.RED) {
status += 1;
}else {
status += 0;
}
}
return status;
}
//Resets field
public void reset() {
for (int i = 0; i < TOTAL_COLUMNS; i++) {
for (int j = 0 ;j < TOTAL_ROWS; j++) {
colorArray[i][j] = Color.LIGHT_GRAY;
minefield[i][j] = ' ';
MyMouseAdapter.f = 1;
repaint();
}
}
placeMines();
}
public int getGridX(int x, int y) {
Insets myInsets = getInsets();
int x1 = myInsets.left;
int y1 = myInsets.top;
x = x - x1 - GRID_X;
y = y - y1 - GRID_Y;
if (x < 0) { //To the left of the grid
return -1;
}
if (y < 0) { //Above the grid
return -1;
}
if ((x % (INNER_CELL_SIZE + 1) == 0) || (y % (INNER_CELL_SIZE + 1) == 0)) { //Coordinate is at an edge; not inside a cell
return -1;
}
x = x / (INNER_CELL_SIZE + 1);
y = y / (INNER_CELL_SIZE + 1);
if (x == 0 && y == TOTAL_ROWS - 1) { //The lower left extra cell
return x;
}
if (x < 0 || x > TOTAL_COLUMNS - 1 || y < 0 || y > TOTAL_ROWS - 2) { //Outside the rest of the grid
return -1;
}
return x;
}
public int getGridY(int x, int y) {
Insets myInsets = getInsets();
int x1 = myInsets.left;
int y1 = myInsets.top;
x = x - x1 - GRID_X;
y = y - y1 - GRID_Y;
if (x < 0) { //To the left of the grid
return -1;
}
if (y < 0) { //Above the grid
return -1;
}
if ((x % (INNER_CELL_SIZE + 1) == 0) || (y % (INNER_CELL_SIZE + 1) == 0)) { //Coordinate is at an edge; not inside a cell
return -1;
}
x = x / (INNER_CELL_SIZE + 1);
y = y / (INNER_CELL_SIZE + 1);
if (x == 0 && y == TOTAL_ROWS - 1) { //The lower left extra cell
return y;
}
if (x < 0 || x > TOTAL_COLUMNS - 1 || y < 0 || y > TOTAL_ROWS - 2) { //Outside the rest of the grid
return -1;
}
return y;
}
public ImageIcon getIcon() {
return icon;
}
public void setIcon(ImageIcon icon) {
this.icon = icon;
}
}
-
import java.awt.Color;
import java.awt.Component;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Random;
import javax.swing.JFrame;
public class MyMouseAdapter extends MouseAdapter {
public static int f = 1;
public void mousePressed(MouseEvent e) {
switch (e.getButton()) {
case 1: //Left mouse button
Component c = e.getComponent();
while (!(c instanceof JFrame)) {
c = c.getParent();
if (c == null) {
return;
}
}
JFrame myFrame = (JFrame) c;
MyPanel myPanel = (MyPanel) myFrame.getContentPane().getComponent(0);
Insets myInsets = myFrame.getInsets();
int x1 = myInsets.left;
int y1 = myInsets.top;
e.translatePoint(-x1, -y1);
int x = e.getX();
int y = e.getY();
myPanel.x = x;
myPanel.y = y;
myPanel.mouseDownGridX = myPanel.getGridX(x, y);
myPanel.mouseDownGridY = myPanel.getGridY(x, y);
myPanel.repaint();
break;
case 3: //Right mouse button
Component c1 = e.getComponent();
while (!(c1 instanceof JFrame)) {
c = c1.getParent();
if (c == null) {
return;
}
}
JFrame myFrame1 = (JFrame)c1;
MyPanel myPanel1 = (MyPanel) myFrame1.getContentPane().getComponent(0); //Can also loop among components to find MyPanel
Insets myInsets1 = myFrame1.getInsets();
int x2 = myInsets1.left;
int y2 = myInsets1.top;
e.translatePoint(-x2, -y2);
int x3 = e.getX();
int y3 = e.getY();
myPanel1.x = x3;
myPanel1.y = y3;
myPanel1.mouseDownGridX = myPanel1.getGridX(x3, y3);
myPanel1.mouseDownGridY = myPanel1.getGridY(x3, y3);
break;
default: //Some other button (2 = Middle mouse button, etc.)
//Do nothing
break;
}
}
public void mouseReleased(MouseEvent e) {
switch (e.getButton()) {
case 1: //Left mouse button
Component c = e.getComponent();
while (!(c instanceof JFrame)) {
c = c.getParent();
if (c == null) {
return;
}
}
JFrame myFrame = (JFrame)c;
MyPanel myPanel = (MyPanel) myFrame.getContentPane().getComponent(0); //Can also loop among components to find MyPanel
Insets myInsets = myFrame.getInsets();
int x1 = myInsets.left;
int y1 = myInsets.top;
e.translatePoint(-x1, -y1);
int x = e.getX();
int y = e.getY();
myPanel.x = x;
myPanel.y = y;
int gridX = myPanel.getGridX(x, y);
int gridY = myPanel.getGridY(x, y);
if ((myPanel.mouseDownGridX == -1) || (myPanel.mouseDownGridY == -1)) {
//Had pressed outside
//Do nothing
} else {
if ((gridX == -1) || (gridY == -1)) {
//Do nothing
}else if (gridX == 0 && gridY == 9) {
myPanel.reset();
} else {
if ((myPanel.mouseDownGridX != gridX) || (myPanel.mouseDownGridY != gridY)) {
//Released the mouse button on a different cell where it was pressed
//Do nothing
} else {
//Released the mouse button on the same cell where it was pressed
if (!(myPanel.mouseDownGridX == -1) || (myPanel.mouseDownGridY == -1)) {
if (!(myPanel.colorArray[gridX][gridY] == Color.RED)) {
if (myPanel.bombCheck(gridX, gridY) == 0) {
myPanel.checkAround(gridX, gridY);
}
else{
myPanel.colorArray[gridX][gridY] = Color.BLACK ;
System.out.println("You've Lost!");
myPanel.reset();
myPanel.repaint();
}
}
}
}
}
}
myPanel.repaint();
break;
case 3: //Right mouse button
Component c1 = e.getComponent();
while (!(c1 instanceof JFrame)) {
c = c1.getParent();
if (c == null) {
return;
}
}
JFrame myFrame1 = (JFrame)c1;
MyPanel myPanel1 = (MyPanel) myFrame1.getContentPane().getComponent(0); //Can also loop among components to find MyPanel
Insets myInsets1 = myFrame1.getInsets();
int x2 = myInsets1.left;
int y2 = myInsets1.top;
e.translatePoint(-x2, -y2);
int x3 = e.getX();
int y3 = e.getY();
myPanel1.x = x3;
myPanel1.y = y3;
int gridX1 = myPanel1.getGridX(x3, y3);
int gridY1 = myPanel1.getGridY(x3, y3);
int flags = 10;
if ((myPanel1.mouseDownGridX == -1) || (myPanel1.mouseDownGridY == -1)) {
//Had pressed outside
//Do nothing
} else {
if ((gridX1 == -1) || (gridY1 == -1)) {
//Is releasing outside
//Do nothing
} else {
if ((myPanel1.mouseDownGridX != gridX1) || (myPanel1.mouseDownGridY != gridY1)) {
}else{
if (!(myPanel1.colorArray[gridX1][gridY1] == Color.WHITE)) {
if (myPanel1.checkflag(gridX1, gridY1) == 0) {
if (!(f > flags)) {
if (myPanel1.bombCheck(gridX1, gridY1) == 1) {
MyPanel.flagged ++;
if (MyPanel.flagged == 10) {
System.out.println("You've Won! Congratulations!");
myPanel1.reset();
myPanel1.colorArray[gridX1][gridY1] = Color.LIGHT_GRAY ;
myPanel1.repaint();
}
}
myPanel1.colorArray[gridX1][gridY1] = Color.RED ;
myPanel1.repaint();
f ++;
}
}
else {
myPanel1.colorArray[gridX1][gridY1] = Color.LIGHT_GRAY ;
myPanel1.repaint();
f --;
}
}
}
}
}
break;
default: //Some other button (2 = Middle mouse button, etc.)
//Do nothing
break;
}
}
}
-
import javax.swing.JFrame;
public class Main {
public static void main(String[] args) {
JFrame myFrame = new JFrame("Color Grid");
myFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
myFrame.setLocation(400, 150);
myFrame.setSize(400, 400);
MyPanel myPanel = new MyPanel();
myFrame.add(myPanel);
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
myFrame.addMouseListener(myMouseAdapter);
myFrame.setVisible(true);
myPanel.placeMines();
}
}
This is only my first year studying Computer science, but if my intuition is correct, my draw method is drawing the number behind the tiles. These are just my thoughts, I have relatively little to no experience with Java.
In your paintComponent() add something like this:
Font f = new Font("Dialog", Font.PLAIN, 12); // choose a font for the numbers
g.setFont(f);
// Draw cell numbers
for (int x = 0; x < TOTAL_COLUMNS; x++) {
for (int y = 0; y < TOTAL_ROWS; y++) {
if (/* check if the (x,y) cell is uncovered */) {
int around = minesAround(x, y);
g.drawString(String.valueOf(around), /*cell x coord*/, /*cell y coord*/);
}
}
}
Alternatively, you can use an image for each cell number instead of using a string.

A* algorithm current node spreading outwards instead of one direction

The yellow circle indicates the starting node and the red circle is indicating the goal node. I can't understand why my current node is spreading outwards instead of the image below where the node is just going straight into the goal.
I'm currently following this guide Link
I just can't get this part into my head on how should I choose a better path using G cost. It says that a lower G cost means a better path. but what node should I compare to that lower G cost?
If it is on the open list already, check to see if this path to that square is better, using G cost as the measure. A lower G cost means that this is a better path. If so, change the parent of the square to the current square, and recalculate the G and F scores of the square.
My desired output should be like this.
public class AStar {
private List<Node> open = new ArrayList<Node>();
private List<Node> close = new ArrayList<Node>();
private Node[][] nodes;
private GIS gis;
private MapListener mapListener;
private Arrow arrow;
public AStar(GIS gis) {
this.gis = gis;
mapListener = new MapListener(this);
createMapNodes();
}
private void createMapNodes() {
nodes = new Node[gis.getUslMap().getTileWidth()][gis.getUslMap().getTileHeight()];
for (int x = 0; x < gis.getUslMap().getTileWidth(); x++) {
for (int y = 0; y < gis.getUslMap().getTileHeight(); y++) {
TiledMapTileLayer.Cell cell = gis.getUslMap().getPathLayer().getCell(x, y);
arrow = new Arrow();
nodes[x][y] = new Node(cell, arrow, x, y);
if (cell != null) {
nodes[x][y].setBounds(x * Map.TILE.getSize(), y * Map.TILE.getSize(), Map.TILE.getSize(), Map.TILE.getSize());
nodes[x][y].getLabel().setBounds(x * Map.TILE.getSize(), y * Map.TILE.getSize(), Map.TILE.getSize(), Map.TILE.getSize());
nodes[x][y].getArrow().getImage().setBounds(x * Map.TILE.getSize(), y * Map.TILE.getSize(), Map.TILE.getSize(), Map.TILE.getSize());
mapListener = new MapListener(this);
nodes[x][y].addListener(mapListener);
gis.getUslMap().getStage().getActors().add(nodes[x][y].getLabel());
gis.getUslMap().getStage().getActors().add(nodes[x][y].getArrow().getImage());
gis.getUslMap().getStage().addActor(nodes[x][y]);
nodes[x][y].debug();
}
}
}
}
private void clearNodes() {
for (int x = 0; x < gis.getUslMap().getTileWidth(); x++) {
for (int y = 0; y < gis.getUslMap().getTileHeight(); y++) {
nodes[x][y].gCost = 0;
nodes[x][y].hCost = 0;
nodes[x][y].fCost = 0;
nodes[x][y].getLabel().setText("");
nodes[x][y].getArrow().setDrawable("blank");
}
}
close.clear();
open.clear();
}
public void search(Vector2 start, Node goal) {
clearNodes();
Node current = nodes[(int) start.x][(int) start.y];
open.add(current);
while (!open.isEmpty()) {
current = getLowestFCost(open);
if (current == goal)
return;
open.remove(current);
close.add(current);
// Prints the Fcost.
current.getLabel().setText(current.fCost + "");
// Detect the adjacent tiles or nodes of the current node
// and calculate the G, H and F cost
for (int x = -1; x < 2; x++) {
for (int y = -1; y < 2; y++) {
int dx = current.x + x;
int dy = current.y + y;
if (isValidLocation(dx, dy)) {
if (isWalkable(x, y, nodes[dx][dy]))
continue;
if (!open.contains(nodes[dx][dy])) {
open.add(nodes[dx][dy]);
nodes[dx][dy].parent = current;
if (isDiagonal(x, y))
nodes[dx][dy].gCost = current.gCost + 14;
else
nodes[dx][dy].gCost = current.gCost + 10;
nodes[dx][dy].fCost = nodes[dx][dy].gCost + heuristic(nodes[dx][dy], goal);
} else if (open.contains(nodes[dx][dy])&&) {
}
}
}
}
}
}
private boolean isWalkable(int x, int y, Node node) {
return x == 0 && y == 0 || node.getCell() == null || close.contains(node);
}
private boolean isValidLocation(int dx, int dy) {
return dx > 0 && dx < gis.getUslMap().getTileWidth() &&
dy > 0 && dy < gis.getUslMap().getTileHeight();
}
private boolean isDiagonal(int x, int y) {
return x == -1 && y == 1 || x == 1 && y == 1 ||
x == -1 && y == -1 || y == -1 && x == 1;
}
private Node getLowestFCost(List<Node> open) {
int lowestCost = 0;
int index = 0;
for (int i = 0; i < open.size(); i++) {
if (open.get(i).fCost <= lowestCost) {
lowestCost = open.get(i).fCost;
index = i;
}
}
return open.get(index);
}
private int heuristic(Node start, Node goal) {
int dx = Math.abs(start.x - goal.x);
int dy = Math.abs(start.y - goal.y);
start.hCost = 10 * (dx + dy);
return start.hCost;
}
}
My node.class
private TiledMapTileLayer.Cell cell;
private Label label;
private Arrow arrow;
boolean diagonal;
Node parent;
int x;
int y;
int hCost;
int gCost;
int fCost;
public Node(TiledMapTileLayer.Cell cell, Arrow arrow, int x, int y) {
this.cell = cell;
this.x = x;
this.y = y;
this.arrow = arrow;
label = new Label("", Assets.getInstance().getMapAsset().getAssetSkin(), "default");
label.setPosition(this.getX(), this.getY());
}
TiledMapTileLayer.Cell getCell() {
return cell;
}
Label getLabel() {
return label;
}
public Arrow getArrow() {
return arrow;
}
I think you have a problem to get the lowestcost:
private Node getLowestFCost(List<Node> open) {
int lowestCost = 0;
int index = 0;
for (int i = 0; i < open.size(); i++) {
if (open.get(i).fCost <= lowestCost) {
lowestCost = open.get(i).fCost;
index = i;
}
}
return open.get(index);
}
you initiate lowestCost = 0 but fCost always more than 0, so this function is not really work. It makes the lowest cost obtained from initial lowestCost, not from fCost open list. Try to initiate lowestCost with big number or first value in open list.

Intersection of Rectangles for Java (Freeze Tag)

**Edited still not getting the right response **
I am not quite understanding how to figure out the intersection aspect of my project. So far I have determined the top, bottom, left and right but I am not sure where to go from there.
The main driver should call to check if my moving rectangles are intersecting and if the rectangle is froze the moving one intersecting with it should unfreeze it and change its color. I understand how to unfreeze it and change the color but for whatever the reason it isn't returning the value as true when they are intersecting and I know this code is wrong. Any helpful tips are appreciated.
*CLASS CODE*
import edu.princeton.cs.introcs.StdDraw;
import java.util.Random;
import java.awt.Color;
public class MovingRectangle {
Random rnd = new Random();
private int xCoord;
private int yCoord;
private int width;
private int height;
private int xVelocity;
private int yVelocity;
private Color color;
private boolean frozen;
private int canvas;
public MovingRectangle(int x, int y, int w, int h, int xv, int yv, int canvasSize) {
canvas = canvasSize;
xCoord = x;
yCoord = y;
width = w;
height = h;
xVelocity = xv;
yVelocity = yv;
frozen = false;
int c = rnd.nextInt(5);
if (c == 0) {
color = StdDraw.MAGENTA;
}
if (c == 1) {
color = StdDraw.BLUE;
}
if (c == 2) {
color = StdDraw.CYAN;
}
if (c == 3) {
color = StdDraw.ORANGE;
}
if (c == 4) {
color = StdDraw.GREEN;
}
}
public void draw() {
StdDraw.setPenColor(color);
StdDraw.filledRectangle(xCoord, yCoord, width, height);
}
public void move() {
if (frozen == false) {
xCoord = xCoord + xVelocity;
yCoord = yCoord + yVelocity;
}
else {
xCoord +=0;
yCoord +=0;
}
if (xCoord >= canvas || xCoord < 0) {
xVelocity *= -1;
this.setRandomColor();
}
if (yCoord >= canvas || yCoord < 0) {
yVelocity *= -1;
this.setRandomColor();
}
}
public void setColor(Color c) {
StdDraw.setPenColor(color);
}
public void setRandomColor() {
int c = rnd.nextInt(5);
if (c == 0) {
color = StdDraw.MAGENTA;
}
if (c == 1) {
color = StdDraw.BLUE;
}
if (c == 2) {
color = StdDraw.CYAN;
}
if (c == 3) {
color = StdDraw.ORANGE;
}
if (c == 4) {
color = StdDraw.GREEN;
}
}
public boolean containsPoint(double x, double y) {
int bottom = yCoord - height / 2;
int top = yCoord + height / 2;
int left = xCoord - width / 2;
int right = xCoord + width / 2;
if (x > left && x < right && y > bottom && y < top) {
color = StdDraw.RED;
return true;
} else {
return false;
}
}
public boolean isFrozen() {
if (frozen) {
return true;
} else {
return false;
}
}
public void setFrozen(boolean val) {
frozen = val;
}
public boolean isIntersecting(MovingRectangle r) {
int top = xCoord + height/2;
int bottom = xCoord - height/2;
int right = yCoord + width/2;
int left = yCoord - width/2;
int rTop = r.xCoord + r.height/2;
int rBottom = r.xCoord - r.height/2;
int rRight = r.yCoord + r.width/2;
int rLeft = r.yCoord - r.width/2;
if(right <= rRight && right >= rLeft || bottom <= rBottom && bottom
>= rTop){
return true;
} else {
return false;
}
}
}
Here is my main driver as well, because I might be doing something wrong here too.
import edu.princeton.cs.introcs.StdDraw;
import java.util.Random;
public class FreezeTagDriver {
public static final int CANVAS_SIZE = 800;
public static void main(String[] args) {
StdDraw.setCanvasSize(CANVAS_SIZE, CANVAS_SIZE);
StdDraw.setXscale(0, CANVAS_SIZE);
StdDraw.setYscale(0, CANVAS_SIZE);
Random rnd = new Random();
MovingRectangle[] recs;
recs = new MovingRectangle[5];
boolean frozen = false;
for (int i = 0; i < recs.length; i++) {
int xv = rnd.nextInt(4);
int yv = rnd.nextInt(4);
int x = rnd.nextInt(400);
int y = rnd.nextInt(400);
int h = rnd.nextInt(100) + 10;
int w = rnd.nextInt(100) + 10;
recs[i] = new MovingRectangle(x, y, w, h, xv, yv, CANVAS_SIZE);
}
while (true) {
StdDraw.clear();
for (int i = 0; i < recs.length; i++) {
recs[i].draw();
recs[i].move();
}
if (StdDraw.mousePressed()) {
for (int i = 0; i < recs.length; i++) {
double x = StdDraw.mouseX();
double y = StdDraw.mouseY();
if (recs[i].containsPoint(x, y)) {
recs[i].setFrozen(true);
}
}
}
for (int i = 0; i < recs.length; i++) {
//for 0
if(recs[0].isFrozen() && recs[0].isIntersecting(recs[1])){
recs[0].setFrozen(false);
}
if(recs[0].isFrozen() && recs[0].isIntersecting(recs[2])){
recs[0].setFrozen(false);
}
if(recs[0].isFrozen() && recs[0].isIntersecting(recs[3])){
recs[0].setFrozen(false);
}
//for 1
if(recs[1].isFrozen() && recs[1].isIntersecting(recs[2])){
recs[1].setFrozen(false);
}
if(recs[1].isFrozen() && recs[1].isIntersecting(recs[3])){
recs[1].setFrozen(false);
}
if(recs[1].isFrozen() && recs[1].isIntersecting(recs[4])){
recs[1].setFrozen(false);
}
//for 2
if(recs[2].isFrozen() && recs[2].isIntersecting(recs[0])){
recs[2].setFrozen(false);
}
if(recs[2].isFrozen() && recs[2].isIntersecting(recs[1])){
recs[2].setFrozen(false);
}
if(recs[2].isFrozen() && recs[2].isIntersecting(recs[3])){
recs[2].setFrozen(false);
}
if(recs[2].isFrozen() && recs[2].isIntersecting(recs[4])){
recs[2].setFrozen(false);
}
//for 3
if(recs[3].isFrozen() && recs[3].isIntersecting(recs[0])){
recs[3].setFrozen(false);
}
if(recs[3].isFrozen() && recs[3].isIntersecting(recs[1])){
recs[3].setFrozen(false);
}
if(recs[3].isFrozen() && recs[3].isIntersecting(recs[2])){
recs[3].setFrozen(false);
}
if(recs[3].isFrozen() && recs[3].isIntersecting(recs[4])){
recs[3].setFrozen(false);
}
//for 4
if(recs[4].isFrozen() && recs[4].isIntersecting(recs[0])){
recs[4].setFrozen(false);
}
if(recs[4].isFrozen() && recs[4].isIntersecting(recs[1])){
recs[4].setFrozen(false);
}
if(recs[4].isFrozen() && recs[4].isIntersecting(recs[3])){
recs[4].setFrozen(false);
}
if(recs[4].isFrozen() && recs[4].isIntersecting(recs[2]))
recs[4].setFrozen(false);
}
if (recs[0].isFrozen() && recs[1].isFrozen() &&
recs[2].isFrozen() && recs[3].isFrozen()
&& recs[4].isFrozen()) {
StdDraw.text(400, 400, "YOU WIN");
}
StdDraw.show(20);
}
}
}
Keep in mind you're using the OR operator here. So if right is less than rLeft, your intersector will return true. This isn't how it should work.
You need to check if right is INSIDE the rectangles bounds so to speak.
if(right <= rRight && right >= rLeft || the other checks here)
The above code checks if right is less than the rectangle's right, but also that the right is bigger than rectangle's left, which means it's somewhere in middle of the rectangle's left and right.
If this becomes too complicated you can simply use java's rectangle class, as it has the methods contains and intersects

How to import .java library in IntelliJ (folder of .java files)

I am a new programmer.
Here, I am trying to import a library (com.digitalmodular).
What I want to do is run the java program in here
package demos;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Arrays;
import com.digitalmodular.utilities.RandomFunctions;
import com.digitalmodular.utilities.gui.ImageFunctions;
import com.digitalmodular.utilities.swing.window.PixelImage;
import com.digitalmodular.utilities.swing.window.PixelWindow;
/**
* #author jeronimus
*/
// Date 2014-02-28
public class AllColorDiffusion extends PixelWindow implements Runnable {
private static final int CHANNEL_BITS = 7;
public static void main(String[] args) {
int bits = CHANNEL_BITS * 3;
int heightBits = bits / 2;
int widthBits = bits - heightBits;
new AllColorDiffusion(CHANNEL_BITS, 1 << widthBits, 1 << heightBits);
}
private final int width;
private final int height;
private final int channelBits;
private final int channelSize;
private PixelImage img;
private javax.swing.Timer timer;
private boolean[] colorCube;
private long[] foundColors;
private boolean[] queued;
private int[] queue;
private int queuePointer = 0;
private int remaining;
public AllColorDiffusion(int channelBits, int width, int height) {
super(1024, 1024 * height / width);
RandomFunctions.RND.setSeed(0);
this.width = width;
this.height = height;
this.channelBits = channelBits;
channelSize = 1 << channelBits;
}
#Override
public void initialized() {
img = new PixelImage(width, height);
colorCube = new boolean[channelSize * channelSize * channelSize];
foundColors = new long[channelSize * channelSize * channelSize];
queued = new boolean[width * height];
queue = new int[width * height];
for (int i = 0; i < queue.length; i++)
queue[i] = i;
new Thread(this).start();
}
#Override
public void resized() {}
#Override
public void run() {
timer = new javax.swing.Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
draw();
}
});
while (true) {
img.clear(0);
init();
render();
}
// System.exit(0);
}
private void init() {
RandomFunctions.RND.setSeed(0);
Arrays.fill(colorCube, false);
Arrays.fill(queued, false);
remaining = width * height;
// Initial seeds (need to be the darkest colors, because of the darkest
// neighbor color search algorithm.)
setPixel(width / 2 + height / 2 * width, 0);
remaining--;
}
private void render() {
timer.start();
for (; remaining > 0; remaining--) {
int point = findPoint();
int color = findColor(point);
setPixel(point, color);
}
timer.stop();
draw();
try {
ImageFunctions.savePNG(System.currentTimeMillis() + ".png", img.image);
}
catch (IOException e1) {
e1.printStackTrace();
}
}
void draw() {
g.drawImage(img.image, 0, 0, getWidth(), getHeight(), 0, 0, width, height, null);
repaintNow();
}
private int findPoint() {
while (true) {
// Time to reshuffle?
if (queuePointer == 0) {
for (int i = queue.length - 1; i > 0; i--) {
int j = RandomFunctions.RND.nextInt(i);
int temp = queue[i];
queue[i] = queue[j];
queue[j] = temp;
queuePointer = queue.length;
}
}
if (queued[queue[--queuePointer]])
return queue[queuePointer];
}
}
private int findColor(int point) {
int x = point & width - 1;
int y = point / width;
// Calculate the reference color as the average of all 8-connected
// colors.
int r = 0;
int g = 0;
int b = 0;
int n = 0;
for (int j = -1; j <= 1; j++) {
for (int i = -1; i <= 1; i++) {
point = (x + i & width - 1) + width * (y + j & height - 1);
if (img.pixels[point] != 0) {
int pixel = img.pixels[point];
r += pixel >> 24 - channelBits & channelSize - 1;
g += pixel >> 16 - channelBits & channelSize - 1;
b += pixel >> 8 - channelBits & channelSize - 1;
n++;
}
}
}
r /= n;
g /= n;
b /= n;
// Find a color that is preferably darker but not too far from the
// original. This algorithm might fail to take some darker colors at the
// start, and when the image is almost done the size will become really
// huge because only bright reference pixels are being searched for.
// This happens with a probability of 50% with 6 channelBits, and more
// with higher channelBits values.
//
// Try incrementally larger distances from reference color.
for (int size = 2; size <= channelSize; size *= 2) {
n = 0;
// Find all colors in a neighborhood from the reference color (-1 if
// already taken).
for (int ri = r - size; ri <= r + size; ri++) {
if (ri < 0 || ri >= channelSize)
continue;
int plane = ri * channelSize * channelSize;
int dr = Math.abs(ri - r);
for (int gi = g - size; gi <= g + size; gi++) {
if (gi < 0 || gi >= channelSize)
continue;
int slice = plane + gi * channelSize;
int drg = Math.max(dr, Math.abs(gi - g));
int mrg = Math.min(ri, gi);
for (int bi = b - size; bi <= b + size; bi++) {
if (bi < 0 || bi >= channelSize)
continue;
if (Math.max(drg, Math.abs(bi - b)) > size)
continue;
if (!colorCube[slice + bi])
foundColors[n++] = Math.min(mrg, bi) << channelBits * 3 | slice + bi;
}
}
}
if (n > 0) {
// Sort by distance from origin.
Arrays.sort(foundColors, 0, n);
// Find a random color amongst all colors equally distant from
// the origin.
int lowest = (int)(foundColors[0] >> channelBits * 3);
for (int i = 1; i < n; i++) {
if (foundColors[i] >> channelBits * 3 > lowest) {
n = i;
break;
}
}
int nextInt = RandomFunctions.RND.nextInt(n);
return (int)(foundColors[nextInt] & (1 << channelBits * 3) - 1);
}
}
return -1;
}
private void setPixel(int point, int color) {
int b = color & channelSize - 1;
int g = color >> channelBits & channelSize - 1;
int r = color >> channelBits * 2 & channelSize - 1;
img.pixels[point] = 0xFF000000 | ((r << 8 | g) << 8 | b) << 8 - channelBits;
colorCube[color] = true;
int x = point & width - 1;
int y = point / width;
queued[point] = false;
for (int j = -1; j <= 1; j++) {
for (int i = -1; i <= 1; i++) {
point = (x + i & width - 1) + width * (y + j & height - 1);
if (img.pixels[point] == 0) {
queued[point] = true;
}
}
}
}
}
The thing is, I cant figure out how to import the library into IntelliJ. I have tried importing the library from Project Structure->Modules->Dependencies->Library->Java but failed. It appears that all the files in the given library are .java files, not .jar files
How should I import the library? Do I need to compile the whole library first? If yes, how?
This is my first question on this site, so my question may not be so clear :P
try
go to project settings -> Platform Settings -> SDKs -> Sourcepath (in the right panel) and add your downloaded zip -> Apply -> OK

java.lang.NullPointerException Can't Find Source

I'm in the process of programming a java rpg game, and have reached an impass. My code currently has sprite animation, a random map generation with perlin noise and collision detection. The map is tiled base, so i'm currently trying to convert the perlin noise to tiles. The perlin functions generate a array, and im each number of that array to a tile png. This is where the problem comes: RUNTIME ERROR: Java.Lang.NullPointerException.
The probleme is my compiler (netbeans) does not show me where the error occurs, but instead only gives me this error code. With a process of exclusion I managed to locate the error, which occurs at line 364. If this site doesnt support lines, it is at the loadTile() method, at "if(perlinIsland[x][y] <= 0.05)blockImg[x][y] = TILE[0];". I believe all the variables are correctly initialized, but I can't manage to find a solution. Please excuse the long code, but I included everything for the sake of information. Thanks you in advance for you help!
package java4k;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import java.math.*;
import java.util.*;
/**
*
* #author Christophe
*/
public class Main extends JFrame implements Runnable{
public Image dbImage;
public Graphics dbGraphics;
//Image + Array size
final static int listWidth = 500, listHeight = 500;
//Move Variables
int playerX = 320, playerY = 240, xDirection, yDirection;
//Sprites
BufferedImage spriteSheet;
//Lists for sprite sheet: 1 = STILL; 2 = MOVING_1; 3 = MOVING_2
BufferedImage[] ARCHER_NORTH = new BufferedImage[4];
BufferedImage[] ARCHER_SOUTH = new BufferedImage[4];
BufferedImage[] ARCHER_EAST = new BufferedImage[4];
BufferedImage[] ARCHER_WEST = new BufferedImage[4];
Image[] TILE = new Image[8];
//Animation Variables
int currentFrame = 0, framePeriod = 150;
long frameTicker = 0l;
Boolean still = true;
Boolean MOVING_NORTH = false, MOVING_SOUTH = false, MOVING_EAST = false, MOVING_WEST = false;
BufferedImage player = ARCHER_SOUTH[0];
//World Tile Variables
//20 X 15 = 300 tiles
Rectangle[][] blocks = new Rectangle[listWidth][listHeight];
Image[][] blockImg = new Image[listWidth][listHeight];
Image[][] blockImgTrans = new Image[listWidth][listHeight];
Boolean[][] isSolid = new Boolean[listWidth][listHeight];
int tileX = 0, tileY = 0;
Random r = new Random();
Rectangle playerRect = new Rectangle(playerX + 4,playerY+20,32,20);
//Map Navigation
static final byte PAN_UP = 0, PAN_DOWN = 1, PAN_LEFT = 2, PAN_RIGHT = 3;
//Perlin noise variables:
Color test = new Color(0, 0, 0);
static float[][] perlinNoise = new float[listWidth][listHeight];
static float[][] gradiantNoise = new float[listWidth][listHeight];
static float[][] perlinIsland = new float[listWidth][listHeight];
static float[][] biome = new float[listWidth][listHeight];
//Saved as png
static BufferedImage perlinImage;
public Main(){
this.setTitle("JAVA4K");
this.setSize(640,505);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
addKeyListener(new AL());
TILE[0] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_GRASS_1.png").getImage();
TILE[1] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_GRASS_2.png").getImage();
TILE[2] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_GRASS_3.png").getImage();
TILE[3] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_WATER_1.png").getImage();
TILE[4] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_TREE_1_BOT.png").getImage();
TILE[5] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_TREE_1_TOP.png").getImage();
TILE[6] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_TREE_2_BOT.png").getImage();
TILE[7] = new ImageIcon("C:/Users/Christophe/Documents/NetBeansProjects/Java4k/src/java4k/TILE_TREE_2_TOP.png").getImage();
loadTiles();
init();
}
//Step 1: Generates array of random number 0 < n < 1
public static float[][] GenerateWhiteNoise(int width, int height){
Random r = new Random();
Random random = new Random(r.nextInt(1000000000)); //Seed to 0 for testing
float[][] noise = new float[width][height];
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
noise[i][j] = (float)random.nextDouble() % 1;
}
}
return noise;
}
//Step 2: Smooths out random numbers
public static float[][] GenerateSmoothNoise(float[][] baseNoise, int octave){
int width = baseNoise.length;
int height = baseNoise.length;
float[][] smoothNoise = new float[width][height];
int samplePeriod = 1 << octave; // calculates 2 ^ k
float sampleFrequency = 1.0f / samplePeriod;
for (int i = 0; i < width; i++)
{
//calculate the horizontal sampling indices
int sample_i0 = (i / samplePeriod) * samplePeriod;
int sample_i1 = (sample_i0 + samplePeriod) % width; //wrap around
float horizontal_blend = (i - sample_i0) * sampleFrequency;
for (int j = 0; j < height; j++)
{
//calculate the vertical sampling indices
int sample_j0 = (j / samplePeriod) * samplePeriod;
int sample_j1 = (sample_j0 + samplePeriod) % height; //wrap around
float vertical_blend = (j - sample_j0) * sampleFrequency;
//blend the top two corners
float top = Interpolate(baseNoise[sample_i0][sample_j0],
baseNoise[sample_i1][sample_j0], horizontal_blend);
//blend the bottom two corners
float bottom = Interpolate(baseNoise[sample_i0][sample_j1],
baseNoise[sample_i1][sample_j1], horizontal_blend);
//final blend
smoothNoise[i][j] = Interpolate(top, bottom, vertical_blend);
}
}
return smoothNoise;
}
//Used in GeneratePerlinNoise() to derivate functions
public static float Interpolate(float x0, float x1, float alpha)
{
float ft = alpha * 3.1415927f;
float f = (float) (1 - Math.cos(ft)) * .5f;
return x0*(1-f) + x1*f;
}
//Step 3: Combines arrays together to generate final perlin noise
public static float[][] GeneratePerlinNoise(float[][] baseNoise, int octaveCount)
{
int width = baseNoise.length;
int height = baseNoise[0].length;
float[][][] smoothNoise = new float[octaveCount][][]; //an array of 2D arrays containing
float persistance = 0.5f;
//generate smooth noise
for (int i = 0; i < octaveCount; i++)
{
smoothNoise[i] = GenerateSmoothNoise(baseNoise, i);
}
float[][] perlinNoise = new float[width][height];
float amplitude = 1.0f;
float totalAmplitude = 0.0f;
//blend noise together
for (int octave = octaveCount - 1; octave >= 0; octave--)
{
amplitude *= persistance;
totalAmplitude += amplitude;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
perlinNoise[i][j] += smoothNoise[octave][i][j] * amplitude;
}
}
}
//normalisation
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
perlinNoise[i][j] /= totalAmplitude;
}
}
return perlinNoise;
}
//Step 4: Generate circular gradiant: center = 0, outside = 1
public static float[][] GenerateCircularGradiant(float[][] base, int size, int centerX, int centerY){
base = new float[size][size];
for (int x = 0; x < base.length; x++) {
for (int y = 0; y < base.length; y++) {
//Simple squaring, you can use whatever math libraries are available to you to make this more readable
//The cool thing about squaring is that it will always give you a positive distance! (-10 * -10 = 100)
float distanceX = (centerX - x) * (centerX - x);
float distanceY = (centerY - y) * (centerY - y);
float distanceToCenter = (float) Math.sqrt(distanceX + distanceY);
//Make sure this value ends up as a float and not an integer
//If you're not outputting this to an image, get the correct 1.0 white on the furthest edges by dividing by half the map size, in this case 64. You will get higher than 1.0 values, so clamp them!
float mapSize = base.length/2;
//mapSize = 500;
distanceToCenter = distanceToCenter / mapSize;
base[x][y] = distanceToCenter - 0.2f;
}
}
return base;
}
//step 5: Combine perlin noise with circular gradiant to create island
public static float[][] GenerateIsland(float[][] baseCircle, float[][] baseNoise){
float[][] baseIsland = new float[baseNoise.length][baseNoise.length];
for(int x = 0; x < baseNoise.length; x++){
for(int y = 0; y < baseNoise.length; y++){
baseIsland[x][y] = baseNoise[x][y] - baseCircle[x][y];
}
}
return baseIsland;
}
//Method for optional paramater = float[][] biome
public static void GreyWriteImage(float[][] data, String filename){
float[][] temp = null;
GreyWriteImage(data, temp, filename);
}
//Converts array data to png image
public static void GreyWriteImage(float[][] data, float[][] biome, String fileName){
//this takes and array of doubles between 0 and 1 and generates a grey scale image from them
BufferedImage image = new BufferedImage(data.length,data[0].length, BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < data[0].length; y++)
{
for (int x = 0; x < data.length; x++)
{
if (data[x][y]>1){
data[x][y]=1;
}
if (data[x][y]<0){
data[x][y]=0;
}
Color col;
//Deep Water 0 - 0.05
if(data[x][y] <= 0.05) col = new Color(0, 0, 255);
//Shallow Water 0.05 - 0.08
else if(data[x][y] <= 0.08) col = new Color(100, 100, 255);
//Beach 0.08 - 0.2
else if(data[x][y]<=0.15) col = new Color(255, 255, 0);
//Forest 0.2 - 0.6 + 0 0 0.7
else if(data[x][y]<=0.6 && biome != null && (biome[x][y] < 0.6 || biome[x][y] > 0.9)){
//Forest
if(biome[x][y] < 0.6) col = new Color(0, 150, 0);
//Desert
else col = new Color(200, 200, 0);
}
//Plains 0.2 - 0.6
else if(data[x][y] <= 0.6) col = new Color(0, 255, 0);
//Rocky Mountains 0.6 - 0.8
else if(data[x][y] <= 0.65) col = new Color(100, 100, 100);
//Snowy Mountains 0.6 - 1
else col = new Color(255, 255, 255);
image.setRGB(x, y, col.getRGB());
}
}
try {
// retrieve image
File outputfile = new File(fileName);
outputfile.createNewFile();
ImageIO.write(image, "png", outputfile);
} catch (IOException e) {
System.out.println("GREY WRITE IMAGE ERROR 303: " + e);
}
}
//First called to store image tiles in blockImg[][] and tile rectangles in blocks[][]
private void loadTiles(){
//Primary Perlin Noise Generation
perlinNoise = GenerateWhiteNoise(listWidth, listHeight);
GreyWriteImage(perlinNoise, "perlinNoise.png");
perlinNoise = GenerateSmoothNoise(perlinNoise, 7);
GreyWriteImage(perlinNoise, "smoothNoise.png");
perlinNoise = GeneratePerlinNoise(perlinNoise, 5);
GreyWriteImage(perlinNoise, "finalPerlin.png");
gradiantNoise = GenerateCircularGradiant(gradiantNoise, listWidth, listWidth/2 - 1, listHeight/2 - 1);
GreyWriteImage(gradiantNoise, "gradiantNoise.png");
perlinIsland = GenerateIsland(gradiantNoise, perlinNoise);
GreyWriteImage(perlinIsland, "perlinIsland.png");
//Biome Perlin Noise Generation
biome = GenerateWhiteNoise(listWidth, listHeight);
biome = GenerateSmoothNoise(biome, 6);
biome = GeneratePerlinNoise(biome, 5);
GreyWriteImage(perlinIsland, biome, "biome.png");
for(int y = 0; y < listHeight; y++){
for(int x = 0; x < listWidth; x++){
//Sets boundaries: 0 < perlinIsland[x][y] < 1
if (perlinIsland[x][y]>1) perlinIsland[x][y]=1;
if (perlinIsland[x][y]<0) perlinIsland[x][y]=0;
//Deep Water 0 - 0.05
if(perlinIsland[x][y] <= 0.05)blockImg[x][y] = TILE[0];
//Shallow Water 0.05 - 0.08
else if(perlinIsland[x][y] <= 0.08) blockImg[x][y] = TILE[3];
//Beach 0.08 - 0.2
else if(perlinIsland[x][y]<=0.15) blockImg[x][y] = TILE[4];
//Forest 0.2 - 0.6 + 0 0 0.7
else if(perlinIsland[x][y]<=0.6 && biome != null && (biome[x][y] < 0.6 || biome[x][y] > 0.9)){
//Forest
if(biome[x][y] < 0.6) blockImg[x][y] = TILE[5];
//Desert
else blockImg[x][y] = TILE[3];
}
//Plains 0.2 - 0.6
else if(perlinIsland[x][y] <= 0.6) blockImg[x][y] = TILE[2];
//Rocky Mountains 0.6 - 0.8
else if(perlinIsland[x][y] <= 0.65) blockImg[x][y] = TILE[3];
//Snowy Mountains 0.6 - 1
else blockImg[x][y] = TILE[1];
blocks[x][y] = new Rectangle(x*32, y*32, 32, 32);
}
}
}
//collision detection
public boolean collide(Rectangle in)
{
if(blocks[0][0] != null){
for (int y = (int)((playerRect.y - blocks[0][0].y) / 32)-1; y <= (int)((playerRect.y+playerRect.height - blocks[0][0].y) / 32)+1; y++){
for (int x = (int)((playerRect.x - blocks[0][0].x) / 32)-1; x <= (int)((playerRect.x+playerRect.width - blocks[0][0].x) / 32) + 1; x++){
if (x >= 0 && y >= 0 && x < 32 && y < 32){
if (blockImg[x][y] != null)
{
if (in.intersects(blocks[x][y]) && isSolid[x][y] == true){
{
return true;
}
}
}
}
}
}
}
return false;
}
//Key Listener
public class AL extends KeyAdapter{
public void keyPressed(KeyEvent e){
int keyInput = e.getKeyCode();
still = false;
if(keyInput == e.VK_LEFT){
navigateMap(PAN_RIGHT);
MOVING_WEST = true;
}if(keyInput == e.VK_RIGHT){
navigateMap(PAN_LEFT);
MOVING_EAST = true;
}if(keyInput == e.VK_UP){
navigateMap(PAN_DOWN);
MOVING_NORTH = true;
}if(keyInput == e.VK_DOWN){
navigateMap(PAN_UP);
MOVING_SOUTH = true;
}
}
public void keyReleased(KeyEvent e){
int keyInput = e.getKeyCode();
setYDirection(0);
setXDirection(0);
if(keyInput == e.VK_LEFT){
MOVING_WEST = false;
player = ARCHER_WEST[0];
}if(keyInput == e.VK_RIGHT){
MOVING_EAST = false;
player = ARCHER_EAST[0];
}if(keyInput == e.VK_UP){
MOVING_NORTH = false;
player = ARCHER_NORTH[0];
}if(keyInput == e.VK_DOWN){
MOVING_SOUTH = false;
player = ARCHER_SOUTH[0];
}
if( MOVING_SOUTH == MOVING_NORTH == MOVING_EAST == MOVING_WEST == false){
still = true;
}
}
}
public void moveMap(){
for(int a = 0; a < 30; a++){
for(int b = 0; b < 30; b++){
if(blocks[a][b] != null){
blocks[a][b].x += xDirection;
blocks[a][b].y += yDirection;
}
}
}
if(collide(playerRect) && blocks[0][0]!= null){
for(int a = 0; a < 30; a++){
for(int b = 0; b < 30; b++){
blocks[a][b].x -= xDirection;
blocks[a][b].y -= yDirection;
}
}
}
}
public void navigateMap(byte pan){
switch(pan){
default:
System.out.println("Unrecognized pan!");
break;
case PAN_UP:
setYDirection(-1);
break;
case PAN_DOWN:
setYDirection(+1);
break;
case PAN_LEFT:
setXDirection(-1);
break;
case PAN_RIGHT:
setXDirection(+1);
break;
}
}
//Animation Update
public void update(long gameTime) {
if (gameTime > frameTicker + framePeriod) {
frameTicker = gameTime;
currentFrame++;
if (currentFrame >= 4) {
currentFrame = 0;
}
}
if(MOVING_NORTH) player = ARCHER_NORTH[currentFrame];
if(MOVING_SOUTH) player = ARCHER_SOUTH[currentFrame];
if(MOVING_EAST) player = ARCHER_EAST[currentFrame];
if(MOVING_WEST) player = ARCHER_WEST[currentFrame];
}
public void setXDirection(int xdir){
xDirection = xdir;
}
public void setYDirection(int ydir){
yDirection = ydir;
}
//Method to get sprites
public BufferedImage grabSprite(int x, int y, int width, int height){
BufferedImage sprite = spriteSheet.getSubimage(x, y, width, height);
return sprite;
}
private void init(){
spriteSheet = null;
try {
spriteSheet = loadImage("ARCHER_SPRITESHEET.png");
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
for(int i = 0; i <= 3; i++){
ARCHER_NORTH[i] = grabSprite(i*16, 16, 16,16);
ARCHER_SOUTH[i] = grabSprite(i*16, 0, 16, 16);
ARCHER_EAST[i] = grabSprite(i*16, 32, 16, 16);
ARCHER_WEST[i] = grabSprite(i*16, 48, 16, 16);
}
}
public BufferedImage loadImage(String pathRelativeToThis) throws IOException{
URL url = this.getClass().getResource(pathRelativeToThis);
BufferedImage img = ImageIO.read(url);
return img;
}
public void paint(Graphics g){
dbImage = createImage(getWidth(), getHeight());
dbGraphics = dbImage.getGraphics();
paintComponent(dbGraphics);
g.drawImage(dbImage, 0, 25, this);
}
public void paintComponent(Graphics g){
requestFocus();
/**
//Draws tiles and rectangular boundaries for debugging
for(int a = 200; a < 230; a++){
for(int b = 200; b < 230; b++){
if(blockImg[a][b] != null && blocks[a][b] != null){
g.drawImage(blockImg[a][b], Math.round(blocks[a][b].x), Math.round(blocks[a][b].y), 32, 32, null);
}
}
}
//Draw player and rectangular boundary for collision detection
g.drawImage(player, playerX, playerY, 40, 40, null);
repaint();
//Draws transparent tiles
for(int a = 0; a < 20; a++){
for(int b = 0; b < 15; b++){
if(blockImgTrans[a][b] != null && blocks[a][b] != null){
g.drawImage(blockImgTrans[a][b], blocks[a][b].x, blocks[a][b].y, 32, 32, null);
}
}
}
**/
}
public void run(){
try{
while(true){
moveMap();
if(!still) update(System.currentTimeMillis());
Thread.sleep(13);
}
}catch(Exception e){
System.out.println("RUNTIME ERROR: " + e);
}
}
public static void main(String[] args) {
Main main = new Main();
//Threads
Thread thread1 = new Thread(main);
thread1.start();
}
}
Your limited catch block code hampers your ability to find your nulls.
For instance, these lines of code:
try {
while (true) {
moveMap();
if (!still)
update(System.currentTimeMillis());
Thread.sleep(13);
}
} catch (Exception e) {
System.out.println("RUNTIME ERROR: " + e);
}
Will only print
RUNTIME ERROR: java.lang.NullPointerException
without line numbers or stack trace when this code runs into an NPE.
First off, you should not be trapping for plain Exception but rather for explicit Exceptions. Next you should use a more informative catch block, for instance one that at least prints out the stack trace via e.printStackTrace().
The block above should really be written:
public void run() {
while (true) {
moveMap();
if (!still)
update(System.currentTimeMillis());
try {
Thread.sleep(13);
// only catch the explicit exception and in localized code if possible.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Do this, and you'll see that the NPE occurs here:
if (in.intersects(blocks[x][y]) && isSolid[x][y] == true) {
Then you can stuff code in front of that line to see which variable is causing the problem:
e.g.,
if (blockImg[x][y] != null) {
System.out.println("in is null: " + (in == null));
System.out.println("blocks[x][y] is null: "
+ (blocks[x][y] == null));
System.out.println("isSolid is null: "
+ (isSolid == null));
System.out.println("isSolid[x][y] is null: "
+ (isSolid[x][y] == null));
if (in.intersects(blocks[x][y]) && isSolid[x][y] == true) {
{
return true;
}
}
}
And you'll see the problem is that isSolid[x][y] is null:
in is null: false
blocks[x][y] is null: false
isSolid is null: false
isSolid[x][y] is null: true
in is null: false
blocks[x][y] is null: false
isSolid is null: false
isSolid[x][y] is null: true
in is null: false
blocks[x][y] is null: false
isSolid is null: false
isSolid[x][y] is null: true
Exception in thread "Thread-3" java.lang.NullPointerException
at pkg.Main.collide(Main.java:465)
at pkg.Main.moveMap(Main.java:557)
at pkg.Main.run(Main.java:693)
at java.lang.Thread.run(Unknown Source)
in is null: false
blocks[x][y] is null: false
isSolid is null: false
isSolid[x][y] is null: true
in is null: false
blocks[x][y] is null: false
isSolid is null: false
isSolid[x][y] is null: true
in is null: false
blocks[x][y] is null: false
isSolid is null: false
isSolid[x][y] is null: true
And why is that? It's an array of Booleans, not booleans, so it is not initialized to Boolean.FALSE but rather it defaults to null. Solution: either use boolean[][] array or initialize your array explicitly.
Most important: use informative catch blocks and don't catch for general Exceptions.
Edit note that as an aside, in order for me to get your code to run, I had to disable your use of images and sprite sheets, since these are resources that are unavailable to me. This effort should be yours though since you are the one seeking in the future. I ask that in the future, you limit your code to the smallest code that we can test and run, that demonstrates your problem, but that has no code unrelated to your problem, and that does not rely on outside resources such as images, databases, etc..., an sscce.

Categories