Colision detecting in java(Tiled map) - java

Here i have a code with a picture moving around the map.
How to make this picture colide when interacte with map tiles ? I'm a beginer at java so i have no ideas. Any Help or advise is very welcome.
Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.swing.Timer;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import org.omg.CORBA.portable.InputStream;
import java.io.Reader;
public class NewTest extends JFrame implements KeyListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private Image TestImage;
private BufferedImage bf;
private BufferedImage bufferedImage;
private int cordX = 100;
private int cordY = 100;
public int mapy=25;
public int mapx=mapy;
public int size= 20;
private boolean down, up, left, right;
private Image wall = Toolkit.getDefaultToolkit().getImage("image/Koala.jpg");
private Image no = Toolkit.getDefaultToolkit().getImage("image/house.jpg");
public static int[][]
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, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 10, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 11},
{0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 3, 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3},
{0, 12, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 13}};
public NewTest() throws IOException {
setTitle("Testing....");
setSize(mapy*size+50,mapx*size+50);
imageLoader();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void imageLoader() throws IOException {
TestImage = Toolkit.getDefaultToolkit().getImage("image/Koala.jpg");
addKeyListener(this);
}
public void update(Graphics g){
paint(g);
}
public void paint(Graphics g){
bf = new BufferedImage( this.getWidth(),this.getHeight(), BufferedImage.TYPE_INT_RGB);
try{
animation(bf.getGraphics());
g.drawImage(bf,0,0,null);
}catch(Exception ex){
}
}
public void animation(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
for (int y = 0; y <= mapy; y++){
for (int x = 0; x <= mapx; x++){
int L = x * size;
int U = y * size;
int R = size;
int D = size;
/// g2d.rotate(Math.toRadians(-90));
if (map[y][x] == 1){
//no black wall
g2d.setColor(Color.green);
g2d.fillRect(L, U, R, D);
}else if (map[y][x] == 2){
//on left
g2d.setColor(Color.green);
g2d.fillRect(L, U, R, D);
g2d.setColor(Color.black);
g2d.fillRect(L-size/2 +2, U, 8, size);
}else if (map[y][x] == 3){
//on right
g2d.setColor(Color.green);
g2d.fillRect(L, U, R, D);
g2d.setColor(Color.black);
g2d.fillRect(L+size, U, 8, size);
}else if (map[y][x] == 4){
//on top
g2d.setColor(Color.green);
g2d.fillRect(L, U, R, D);
g2d.setColor(Color.black);
g2d.fillRect(L, U-size/2 + 2, size, 8);
}else if (map[y][x] == 5){
//on bottom
g2d.setColor(Color.green);
g2d.fillRect(L, U, R, D);
g2d.setColor(Color.black);
g2d.fillRect(L, U+size, size, 8);
}else if (map[y][x] == 10){
//on bottom
g2d.setColor(Color.green);
g2d.fillRect(L, U, R, D);
g2d.setColor(Color.black);
g2d.fillRect(L, U-size/2 + 2, size, 8);
g2d.fillRect(L-size/2 +2, U, 8, size );
}else if (map[y][x] == 11){
//on bottom
g2d.setColor(Color.green);
g2d.fillRect(L, U, R, D);
g2d.setColor(Color.black);
g2d.fillRect(L, U+size, size, 8);
}else if (map[y][x] == 12){
//on bottom
g2d.setColor(Color.green);
g2d.fillRect(L, U, R, D);
g2d.setColor(Color.black);
g2d.fillRect(L, U+size, size, 8);
}else if (map[y][x] == 13){
//on bottom
g2d.setColor(Color.green);
g2d.fillRect(L, U, R, D);
g2d.setColor(Color.black);
g2d.fillRect(L, U+size, size, 8);
}
}
}
g.drawImage(TestImage, cordX, cordY,20 , 20, this);
}
public static void main(String[] args) {
try {
new NewTest();
} catch (IOException e) {
e.printStackTrace();
}
}
public void keyPressed(KeyEvent ke) {
switch (ke.getKeyCode()) {
case KeyEvent.VK_RIGHT:
right = true;
break;
case KeyEvent.VK_LEFT:
left = true;
break;
case KeyEvent.VK_DOWN:
down = true;
break;
case KeyEvent.VK_UP:
up = true;
break;
}
updateState();
}
public void keyReleased(KeyEvent ke) {
switch (ke.getKeyCode()) {
case KeyEvent.VK_RIGHT:
right = false;
break;
case KeyEvent.VK_LEFT:
left = false;
break;
case KeyEvent.VK_DOWN:
down = false;
break;
case KeyEvent.VK_UP:
up = false;
break;
}
updateState();
}
protected void updateState() {
if (right) {
cordX += 5;
} else if (left) {
cordX -= 5;
}
if (down) {
cordY += 5;
} else if (up) {
cordY -= 3;
}
if (down && up) {
cordY += 0;
cordX += 0;
}
if (right && left) {
cordX += 0;
cordY += 0;
}
System.out.printf("X:");System.out.println(cordX);
System.out.printf("Y:");System.out.println(cordY);
repaint();
}
public void keyTyped(KeyEvent ke) {
}
}
Thank you for help!

