Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to detect a collision?
    text
    copied!<p>I'm having a two image(a cat and a dog) inside the world which is in my Board class. The cat moves in a random direction while the dog move only when I press the arrow keys. My problem now is that how can I make the cat disappear whenever there is a collision between the two images? Any answer or idea would be much appreciated.</p> <p>Here's what I've tried...</p> <pre><code>public class Cat extends Sprite implements ImageObserver { private java.awt.Image catImage; private final Board board; private double x; private double y; private double speed; private double angle; private boolean visible; public Cat(Board board, double x, double y, double speed) { this.board = board; this.x = x; this.y = y; this.speed = convertToMeterPerSecond(speed); visible = true; URL iU = this.getClass().getResource("cat.gif"); ImageIcon icon = new ImageIcon(iU); catImage = icon.getImage(); } public Image getImage() { return catImage; } public void move(long dt) { double dt_s = dt / 1e9; double dx_m = speed * dt_s * Math.sin(angle); double dy_m = speed * dt_s * Math.cos(angle); final double right_wall = board.x1_world; final double up_wall = board.y1_world; final double down_wall = 0.0; final double left_wall = 0.0; x += dx_m; y += dy_m; if (x &gt;= right_wall) { x = right_wall; setRandomDirection(); } if (y &gt; up_wall) { y = up_wall; setRandomDirection(); } if (x &lt;= left_wall) { x = left_wall; setRandomDirection(); } if (y &lt; down_wall) { y = down_wall; setRandomDirection(); } } public void setRandomDirection() { Cat myObject = this; myObject.setAngle(Math.PI * 2 * Math.random()); } @Override public void render(Graphics2D g2d) { AffineTransform t = g2d.getTransform(); double height = 0.3; //meter double width = 0.3; //meter double cat_footy = height; double cat_footx = width / 2; int xx = board.convertToPixelX(x - cat_footx); int yy = board.convertToPixelY(y + cat_footy); g2d.translate(xx, yy); double x_expected_pixels = width * board.meter; double y_expected_pixels = height * board.meter; double x_s = x_expected_pixels / ((ToolkitImage) catImage).getWidth(); double y_s = y_expected_pixels / ((ToolkitImage) catImage).getHeight(); double w = ((ToolkitImage) catImage).getWidth(); double h = ((ToolkitImage) catImage).getHeight(); g2d.scale(x_s, y_s); g2d.drawImage(getImage(), 0, 0, this); // upper left corner g2d.setColor(Color.BLACK); g2d.drawRect(0, 0, (int) w, (int) h); g2d.setTransform(t); } public void moveAt(double distance_x, double distance_y) { this.x = (int) distance_x; this.y = (int) distance_y; } @Override public Rectangle getBounds() { double w = ((ToolkitImage) catImage).getWidth(); double h = ((ToolkitImage) catImage).getHeight(); return new Rectangle((int) x, (int) y, (int) w, (int) h); } public void setAngle(double angle) { this.angle = angle; } public boolean isVisible() { return visible; } public void setVisible(Boolean visible) { this.visible = visible; } @Override public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { return true; } } </code></pre> <p>for my Cat class</p> <pre><code>public class Dog extends Sprite implements ImageObserver { private java.awt.Image humanImage; private final Board board; private double x; private double y; private double speed; private boolean visible; private double angle; private double dx_m; private double dy_m; public Dog(Board board, double x, double y, double speed) { this.board = board; this.x = x; this.y = y; this.speed = convertToMeterPerSecond(speed); visible = true; URL iU = this.getClass().getResource("dog.jpg"); ImageIcon icon = new ImageIcon(iU); dogImage = icon.getImage(); } public Image getImage() { return dogImage; } public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if (key == KeyEvent.VK_LEFT) { dx_m = -0.3; } if (key == KeyEvent.VK_RIGHT) { dx_m = 0.3; } if (key == KeyEvent.VK_UP) { dy_m = 0.3; } if (key == KeyEvent.VK_DOWN) { dy_m = -0.3; } } public void keyReleased(KeyEvent e) { int key = e.getKeyCode(); if (key == KeyEvent.VK_LEFT) { dx_m = 0; } if (key == KeyEvent.VK_RIGHT) { dx_m = 0; } if (key == KeyEvent.VK_UP) { dy_m = 0; } if (key == KeyEvent.VK_DOWN) { dy_m = 0; } } @Override public void move(long dt) { double dt_s = dt / 1e9; final double right_wall = board.x1_world; final double up_wall = board.y1_world; final double down_wall = 0.0; final double left_wall = 0.0; x += dx_m; y += dy_m; if (x &lt;= left_wall) { x = left_wall; } if (x &gt;= right_wall) { x = right_wall; } if (y &lt;= down_wall) { y = down_wall; } if (y &gt;= up_wall) { y=up_wall; } } public void setRandomDirection() { Dog myObject = this; myObject.setAngle(Math.PI * 2 * Math.random()); } @Override public void render(Graphics2D g2d) { AffineTransform t = g2d.getTransform(); final double dogHeight = 1.6;// meter final double dogWidth = 1.8; //meter final double foot_position_y = dogHeight; final double foot_position_x = dogWidth / 2; int xx = board.convertToPixelX(x - foot_position_x); // to find the upper-left corner int yy = board.convertToPixelY(y + foot_position_y); // to find the upper-left corner g2d.translate(xx, yy); // ratio for actual Image size double x_expected_pixels = dogHeight * board.meter; double y_expected_pixels = dogWidth * board.meter; double w = ((ToolkitImage) dogImage).getWidth(); double h = ((ToolkitImage) dogImage).getHeight(); double x_s = x_expected_pixels / w; double y_s = y_expected_pixels / h; g2d.scale(x_s, y_s); g2d.drawImage(getImage(), 0, 0, this); // upper left corner g2d.setColor(Color.BLACK); g2d.drawRect(0, 0, (int) w, (int) h); g2d.setTransform(t); } @Override public void moveAt(double distance_x, double distance_y) { this.x = distance_x; this.y = distance_y; } public void setAngle(double angle) { this.angle = angle; } @Override public Rectangle getBounds() { double width = ((ToolkitImage) dogImage).getWidth(); double height = ((ToolkitImage) dogImage).getHeight(); return new Rectangle((int) x, (int) y, (int) width, (int) height); } public boolean isVisible() { return visible; } public void setVisible(Boolean visible) { this.visible = visible; } @Override public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) { return true; } } </code></pre> <p>for my Dog class</p> <pre><code>public class Board extends Canvas { private Cat cat; public static final long SECOND = 1000 * 1000 * 1000; public double meter;//PIXEL private HumanBeing humanBeing; /** * ascending from 0 to N * 0 : most far way... * N : is the closest (painted the last) */ private final java.util.List&lt;Sprite&gt; z_sorted_sprites = new ArrayList&lt;Sprite&gt;(); private BufferStrategy strategy; int x0_pixel; int y0_pixel; int x1_pixel; int y1_pixel; double x1_world; double y1_world; private final Frame frame; public Board(Frame frame, double meter) { addKeyListener(new TAdapter()); this.frame = frame; this.setIgnoreRepaint(true); this.meter = meter; setFocusable(true); dog = new Dog(this, 5, 5, 40); init(); addComponentListener(new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { render(); } }); } public void init() { z_sorted_sprites.add(new Cat(this, 0, 0, 30)); z_sorted_sprites.add(new Cat(this, 1, 1, 10)); z_sorted_sprites.add(new Cat(this, 2, 2, 20)); z_sorted_sprites.add(new Cat(this, 3, 3, 100)); } public void render() { setupStrategy(); x0_pixel = 0; y0_pixel = 0; x1_pixel = getWidth(); y1_pixel = getHeight(); x1_world = x1_pixel / meter; y1_world = y1_pixel / meter; Graphics2D g2d = (Graphics2D) strategy.getDrawGraphics(); g2d.setBackground(Color.lightGray); g2d.clearRect(0, 0, x1_pixel, y1_pixel); g2d.setColor(Color.BLACK); for (double x = 0; x &lt; x1_world; x++) { for (double y = 0; y &lt; y1_world; y++) { int xx = convertToPixelX(x); int yy = convertToPixelY(y); g2d.drawOval(xx, yy, 2, 2); } } for (Sprite z_sorted_sprite : z_sorted_sprites) { z_sorted_sprite.render(g2d); } dog.render(g2d); g2d.dispose(); strategy.show(); Toolkit.getDefaultToolkit().sync(); } public int convertToPixelX(double distance) { return (int) (distance * meter); } public int convertToPixelY(double y_world) { return (int) (y1_pixel - (y_world * meter)); } public void onZoomUpdated(int value) { meter = value; render(); } private void setupStrategy() { if (strategy == null) { this.createBufferStrategy(2); strategy = this.getBufferStrategy(); } } public void start() throws InterruptedException { long prevLoopStart = System.nanoTime(); Avg avg = new Avg(); while (true) { final long loopStart = System.nanoTime(); final long dt = loopStart - prevLoopStart; for (Sprite sprite : z_sorted_sprites) { sprite.move(dt); } dog.move(dt); render(); frame.onFpsUpdated(1.0 / dt * SECOND, avg.add(loopStart)); final long elapsed_ns = System.nanoTime() - loopStart; long expected_elapsed_ms = 1000 / 60; long elapsed_ms = (long) (elapsed_ns / (1000.0 * 1000.0)); long sleep_ms = expected_elapsed_ms - elapsed_ms; if (sleep_ms &gt; 0) { Thread.sleep(sleep_ms /* ms */); } prevLoopStart = loopStart; } } private void checkCollision() { Rectangle r2 = cat.getBounds(); Rectangle r3 = dog.getBounds(); if (r3.intersects(r2)) { dog.setVisible(false); cat.setVisible(false); } } static class Avg { java.util.List&lt;Long&gt; ticks = new ArrayList&lt;Long&gt;(); /** * @return the rate for the last second */ int add(long tick) { ticks.add(0, tick); if (ticks.size() &lt; 2) { return -1; } int last = -1; for (int pos = ticks.size() - 1; pos &gt;= 0; pos--) { if (tick - ticks.get(pos) &lt;= SECOND) { last = pos; break; } } while (ticks.size() - 1 &gt; last) { ticks.remove(ticks.size() - 1); } return ticks.size(); } } private class TAdapter extends KeyAdapter { public void keyReleased(KeyEvent e) { dog.keyReleased(e); } public void keyPressed(KeyEvent e) { dog.keyPressed(e); } } } </code></pre> <p>For my Board class</p> <pre><code>public abstract class Sprite { public Sprite() { } public Rectangle getBounds() { return new Rectangle(); } public static double convertToMeterPerSecond(double speed) { // 25 km / hour // 25000 m / 3600 s return speed / 3.6; } public abstract void move(long dt); public abstract void moveAt(double distance_x, double distance_y); public abstract void render(Graphics2D g2d); public abstract void setVisible(Boolean visible); } </code></pre> <p>For my sprite class</p> <pre><code>public boolean checkCollisions(java.util.List&lt;Sprite&gt; sprites) { Dog dog = this; Rectangle r1 = dog.getBounds(); for (int i = 0; i &lt; sprites.size(); i++) { Rectangle r2 = sprites.get(i).getBounds(); if (r1.intersects(r2)) { sprites.remove(i); } } return true; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload