java画图画球循环,Java球对象不像它应该的那样从绘制的矩形反弹.

抱歉这个糟糕的头衔. Java applet的目的是这样的:一个球在屏幕上弹跳.这个球的大小和速度可以通过滚动条改变.用户可以在屏幕上按下并拖动鼠标以绘制矩形.球也将从这些矩形反弹.这些矩形的边界存储在矢量中.单击矩形时,将从矢量(和屏幕)中删除它(以及该点处的所有其他矩形).

我遇到的问题有两个:一,当我点击一个矩形去除它时,它不会被删除,但这可以在以后解决.

二:球不会像它应该的那样从矩形反弹.当我在与球相同的行或列中绘制一个矩形时,球会在一个小矩形内部反弹,就像它被卡住一样.

这是我的代码,用于检测球是否正在击中小程序或任何矩形的边界:

public void move()

{

//if it will hit the right or left boundary, flip the x direction and set it

if (loc.x+size >= boundx || loc.x <= 0)

{ dx *= -1; }

//if it will hit the top or bottom boundray, flip the y direction and set it

if (loc.y+size >= boundy || loc.y <= 0)

{ dy *= -1; }

for (int i = 0; i < r.size(); i++)

{

temp = new Rectangle(r.elementAt(i));

int rx = temp.x;

int ry = temp.y;

int rh = temp.height;

int rw = temp.width;

//If the ball hits either side of the rectangle, change the x direction

if((loc.x > rx && loc.x > ry && loc.x < (ry + rh))||(loc.x < (rx + rw) && loc.x > rx && loc.x

{dx *= -1;}

//If the ball hits either the top or bottom, change the y direction

if((loc.y > ry && loc.y > rx && loc.y < (rx + rw))||(loc.y < (ry + rh) && loc.y > ry && loc.y

{dy *= -1;}

}

//Increment or decrement the location of the ball based on the X and Y directions.

loc.x += dx;

loc.y += dy;

}

在此先感谢所有精彩的帮助.

解决方法:

我终于找到了一个我喜欢的边缘检测系统……

基本上,魔术发生在这里……

// Detect if we collided with any one (collision is the rectangle, bounds is us)

if (collision.intersects(bounds)) {

// Determine the intersect of the collision...

insect = collision.intersection(bounds);

// Flags...

boolean vertical = false;

boolean horizontal = false;

boolean isLeft = false;

boolean isTop = false;

// Left side...

if (insect.x == collision.x) {

horizontal = true;

isLeft = true;

// Right side

} else if (insect.x + insect.width == collision.x + collision.width) {

horizontal = true;

}

// Top

if (insect.y == collision.y) {

vertical = true;

isTop = true;

// Bottom

} else if (insect.y + insect.height == collision.y + collision.height) {

vertical = true;

}

// Technically, we can really only collide with a single edge...more or less

if (horizontal && vertical) {

// Basically, we try and give precedence to the longer edge...

if (insect.width > insect.height) {

horizontal = false;

} else {

vertical = false;

}

}

// We collided with a horizontal side...

if (horizontal) {

dx *= -1;

// Move the ball to the approriate edge so we don't get caught...

if (isLeft) {

bounds.x = collision.x - bounds.width;

} else {

bounds.x = collision.x + collision.width;

}

// We collided with a vertical side...

} else if (vertical) {

dy *= -1;

// Move the ball to the approriate edge so we don't get caught...

if (isTop) {

bounds.y = collision.y - bounds.height;

} else {

bounds.y = collision.y + collision.height;

}

}

}

现在,我只有一个障碍,但我怀疑它需要花费很多精力才能让它与一系列障碍一起工作……;)

public class TestBouncingBall {

private Rectangle insect;

public static void main(String[] args) {

new TestBouncingBall();

}

public TestBouncingBall() {

EventQueue.invokeLater(new Runnable() {

@Override

public void run() {

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

} catch (ClassNotFoundException ex) {

} catch (InstantiationException ex) {

} catch (IllegalAccessException ex) {

} catch (UnsupportedLookAndFeelException ex) {

}

JFrame frame = new JFrame();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setLayout(new BorderLayout());

frame.add(new BallPane());

frame.pack();

frame.setLocationRelativeTo(null);

frame.setVisible(true);

}

});

}

public class BallPane extends JLayeredPane {

private Ball ball;

private Timer timer;

private Rectangle world;

public BallPane() {

// world = new Rectangle(random(400), random(400), random(100), random(100));

world = new Rectangle(100, 100, 200, 200);

ball = new Ball();

ball.setSize(ball.getPreferredSize());

ball.setLocation(10, 10);

add(ball);

timer = new Timer(16, new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

ball.move(getBounds(), world);

invalidate();

repaint();

}

});

timer.setRepeats(true);

timer.setCoalesce(true);

timer.start();

}

protected int random(int max) {

return (int) Math.round(Math.random() * max);

}

@Override

public Dimension getPreferredSize() {

return new Dimension(400, 400);

}

@Override

protected void paintComponent(Graphics g) {

super.paintComponent(g);

Graphics2D g2d = (Graphics2D) g.create();

g2d.setColor(Color.GRAY);

g2d.fill(world);

if (insect != null) {

g2d.setColor(Color.RED);

g2d.fill(insect);

}

g2d.dispose();

}

}

public class Ball extends JPanel {

public int maxSpeed = 10;

private BufferedImage beachBall;

private int dx = 10 - (int)Math.round(Math.random() * (maxSpeed * 2)) + 1;

private int dy = 10 - (int)Math.round(Math.random() * (maxSpeed * 2)) + 1;

private int spin = 20;

private int rotation = 0;

public Ball() {

try {

beachBall = ImageIO.read(getClass().getResource("/ball.png"));

} catch (IOException ex) {

ex.printStackTrace();

}

setOpaque(false);

}

@Override

public Dimension getPreferredSize() {

Dimension size = beachBall == null ? new Dimension(48, 48) : new Dimension(beachBall.getWidth(), beachBall.getHeight());

size.width += 4;

size.height += 4;

return size;

}

@Override

protected void paintComponent(Graphics g) {

super.paintComponent(g);

if (beachBall != null) {

Graphics2D g2d = (Graphics2D) g.create();

g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);

g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);

g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);

g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);