Good approach is to seperate visual and reality model. It means deep in the program, you have your "physics rules" and all objects and based on that model, you draw it.
You can start with creating class like this
public class ObjectInMyGame{
private int posx;
private int posy;
private int width;
private int height;
private Image image;
private int movingX;
private int movingY;
//Note that it is good to use Point or something like that, instead of posx, posy.
}
Then it is good to have some kind of "game controller", which is running your whole world.
public class GameController{
List<ObjectInMyGame> objects;
public updateGame(){
for (ObjectInMyGame object : objects){
object.doSomething(); //sometimes it is good idea to let objects itself do something
}
}
}
So for example, when you move object, you can check, if he collide or not and then decide what to do.

Related

Dijkstra's Algorithm and trouble with A* algorithm

So I have been searching these two algorithms on the Internet and was able to, after days of working on it, get Dijkstra's Algorithm working. From what I have read the two Algorithms are not that different. So I am going to post what I did for Dijkstra's and I was hoping that you can show me or point me into the direction on how to modify it to the A* algorithm.
public Integer processGraph(int graph[][], int algorithm, int s, int d) {
if(algorithm == 1) {
// shortestDist[index] will hold the distance from s to the index
int shortestDist[] = new int[graph.length];
// added[i] is true if vertex index is included / the shortest distance from the source to the index is finalized
boolean added[] = new boolean[graph.length];
// establish all distances as Integer.Max_Value and added[] as false
for (int vertexIndex = 0; vertexIndex < graph.length; vertexIndex++) {
shortestDist[vertexIndex] = Integer.MAX_VALUE;
added[vertexIndex] = false;
}
// Distance of the source from itself is always 0
shortestDist[s] = 0;
// Parent array to store shortest the shortest path -- example: [num, num, num]
int[] parents = new int[graph.length];
// Find shortest path for all vertices
for (int i = 1; i < graph.length; i++) {
// Pick the minimum distance vertex
// from the set of vertices not yet
// processed. nearestVertex is
// always equal to the source in
// first iteration.
int u = minDistance(shortestDist, added);
added[u] = true;
for (int vertexIndex = 0; vertexIndex < graph.length; vertexIndex++) {
if (!added[vertexIndex] && graph[u][vertexIndex] != 0 && shortestDist[u] != Integer.MAX_VALUE && shortestDist[u] + graph[u][vertexIndex] < shortestDist[vertexIndex]) {
shortestDist[vertexIndex] = shortestDist[u] + graph[u][vertexIndex];
parents[vertexIndex] = u;
}
}
}
if(shortestDist[d] == Integer.MAX_VALUE) {
System.out.println(" ");
System.out.println("ERROR MESSAGE -- No path present from " + s + " to " + d);
System.out.println("ERROR MESSAGE --no path present from " + s + " to " + d);
System.out.println(" ");
return null;
}
//pathPrint(s, shortestDist, d); this only works for the first test
return shortestDist[d];
} // end algorithm 1
TO add more context to this, I have a driver class in which with several graphs upon which this finds the shortest path.
Example of graph[][]:
int regValid[][] = {{0, 1, 0, 0, 0, 1, 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, 1, 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, 1, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 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, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 1, 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, 1, 0, 0, 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, 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, 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, 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, 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, 1, 0, 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, 0, 0, 0, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 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, 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, 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, 1, 0, 1},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0}};
Again, how can I modify what I have to work with the A* algorithm instead of Dijkstras. Thank you and hopefully this makes sense.
You have full information about all nodes, edges and destination node, so Dijkstra is the best solution for your problem. A* would be useful if you hadn't known complete graph (most often for huge node space) and were forced to prioritize decisions according to some heuristics.
If you really want to simulate A* on your graph, you have to think out some artificial criterion (heuristics) which describes the estimated distance between given node and target node (in other words, pretend you don't know the path). Since your data set doesn't contain such additional information (and thinking out any satisfying admissibility condition is not trivial), your question doesn't make much sense to me.

2.5D Plane in Slick2D is curved for some reason

I'll readily admit that this code is weird and a pretty unorthodox way of creating anything 2.5D, however if anyone can see what's going on I would appreciate help.
The result of my code is as shown:
I do of course want a totally flat plane, however I'm unsure as to why it curves like so. The code is shown below if anyone has any answers:
public static int width = 640;
public static int height = 480;
private Image image;
private Graphics imageG;
private int mapWidth = 20, mapHeight = 15;
private int[] map;
private float x, y;
public Game(String title)
{
super(title);
}
#Override
public void render(GameContainer gc, Graphics g) throws SlickException
{
imageG.setBackground(Color.black);
imageG.clear();
for (int y = 0; y < mapHeight; y++)
for (int x = 0; x < mapWidth; x++)
{
switch (map[x + y * (mapWidth)])
{
case 0:
imageG.setColor(Color.green);
break;
case 1:
imageG.setColor(Color.yellow);
break;
}
imageG.fillRect(x * 32, y * 32, 32, 32);
}
imageG.flush();
Image frustrum;
for (int i = 0; i < 240; i++)
{
frustrum = image.getSubImage((int) (x - i), (int) (y - i), 32 + 2 * i, 1);
frustrum.draw(0, height - 1 - i, width, 1);
//g.drawImage(frustrum, x - i, y - i);
}
//g.setColor(Color.blue);
//g.fillRect(x, y, 32, 32);
}
#Override
public void init(GameContainer gc) throws SlickException
{
try
{
image = new Image(width, height);
imageG = image.getGraphics();
} catch (SlickException e)
{
e.printStackTrace();
}
/*map = new int[]
{
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
};*/
map = new int[mapWidth * mapHeight];
Random random = new Random();
for (int i = 0; i < map.length; i++)
{
map[i] = random.nextInt(2);
}
x = 10 * 32;
y = 7 * 32;
}
#Override
public void update(GameContainer gc, int delta) throws SlickException
{
if (gc.getInput().isKeyDown(Input.KEY_W)) y--;
if (gc.getInput().isKeyDown(Input.KEY_S)) y++;
if (gc.getInput().isKeyDown(Input.KEY_A)) x--;
if (gc.getInput().isKeyDown(Input.KEY_D)) x++;
}
public static void main(String[] args)
{
try
{
AppGameContainer appgc = new AppGameContainer(new Game("2.5D Game"));
appgc.setDisplayMode(width, height, false);
appgc.start();
} catch (SlickException e)
{
e.printStackTrace();
}
}
This is my first post, so sorry if things look a bit messy. I'm sure I'll get used to it eventually...

how to convert string to collection

I have a string in the below format.
[[115, 1, 0123490, 63824005632, 0036760004, , 01, N, 78, , 7481067028,
122016, 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, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA, OH, 45805, EM, RXRELIEF CARD,
MUCINEX DM 20 0056-32 TAB SA 12HR 600-30MG], [115, 1, 0123490,
63824005632, 0038380001, ,
01, N, 78, , 7481067028, 122016, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA,
OH, 45805, EM, APEX AFFINITY DISCOUNT CARD, MUCINEX DM 20 0056-32 TAB SA
12HR 600-30MG]]
I want to store in collection with each
[115, 1, 0123490, 63824005632, 0038380001, , 01, N, 78, , 7481067028,
122016, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA, OH, 45805, EM, APEX AFFINITY
DISCOUNT CARD, MUCINEX DM 20 0056-32 TAB SA 12HR 600-30MG]
[115, 1, 0123490, 63824005632, 0036760004, , 01, N, 78, , 7481067028,
122016, 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, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA, OH, 45805, EM, RXRELIEF CARD,
MUCINEX DM 20 0056-32 TAB SA 12HR 600-30MG]
How can I split or store in collection?
This should work as long the character ] does not appear as part of a value inside an entry:
public static void main(String[] args) {
String clob = "[[115, 1, 0123490, 63824005632, 0036760004, , 01, N, 78, , 7481067028, 122016, 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, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA, OH, 45805, EM, RXRELIEF CARD, MUCINEX DM 20 0056-32 TAB SA 12HR 600-30MG], [115, 1, 0123490, 63824005632, 0038380001, , 01, N, 78, , 7481067028, 122016, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TABORA, EMMANUEL, J, 4732 WENATCHIE TRL, LIMA, OH, 45805, EM, APEX AFFINITY DISCOUNT CARD, MUCINEX DM 20 0056-32 TAB SA 12HR 600-30MG]]";
List<String> entries = new ArrayList<>();
int start = 1;
while (true) {
start = clob.indexOf("[", start);
int end = clob.indexOf("]", start);
if (start != -1 && end != -1) {
entries.add(clob.substring(start, end + 1));
start = end + 1;
} else {
break;
}
}
}
If you know the escape sequence for characters inside your entries (e.g. \]) you have to check if the found end index represents that escape sequence and if, read again, starting from the end index.
There are many ways to do it. Here’s my suggestion:
public static List<List<String>> stringTo2DList(String input) {
if (input.equals("[]")) {
return Collections.emptyList();
}
if (! input.startsWith("[[")) {
throw new IllegalArgumentException("Not a list of lists");
}
if (! input.endsWith("]]")) {
throw new IllegalArgumentException("Not a list of lists");
}
List<List<String>> result = new ArrayList<>();
String[] innerLists = input.substring(2, input.length() - 2).split("\\], \\[");
for (String innerList : innerLists) {
// check for empty inner list
if (innerList.isEmpty()) {
result.add(Collections.emptyList());
} else {
result.add(Arrays.asList(innerList.split(", ")));
}
}
return result;
}
Should your string contain [], I am interpreting it as an empty list even though it might be a list of one element, the empty string. If you prefer the latter, just skip the check for the empty list in for loop.

