我在世界范围内有一个两个图像(一只猫和一只狗),这是我的Board类。只有当我按下箭头键时,猫才会随机移动,而狗只会移动。我现在的问题是,如果两个图像之间发生碰撞,我怎么能让猫消失?任何答案或想法都将非常感激。
这是我尝试过的......
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 >= right_wall)
{
x = right_wall;
setRandomDirection();
}
if (y > up_wall)
{
y = up_wall;
setRandomDirection();
}
if (x <= left_wall)
{
x = left_wall;
setRandomDirection();
}
if (y < 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;
}
}
我的Cat课程
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 <= left_wall)
{
x = left_wall;
}
if (x >= right_wall)
{
x = right_wall;
}
if (y <= down_wall)
{
y = down_wall;
}
if (y >= 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;
}
}
为我的狗课
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<Sprite> z_sorted_sprites = new ArrayList<Sprite>();
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 < x1_world; x++)
{
for (double y = 0; y < 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 > 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<Long> ticks = new ArrayList<Long>();
/**
* @return the rate for the last second
*/
int add(long tick)
{
ticks.add(0, tick);
if (ticks.size() < 2)
{
return -1;
}
int last = -1;
for (int pos = ticks.size() - 1; pos >= 0; pos--)
{
if (tick - ticks.get(pos) <= SECOND)
{
last = pos;
break;
}
}
while (ticks.size() - 1 > 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);
}
}
}
我的董事会班级
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);
}
我的精灵课
public boolean checkCollisions(java.util.List<Sprite> sprites)
{
Dog dog = this;
Rectangle r1 = dog.getBounds();
for (int i = 0; i < sprites.size(); i++)
{
Rectangle r2 = sprites.get(i).getBounds();
if (r1.intersects(r2))
{
sprites.remove(i);
}
}
return true;
}
答案 0 :(得分:1)
你已经提供了很多代码,但正如Sibbo所说,我没有看到你的checkCollisions
方法在任何地方被调用。它应该被称为游戏的每个循环。
Check out this tutorial,请特别查看gameLoop
类中的Game
方法。当我制作一个需要大量碰撞检测的基于精灵的游戏时,本教程帮助了我很多。
答案 1 :(得分:0)
我实现了检测猫和狗的位置在棋盘类中重叠的方法,因为棋盘是唯一“知道”狗和猫的实例。实现非常简单:比较坐标(类似dog.x + dog.width < cat.x || dog.x > cat.x + cat.width
等等)
如果将来你可以实现更通用的方法,那么如果你想添加鼠标,你将能够重用代码。
答案 2 :(得分:0)
dog类不会覆盖getBounds()方法。因此,每次检查矩形(0,0,0,0)是否相交(例如,3,4,50,50)(如果cat位于(3,4))。
你在哪里调用checkCollision()方法?
修改强>
在Dog类中创建一个类似checkCollision()的方法:
public boolean checkCollision(Sprite s) {...}
当检测到碰撞时,它应该返回true。对于z_sorted_sprites中的每个Sprite,从Board.start()方法调用此方法。如果它返回true,则从列表中删除Sprite。