Okay, so I'm in the progress of making a game, and I need the collisions to work. I have an if() { } else if() {} -statement, but BOTH of them are being called. Here is my code:
Inside my Player Class:
public Rectangle[] tileRect;
public void update() {
tileRect = new Rectangle[Level1.tiles.size()];
for (int w = 0; w < Level1.tiles.size(); w++) {
Tile m = (Tile) Level1.tiles.get(w);
tileRect[w] = m.getBounds();
if(tileRect[w].intersects(getRect())) {
System.out.println("intersecting");
dy = 0;
} else if (!tileRect[w].intersects(getRect())){
dy = 4;
}
}
x += dx;
y += dy;
}
public Rectangle getRect() {
return new Rectangle(x, y, 32, 32);
}
Here is my Tile class (the Level1.tiles is an arrayList of tiles):
package level;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Tile extends Rectangle {
// Defines the id of the tile, used for setting textures.
private static final long serialVersionUID = 1L;
public int id;
// Location
public int x;
public int y;
// Variables for the terrain sprite sheet.
public BufferedImage image;
public String imageLocation;
public BufferedImage[] sprite;
public int rows = 16;
public int collumns = 16;
public int width = 16;
public int height = 16;
public Tile(int idVal, int xPos, int yPos) {
x = xPos * 32;
y = yPos * 32;
id = idVal;
setBounds(x, y, 32, 32);
createImages();
}
public BufferedImage getImage() {
return sprite[id];
}
public void createImages() {
imageLocation = "res/tile/terrain.png";
try {
image = ImageIO.read(new File(imageLocation));
} catch (IOException e) {
System.out.println("Unable to find file " + imageLocation
+ ", printing stack trace!");
e.printStackTrace();
}
sprite = new BufferedImage[rows * collumns];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < collumns; j++) {
sprite[(i * collumns) + j] = image.getSubimage(j * width, i
* height, width, height);
}
}
}
public int getXLoc() {
return x;
}
public int getYLoc() {
return y;
}
public void setX(int xPos) {
x = xPos;
}
public void setY(int yPos) {
y = yPos;
}
}
I'm getting the "intersecting" message in the console, but the player is still falling down (because dy = 4). Please help! I've been trying to solve this all morning...
If and Else cannot both be caught at the same time.
Looks like you are looping through, seeing an intersection, then continuing to loop through regardless.
Try adding a break command to your for loop.
if(tileRect[w].intersects(getRect())) {
System.out.println("intersecting");
dy = 0;
break;
} else if (!tileRect[w].intersects(getRect())){
dy = 4;
}
The break will stop your for loop from continuing and you will exit the loop with dy = 0; rather than going onto the next tile and changing it back to dy = 4;
if and else if cannot be called in the same run. If if condition is true, then any else is never run (not even checked). It's probably different runs. Debug or put a log to see the flow.
Also
if(tileRect[w].intersects(getRect())) {
System.out.println("intersecting");
dy = 0;
} else if (!tileRect[w].intersects(getRect())){
dy = 4;
}
is much simpler written as
if(tileRect[w].intersects(getRect())) {
System.out.println("intersecting");
dy = 0;
} else {
dy = 4;
}
Related
Hi all so I a tank war game thats ran over a network and is multiplayer, however whenever I fire a bullet it shows on my screen but not the other player's screen. Can you help, here's a snippet of code form where i think the problem is coming from:
class Tank implements Ball {
double locX, locY, radius, angle;
int self; // index of this tank in WarPanel.tanks
public boolean turnL, turnR, forth, back, fire;
boolean prevtL, prevtR, prevfo;
Color color;
Image image;
public static final double twoPi = Math.PI * 2.0;
public static final double turnRate = Math.PI / 8;
public static final double speed = 4.0;
public static final int RELOAD = 8; // delay between bullets
int count; // timer for reloading
public static final int MAXBULLETS = 7; // max simultaneous shots
Bullet bullets[] = new Bullet[MAXBULLETS];
AffineTransform saveAT; // place to hold current affine transform
public Tank(double x, double y, double a, int index, Image im){
locX = x;
locY = y;
angle = a;
self = index;
image = im;
radius = 22;
// create bullets for this tank
for (int i = 0; i < bullets.length; i++)
bullets[i] = new Bullet(self);
}
public double getX() { return locX; }
public double getY() { return locY; }
public double getRadius() { return radius; }
public boolean isAlive() { return true; }
void update(Boolean local) {
if (turnL)
turnLeft(turnRate);
if (turnR)
turnRight(turnRate);
if (forth){
moveForward();
// Check for rocks
if (WarPanel.hitAnItem(this, WarPanel.rocks) >= 0)
backUp();
}
if (local){
if (turnL != prevtL){
WarPanel.send("turnL "+turnL+" "+locX+" "+locY+" "+angle);
prevtL = turnL;
}
if (turnR != prevtR){
WarPanel.send("turnR "+turnR+" "+locX+" "+locY+" "+angle);
prevtR = turnR;
}
if (forth != prevfo){
WarPanel.send("forth "+forth+" "+locX+" "+locY+" "+angle);
prevfo = forth;
}
}
if (fire){
fireBullet();
}
// Update all of our bullets
for (Bullet b: bullets)
b.update();
}
public void processMove(String s){
// Update movement parameters based on s
Scanner sc = new Scanner(s);
// Get the flag change
String command = sc.next();
boolean value = sc.nextBoolean();
if (command.equals("turnL"))
turnL = value;
else if (command.equals("turnR"))
turnR = value;
else if (command.equals("forth"))
forth = value;
else
System.out.println("Unexpected move: "+command);
// then unpack position update
locX = sc.nextDouble();
locY = sc.nextDouble();
angle = sc.nextDouble();
}
void paint(Graphics g){
// Use the affine transform feature in Graphics2D
// to easily rotate the tank's image.
Graphics2D g2 = (Graphics2D)g;
saveAT = g2.getTransform();
g2.translate(locX, locY);
g2.rotate(angle);
g2.drawImage(image, (int)(-radius), (int)(-radius), null);
// Reset the transform (this is important)
g2.setTransform(saveAT);
// Then draw bullets
for (Bullet b: bullets)
b.paint(g2);
}
void fireBullet(){
// If it has been long enough since the last shot...
count--;
if (count > 0) return;
// ...and if all the bullets aren't currently in use...
int slot = getAvailableBullet();
if (slot < 0)
return;
// ...then launch a new bullet
bullets[slot].setLocation(locX, locY);
bullets[slot].setDirection(angle);
bullets[slot].reset();
// Reset the timer
count = RELOAD;
}
int getAvailableBullet(){
for (int i = 0; i < bullets.length; i++)
if (!bullets[i].isAlive())
return i;
return -1;
}
void turnRight(double a){
angle += a;
if (angle > twoPi)
angle -= twoPi;
}
void turnLeft(double a){
angle -= a;
if (angle < 0.0)
angle += twoPi;
}
void moveForward(){
locX += speed*Math.cos(angle);
locY += speed*Math.sin(angle);
}
void backUp(){
locX -= speed*Math.cos(angle);
locY -= speed*Math.sin(angle);
}
}
im really new in Java. I just need to explain how to declare 2D array of objects, i have something like:
package breakout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
public class Breakout extends JPanel {
public class Ball {
private
int x = 400;
int y = 300;
int speed = 2;
int dirx = 1;
int diry = -1;
public
void bounce(int px, int py, int lx, int ly) {
if ((x + 10 >= 800 && dirx == 1) || (x <= 0 && dirx == -1))
dirx *= -1;
if (y <= 0 && diry == -1)
diry *= -1;
if (y + 10 >= py && y <= py + ly && diry == 1 && x + 10 >= px && x <= px + lx)
diry *= -1;
}
int getX() {
return x;
}
int getY() {
return y;
}
void setDirx(){
dirx *= -1;
}
void setDiry(){
diry *= -1;
}
void move() {
x += speed*dirx;
y += speed*diry;
}
void paint(Graphics2D g) {
g.fillOval(x,y,10,10);
}
}
public class Paddle {
private
int x = 400;
int y = 520;
int width = 100;
int height = 6;
int speed = 6;
int dirL = 0;
int dirR = 0;
public
void move() {
x -= speed*dirL;
x += speed*dirR;
}
void stop() {
if (x <= 0)
x = 0;
if (x + width >= 800)
x = 800 - width;
}
int getX() {
return x;
}
int getY() {
return y;
}
int getWidth() {
return width;
}
int getHeight() {
return height;
}
void paint(Graphics2D g) {
g.fillRect(x,y,width,height);
}
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT)
dirL = 0;
else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
dirR = 0;
else {
dirL = 0;
dirR = 0;
}
}
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()) {
case KeyEvent.VK_LEFT:
dirL = 1;
break;
case KeyEvent.VK_RIGHT:
dirR = 1;
break;
}
}
}
public class Brick {
private
int x;
int y;
int width;
int height;
boolean alive;
boolean inX = false,inY = false;
public
void setUpBrick(int px, int py, int w, int h, boolean al) {
x = px;
y = py;
width = w;
height = h;
alive = al;
}
void setAlive(boolean alive) {
this.alive = alive;
}
void paint(Graphics2D g) {
if (alive)
g.fillRect(x,y,width,height);
}
boolean collision(int bx, int by) {
if (alive) {
if (bx + 10 >= x && bx <= x + width && by + 10 >= y && by <= y + height) {
setAlive(false);
return true;
} else return false;
}
else return false;
}
void inAreaX(int bx) {
if (bx + 10 >= x && bx <= x + width) {
System.out.println("inAreaX");
inX = true;
} else {
inX = false;
}
}
void inAreaY(int by) {
if (by + 10 >= y && by <= y + height) {
System.out.println("inAreaY");
inY = true;
} else {
inY = false;
}
}
boolean isInAreaX () {
if (inX)
return true;
else return false;
}
boolean isInAreaY () {
if (inY)
return true;
else return false;
}
}
Ball ball = new Ball();
Paddle paddle = new Paddle();
Brick[][] brick = new Brick[8][4];
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 4; j++) {
brick[i][j].setUpBrick(j * 101, i * 51, 100, 50, true);
}
}
void bounce() {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 4; j++) {
brick[i][j].inAreaX(ball.getX());
brick[i][j].inAreaY(ball.getY());
if (brick[i][j].collision(ball.getX(), ball.getY())) {
if (brick[i][j].isInAreaX()) {
ball.setDiry();
} else if (brick[i][j].isInAreaY()) {
ball.setDirx();
}
}
}
}
}
void move() {
ball.bounce(paddle.getX(), paddle.getY(), paddle.getWidth(),paddle.getHeight());
ball.move();
paddle.move();
paddle.stop();
bounce();
}
public Breakout() {
addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
paddle.keyReleased(e);
}
public void keyPressed(KeyEvent e) {
paddle.keyPressed(e);
}
});
setFocusable(true);
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.RED);
ball.paint(g2d);
g2d.setColor(Color.BLACK);
paddle.paint(g2d);
g2d.setColor(Color.ORANGE);
for (int i = 0; i < 8; i++)
for (int j = 0; j < 4; j++)
brick[i][j].paint(g2d);
}
public static void main(String[] args) throws InterruptedException {
JFrame window = new JFrame("Tennis");
Breakout game = new Breakout();
window.add(game);
window.setSize(800,600);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
game.move();
game.repaint();
Thread.sleep(10);
}
}
i need to inicialize 2d array of brick, but it says that first for is unexpected token. How to write it? Thank you.
Unless if I have miscounted your opening and closing braces, your for loop is not inside any method, it's directly in your class body. That's why you're getting unexpected token. You will probably want to move it into the Breakout constructor.
In order to create a 2D array in Java, you can create such an array like this:
Object testArray = new Object[10][10];
This array is now a 10*10 array with memory allocated for 100 Object references.
You can create pointers two Objects with a double for-loop:
for (int i = 0; i < testArray.length(); i++) {
for (int j = 0; j < testArray.length; j++) {
testArray[i][j] = Object; //here you input the objects that you want to point to
}
}
Move the logic from setUpBrick to a constructor.
public class Brick {
private int x;
private int y;
private int width;
private int height;
private boolean alive;
private boolean inX = false,inY = false;
public Brick(int px, int py, int w, int h, boolean al) {
x = px;
y = py;
width = w;
height = h;
alive = al;
}
...
}
Then change
brick[i][j].setUpBrick(j * 101, i * 51, 100, 50, true);
to
brick[i][j] = new Brick(j*101, i*51, 100, 50, true);
Also note that access modifiers don't apply to a whole section of your class. In your example,
private
int x;
int y;
int width;
int height;
boolean alive;
boolean inX = false,inY = false;
means that only x is going to be private. The rest of the members will get the default access modifier.
One more tip. A couple of your methods can be simplified.
boolean isInAreaY () {
if (inY)
return true;
else return false;
}
can be written as:
boolean isInAreaY() {
return inY;
}
I am designing a simple java 2d game.where an aircraft shoots missiles and they hit alien ships.(pictures are attached for a better understanding).
Now I need to detect when the missile hits the alien ship. So as to count the number of total hits. I used the rectangle1.intersects(rec2)method, but instead of giving me an integer 1 as the answer (after the boolean of course) it gives me some funny answer. I guess like how much the two rectangles intersect...
Also when adding new aliens in an arraylist I use the following: I add new aliens every two seconds, but this slows down the game very much.
So please guide me on these two issues.
There is a game class (contains the main frame), board class (the panel on which I draw) alient, missile and craft class. Below I am giving the the actionPerformed() of the panel class which gets called by a timer every 2ms (the rest of the code is below).
///CODE TO BE FOCUSED ON
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
public class game extends JFrame {
static long z;
game()
{
add(new board());
setBounds(0, 0, 500, 500);
setVisible(true);
setLayout(null);
setLocationRelativeTo(null);
setTitle("\t\t...................::::~~~~'S GAME~~~~:::::...............");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new game();
z = System.currentTimeMillis();
}
}
class board extends JPanel implements ActionListener
{
Timer t = new Timer(5, this);
public ArrayList alien_list;
craft craft_list = new craft();
Label l = new Label();
int total_hits = 0;
public board() {
setFocusable(true);
setLayout(null);
setDoubleBuffered(true);
setBackground(Color.BLACK);
addKeyListener(craft_list);
l.setBounds(0, 0, 150, 30);
l.setBackground(Color.GREEN);
add(l);
t.start();
alien_list = new ArrayList();
alien_list.add(new alien(0, 100));
alien_list.add(new alien(0, 150));
alien_list.add(new alien(0, 200));
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g1 = (Graphics2D) g;
long z = (System.currentTimeMillis() - game.z) / 1000;
if (z >= 60)
{
remove(l);
g.setColor(Color.red);
g1.drawString("time up", 100, 100);
} else
{
g1.drawImage(craft_list.getImage(), craft_list.getX(),
craft_list.getY(), null);
ArrayList a = craft_list.getmissile();
for (int i = 0; i < a.size(); i++) {
missile m = (missile) a.get(i);
g1.drawImage(m.getImage(), m.getX(), m.getY(), null);
}
l.setText("time elapsed:" + " " + +z + " " + "hits:" + " "
+ total_hits);
for (int i = 0; i < alien_list.size(); i++) {
alien m = (alien) alien_list.get(i);
g1.drawImage(m.getImage(), m.getX(), m.getY(), null);
}
}
}
public void actionPerformed(ActionEvent e) {
ArrayList a = craft_list.getmissile();
for (int i = 0; i < a.size(); i++) {
missile m = (missile) a.get(i);
if (m.visible == true)
m.move();
else
a.remove(i);
}
long z = (System.currentTimeMillis() - game.z) / 1000;
if (z % 3 == 0)
alien_list.add(new alien(-10, 100));
for (int j = 0; j < alien_list.size(); j++) {
alien m = (alien) alien_list.get(j);
if (m.visible == true)
m.move();
else
alien_list.remove(j);
}
craft_list.move();
collison();
repaint();
}
public void collison() {
ArrayList a = craft_list.getmissile();
for (int i = 0; i < a.size(); i++) {
missile m = (missile) a.get(i);
Rectangle r1 = m.getBounds();
for (int j = 0; j < alien_list.size(); j++) {
alien l = (alien) alien_list.get(j);
Rectangle r2 = l.getBounds();
if (r1.intersects(r2)) {
total_hits++;
m.setVisible(false);
l.setVisible(false);
}
}
}
}
}
class craft extends KeyAdapter
{
int x = 250;
int y = 400;
ArrayList m = new ArrayList();
Image i;
int dx, dy;
craft() {
ImageIcon i1 = new ImageIcon("1a.jpg");
i = i1.getImage();
}
public Image getImage() {
return i;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void move() {
x += dx;
y += dy;
if (x < 0)
x = 0;
if (x > 450)
x = 450;
if (y > 420)
y = 420;
if (y < 200)
y = 200;
}
public void keyPressed(KeyEvent k)
{
int key = k.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
fire();
}
if (key == KeyEvent.VK_LEFT) {
dx = -1;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 1;
}
if (key == KeyEvent.VK_UP) {
dy = -1;
}
if (key == KeyEvent.VK_DOWN) {
dy = 1;
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = 0;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 0;
}
if (key == KeyEvent.VK_UP) {
dy = 0;
}
if (key == KeyEvent.VK_DOWN) {
dy = 0;
}
}
public void fire() {
m.add(new missile(getX() + 13, getY() - 6));
}
public ArrayList getmissile() {
return m;
}
public Rectangle getBounds() {
return new Rectangle(x, y, i.getWidth(null), i.getHeight(null));
}
}
class missile {
Image i;
int x, y;
public boolean visible;
missile(int x, int y) {
this.x = x;
this.y = y;
visible = true;
ImageIcon i1 = new ImageIcon("1c.jpg");
i = i1.getImage();
}
public Image getImage() {
return i;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void move() {
y--;
if (y < 0)
visible = false;
}
public Rectangle getBounds() {
return new Rectangle(x, y, i.getWidth(null), i.getHeight(null));
}
public void setVisible(boolean t) {
this.visible = t;
}
}
class alien {
Image i;
int x, y;;
public boolean visible;
public alien(int x, int y)
{
this.x = x;
this.y = y;
ImageIcon i1 = new ImageIcon("b.jpg");
i = i1.getImage();
visible = true;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImage() {
return i;
}
public void move() {
x++;
if (x > 500)
visible = false;
}
public Rectangle getBounds() {
return new Rectangle(x, y, i.getWidth(null), i.getHeight(null));
}
public void setVisible(boolean t) {
this.visible = t;
}
}
Ok, your code format is kind of unreadable and invites everybody to oversee otherwise obvious bugs. That is what I have seen so far for your performance issue:
getBounds() creates a new Rectangle instance every time it gets called. You should update the bounds rectangle at the last line of your move() and just return the rectangle instance instead of creating a new one.
Reuse Image or ImageIcon objects. There is no need to load the same jpg file over and over again in a constructor. Make it static or use a image cache.
Instead of o++ in fire() you should use o = m.size(). Mainly because you never call o--, you only remove the rocket from the ArrayList.
And at that point everybody loses track of what o and m means. Name your variables better! o should be amountOfRockets and m should be listOfRockets.
When you use Eclipse, press ctrl + shift + f to format the code which I highly recommend. After that go through your code and name the variables correctly. That means you should give them a descriptive name. And finally: let the name of your classes start with an upper case.
Very likely that this will not yet remove all issues but it will at least help us to understand and read your code easier... which might lead us to a solution...
Update:
You still haven't done 1. and 2. I suggested but you did 3.
Here is what 1. should be as a sample for the Alien class:
private Rectangle bounds
//constructor
Alien() {
// your stuff and the bounds:
bounds = new Rectangle(x, y, i.getWidth(null), i.getHeight(null));
}
public void move() {
bounds.x++;
if (bounds.x > 500)
visible = false;
}
public Rectangle getBounds() {
return bounds;
}
You need to implement that for the Rocket class as well.
What I still don't get is where you remove the old Alien objects. Just setting their visibility is not enough. You should remove them from the list of your Alien objects. Otherwise you will loop through objects that are not there anymore.
I've made this code that successfully creates a 16x12 grid by 50x50 squares on a 800x600px board.
As you can see, the player moves to the coordinates of the players mouseclick.
Each square of the grid has an object of Felt (field) on it, which can be laast (locked). If a fields lock attribute is set to 1, the player should not be moved to that position.
How do i detect the field a player tries to move on to achieve this?
public class SimpleGame extends BasicGame{
private Image plane;
private float planeX;
private float planeY;
public SimpleGame()
{
super("SpilTest");
}
#Override
public void init(GameContainer gc) throws SlickException {
plane = new Image("figur.png");
}
#Override
public void update(GameContainer gc, int delta) throws SlickException {
Input input = gc.getInput();
if (input.isMousePressed(input.MOUSE_LEFT_BUTTON)) {
this.planeX = input.getMouseX() - 30;
this.planeY = input.getMouseY() - 50;
}
}
public void render(GameContainer gc, Graphics g) throws SlickException {
Felt board[][] = nytGrid();
int distancex = 0;
int distancey = 0;
int counter = 0;
for (int i=0; i < board.length ; i++) {
for (int j=0; j < board[i].length ; j++) {
if (board[i][j].getLaast() == 1) {
g.setColor(Color.red);
g.fillRect(distancex, distancey, 50, 50);
}
distancex += 50;
counter++;
if (counter == 16) {
distancey += 50;
distancex = 0;
counter = 0;
}
}
}
g.drawImage(plane, planeX, planeY);
}
public static void main(String[] args) throws SlickException {
AppGameContainer app = new AppGameContainer(new SimpleGame());
app.setDisplayMode(800, 600, false);
app.setTargetFrameRate(60);
app.start();
}
public Felt[][] nytGrid() {
Felt [][] board = new Felt[16][12];
for (int i=0; i < board.length ; i++) {
for (int j=0; j < board[i].length ; j++) {
int x = i;
int y = j;
board[i][j] = new Felt(x, y);
if (i == 5 && j == 5) {
board[i][j].setLaast(1);
}
}
}
return board;
}
}
First off, you should probably initialize the board in the init() method instead of render, so it doesn't have to do it every frame, and move the declaration for the grid next to the plane, planeX and planeY declarations in the class.
Now to disable movement into a locked square, first add a method to check if a square at certain coordinates is locked, so something along the lines of:
private boolean isLocked(int x, int y) {
int square = board[x/50][y/50];
if (square == 1) return true;
else return false;
}
Next modify the part of your update() method where you update the plane coordinates, so vaguely something like:
if (input.isMousePressed(input.MOUSE_LEFT_BUTTON)) {
int destX = input.getMouseX() - 30;
int destY = input.getMouseY() - 50;
if (!isLocked(destX, destY)) {
this.planeX = destX;
this.planeY = destY;
}
}
It's easy!
int mx = Mouse.getX();
int my = Mouse.getY();
But, it gives you the world cordinates, and you have to translate it to pixels:
int mx = Mouse.getX();
int my = Mouse.getY() * -1 + (Window.WIDTH / 2) + 71;
I am trying to do mouse picking and the tile I click on changes to whatever the opposite tile is ie. grass to dirt, but every grass tile has the same "ID" so every grass tile on the screen changes to dirt. How can I go about generating these tiles in a better way? I want it to be randomly generated and not drawn from an array map of like 000001100.
Block class
public class Block {
public enum BlockType {
Dirt,
Grass,
Selection
}
BlockType Type;
Vector2f Position;
Image texture;
boolean breakable;
public Block(BlockType Type, Vector2f Position, Image texture, boolean breakable) {
this.Type = Type;
this.Position = Position;
this.texture = texture;
this.breakable = breakable;
}
public BlockType getType() {
return Type;
}
public void setType(BlockType value) {
Type = value;
}
public Vector2f getPosition() {
return Position;
}
public void setPosition(Vector2f value) {
Position = value;
}
public Image gettexture() {
return texture;
}
public void settexture(Image value) {
texture = value;
}
public boolean getbreakable() {
return breakable;
}
public void setbreakable(boolean value) {
breakable = value;
}
}
Tile Generation Class
public class TileGen {
Block block;
public Block[] tiles = new Block[2];
public int width, height;
public int[][] index;
boolean selected;
int mouseX, mouseY;
int tileX, tileY;
Image dirt, grass, selection;
SpriteSheet tileSheet;
public void init() throws SlickException {
tileSheet = new SpriteSheet("assets/tiles/tileSheet.png", 64, 64);
grass = tileSheet.getSprite(0,0);
dirt = tileSheet.getSprite(1,0);
selection = tileSheet.getSprite(2,0);
tiles[0] = new Block(BlockType.Grass, new Vector2f(tileX,tileY), grass, true);
tiles[1] = new Block(BlockType.Dirt, new Vector2f(tileX,tileY), dirt, true);
width = 50;
height = 50;
index = new int[width][height];
Random rand = new Random();
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
index[x][y] = rand.nextInt(2);
}
}
}
public void update(GameContainer gc) {
Input input = gc.getInput();
mouseX = input.getMouseX();
mouseY = input.getMouseY();
tileX = mouseX / width;
tileY = mouseY / height;
if(input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON)) {
selected = true;
}
else{
selected = false;
}
System.out.println(tiles[index[tileX][tileY]]);
}
public void render() {
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
{
tiles[index[x][y]].texture.draw(x * 64, y *64);
if(IsMouseInsideTile(x, y))
selection.draw(x * 64, y * 64);
if(selected && tiles[index[x][y]].breakable) {
if(tiles[index[tileX][tileY]].Type == BlockType.Grass)
tiles[index[tileX][tileY]].texture = dirt;
}
}
}
}
public boolean IsMouseInsideTile(int x, int y)
{
return (mouseX >= x * 64 && mouseX <= (x + 1) * 64 &&
mouseY >= y * 64 && mouseY <= (y + 1) * 64);
}
I am using slick2d library. I'm not sure if ID is the right word, but I hope you can understand what I am trying to ask.
It looks like your existing structure is fine, but it doesn't look like you understand what it does. The int[][] index array holds a grid of tile types, corresponding to x and y coordinates. To change the tile type at a particular coordinate, all you need to do is set the index array to the type you want.
Specifically, in your render function, you would have something like:
if(IsMouseInsideTile(x, y) && selected && tiles[index[x][y]].breakable)
if(tiles[index[tileX][tileY]].Type == BlockType.Grass)
tiles[index[tileX][tileY]].texture = dirt;
I'd try to figure out exactly what the code you have is doing before modifying it further.
Note: why is this in the render function anyways? You should probably have it in its own function or at least inside your update function.