Side Collisions

I'm making a tilemap game and I've got the simple collisions down. However to make the game work I have to know which side of the rectangle hit the wall/brick. Just putting a simple collision code inside of the main collision:
if(spriteX < brickX + brickwidth) {}
doesn't work. The main collision code at the moment is:
for(int counter = 0; counter < 31; counter++) {
if(spriteX + 40 >= collisionX[counter] && collisionX[counter] + 100 >= spriteX
&& spriteY + 40 >= collisionY[counter] && collisionY[counter] + 100 >= spriteY) {
velX = 0;
velY = 0;
collisions = counter;
} else {
if(counter == collisions && jumping == false) {
fall();
}
}
}
If you want the entire class:
package Main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class Panel extends JPanel implements Runnable, KeyListener {
// dimensions
public static final int width = 800;
public static final int height = 800;
public static final int scale = 1;
// main loop
private Thread thread;
private boolean running = false;
private int FPS = 60;
private int targetTime = 1000 / FPS;
// drawing
private Graphics2D g;
private BufferedImage image;
int x;
int y;
boolean makeCollision = false;
// sprite
int spriteX = 210;
int spriteY = 200;
int velX = 0;
int velY = 10;
public boolean notOnGround = true;
int counter;
int collisionsCounter;
int jumps = 0;
public int row;
public int column;
public boolean collision;
public boolean jumping = false;
public String side = null;
// tilemap
int[][] map = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 1, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 1, 1},
{1, 0, 0, 0, 1, 1, 0, 1},
{1, 0, 0, 1, 1, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1}
};
int[] collisionX = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
int[] collisionY = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
int[] jump = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
int collisions;
public Panel() {
setPreferredSize(new Dimension(width * scale, height * scale));
setFocusable(true);
requestFocus();
}
public void addNotify() {
super.addNotify();
if(thread == null) {
running = true;
addKeyListener(this);
thread = new Thread(this);
thread.start();
}
}
public void init() {
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D) image.getGraphics();
}
public void update() {
if(spriteY < jump[0]) {
System.out.println(jump[0]);
jumping = false;
fall();
}
}
public void draw() {
g.clearRect(0, 0, WIDTH, HEIGHT);
x = 0;
y = 0;
for(column = 0; column <= 7; column++) {
x = 0;
for(row = 0; row <= 7; row++) {
changeColor(row, column, g);
g.fillRect(x, y, 100, 100);
x = x + 100;
}
y = y + 100;
}
g.setColor(Color.YELLOW);
g.fillRect(spriteX, spriteY, 40, 40);
spriteX += velX;
spriteY += velY;
for(int counter = 0; counter < 31; counter++) {
if(spriteX + 40 >= collisionX[counter] && collisionX[counter] + 100 >= spriteX
&& spriteY + 40 >= collisionY[counter] && collisionY[counter] + 100 >= spriteY){
velX = 0;
velY = 0;
collisions = counter;
} else {
if(counter == collisions && jumping == false) {
fall();
}
}
}
}
public void changeColor(int rowGive, int columnGive, Graphics g) {
if(map[rowGive][columnGive] == 1) {
g.setColor(Color.BLACK);
if(counter < 30) {
collisionX[counter] = x;
collisionY[counter] = y;
}
counter++;
} else {
g.setColor(Color.WHITE);
}
}
public void fall() {
velY = 5;
}
public void drawToScreen() {
Graphics g2 = getGraphics();
g2.drawImage(image, 0, 0, width * scale, height * scale, null);
g2.dispose();
}
public void run() {
init();
long wait;
long elapsed;
long start;
while(running) {
start = System.nanoTime();
update();
draw();
drawToScreen();
elapsed = System.nanoTime() - start;
wait = targetTime - elapsed / 1000000;
if(wait < 0) wait = 5;
try {
thread.sleep(wait);
} catch(Exception e) {
e.printStackTrace();
}
}
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if(code == KeyEvent.VK_RIGHT) {
velX = 5;
}
if(code == KeyEvent.VK_LEFT) {
velX = -5;
}
if(code == KeyEvent.VK_SPACE && jumping == false) {
jumping = true;
velY = -5;
jump[0] = spriteY - 100;
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}}
Let's try to divide the problem a little bit. You don't need to find out when a rectange hit a wall: you need to find when the left side of the rectangle hit the right side of the wall and when the right side of the rectangle hit the left side of the wall.
To be more precise: don't test objects. Divide your object in collision surfaces (left and right sides in your case), find a way to modelize them (usually x and x+width are the left and right side of your rectangle, if x is the x coordinate of your topleft corner). And test both at the same time with an "or" condition.
if(spriteX < brickX + brickwidth || spriteX + spritewidth > brickX) {}
edit Reading your complete class a little more closely, it looks like you do something similar but you use "&&" condition, meaning you can never be true since both side collisions cannot happen at the same time. But I may be wrong, can you tell me ?
While not strictly about your collision problem I've noticed a "bug" in draw() that is causing your map array to be displayed flipped around the -45 angle.
You should be incrementing y when row is incremented and x when column is incremented. Do this and your display will look the same as your map initialization code.
In other words this:
public void draw() {
g.clearRect(0, 0, WIDTH, HEIGHT);
x = 0;
y = 0;
for(column = 0; column <= 7; column++) {
y = 0;
for(row = 0; row <= 7; row++) {
changeColor(row, column, g);
g.fillRect(x, y, 100, 100);
y = y + 100;
}
x = x + 100;
}
...
will make this
int[][] map = {
{1, 1, 1, 1, 1, 1, 1, 1},
{1, 0, 0, 1, 0, 0, 1, 1},
{1, 0, 0, 0, 0, 1, 1, 1},
{1, 0, 0, 0, 1, 1, 0, 1},
{1, 0, 0, 1, 1, 0, 0, 1},
{1, 0, 0, 1, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 1, 1, 1}
};
look like this
instead of this

Multidimensional arrays: Java. How does this code work?

I've been following a tutorial about creating a basic tile-based tower defense game in Java and have encountered a piece of code I cannot wrap my brain around and would like some help. (My main question is at the bottom after the code)
At this point we are iterating through a multidimensional array of 0's and 1's that we pass to a constructor which has a method that assigns a grass tile for 0's and stone tile for 1's and then another method to draw them to the screen creating our game screen. Simple enough, right?
Here is the class:
package data;
import static helpers.Artist.*;
public class TileGrid {
public Tile[][] map;
public TileGrid(int[][] newMap){
map = new Tile[20][15];
for(int i = 0; i < map.length; i++){
for(int j = 0; j <map[i].length; j++){
switch(newMap[j][i]){
case 0:
map[i][j] = new Tile(row * 64, col * 64, 64, 64, TileType.GRASS);
break;
case 1:
map[i][j] = new Tile(row * 64, col * 64, 64, 64, TileType.STONE);
break;
case 2:
map[i][j] = new Tile(row * 64, col * 64, 64, 64, TileType.WATER);
break;
}
}
}
}
public void Draw(){
for(int i = 0; i < map.length; i++){
for(int j = 0; j < map[i].length; j++){
Tile t = map[i][j];
DrawQuadTex(t.getTexture(), t.getX(), t.getY(), t.getWidth(), t.getHeight());
}
}
}
}
And here is the array we are passing in:
int[][] map = { //20 tiles wide, 15 tiles high
{0, 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, 0, 0, 0, 1, 0, 0, 0},
{0, 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, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 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, 0},
{0, 0, 1, 0, 0, 0, 0, 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, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0},
};
So my main question has to do with the switch statement in the constructor for the TileGrid.
Why do the i and the j get switched newMap[j][i] when checking what it equals? I get that this code works, well, because it does and I understand nested for loops to iterate through a multidimensional array.
But why wouldn't newMap[i][j] work?
As well at the very beginning of that same constructor why do we create an array (of type Tile) with the dimension of map = new Tile[20][15] when we are passing in an array with the dimensions of map[15][20]?
I have tried to figure this out and study this on my own and will continue to do so until I understand it but any help would be soooo appreciated!
You are passing to the TileGrid constructor a 2D array of 15 rows and 20 columns, but inside the constructor you create a 2D array of 20 rows and 15 columns. That's why map[i][j] corresponds with newMap[j][i].
If the input int[][] map was also of 20 rows and 15 columns, you wouldn't have to switch the order of the indices inside the constructor.
This would give an index out of bounds error if it was really switched. However, there is a col variable in the second for loop that is not defined anywhere so it's hard to tell what's going on. This code will not compile.
If it is some code pulled off a a tutorial on some web page, I would just assume that it was a typo and continue on with that in mind. OR better yet, contact the author.

Categories