g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);

g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

int x = (getWidth() - beachBall.getWidth()) / 2;

int y = (getHeight() - beachBall.getHeight()) / 2;

AffineTransform transform = g2d.getTransform();

AffineTransform at = new AffineTransform();

at.translate(getX(), getY());

at.rotate(Math.toRadians(rotation), getWidth() / 2, getHeight() / 2);

g2d.setTransform(at);

g2d.drawImage(beachBall, x, y, this);

g2d.setTransform(transform);

g2d.dispose();

}

}

public void move(Rectangle world, Rectangle collision) {

Rectangle bounds = getBounds();

bounds.x += dx;

bounds.y += dy;

if (bounds.x < 0) {

bounds.x = 0;

dx *= -1;

}

if (bounds.y < 0) {

bounds.y = 0;

dy *= -1;

}

if (bounds.x + bounds.width > world.width) {

bounds.x = world.width - bounds.width;

dx *= -1;

}

if (bounds.y + bounds.height > world.height) {

bounds.y = world.height - bounds.height;

dy *= -1;

}

if (collision.intersects(bounds)) {

insect = collision.intersection(bounds);

boolean vertical = false;

boolean horizontal = false;

boolean isLeft = false;

boolean isTop = false;

if (insect.x == collision.x) {

horizontal = true;

isLeft = true;

} else if (insect.x + insect.width == collision.x + collision.width) {

horizontal = true;

}

if (insect.y == collision.y) {

vertical = true;

isTop = true;

} else if (insect.y + insect.height == collision.y + collision.height) {

vertical = true;

}

if (horizontal && vertical) {

if (insect.width > insect.height) {

horizontal = false;

} else {

vertical = false;

}

}

System.out.println("v = " + vertical + "; h = " + horizontal);

if (horizontal) {

dx *= -1;

if (isLeft) {

bounds.x = collision.x - bounds.width;

} else {

bounds.x = collision.x + collision.width;

}

} else if (vertical) {

dy *= -1;

if (isTop) {

bounds.y = collision.y - bounds.height;

} else {

bounds.y = collision.y + collision.height;

}

}

}

rotation += spin;

setBounds(bounds);

repaint();

}

}

}

标签:rectangles,java,collision-detection,mouseevent,applet

来源: https://codeday.me/bug/20190917/1808805.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值