在激光与矩形对象相交后,尝试让爆炸消失
我在用Java做一个小型游戏:飞船向一个矩形射出激光,矩形会被移除,同时出现一个爆炸PNG图片。我的问题是在于想让爆炸的动画在几秒后也被移除,但一直没搞定……爆炸动画不会消失。
下面是一些代码,真的非常感谢任何帮助……
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
public class MovingObject extends JPanel implements KeyListener {
private ArrayList<Rectangle> rects = new ArrayList<>();
private final int MAX_X = 400;
private final int SPEED = 7;
private BufferedImage image, image2, image3;
private boolean visible = false;
public MovingObject() {
rects.add(new Rectangle(20, 50, 128, 128));
rects.add(new Rectangle(80, 75, 32, 32));
rects.add(new Rectangle(130, 25, 128, 128));
rects.add(new Rectangle(200, 50, 50, 50));
rects.add(new Rectangle(300, 50, 50, 50));
try {
image = ImageIO.read(new File("C:/Users/hm_08/OneDrive/Desktop/ship3.png"));
image2 = ImageIO.read(new File("C:/Users/hm_08/OneDrive/Desktop/shot.png"));
image3 = ImageIO.read(new File("C:/Users/hm_08/OneDrive/Desktop/expl.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bgColor();
this.setFocusable(true);
addKeyListener(this);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (visible) {
g.drawImage(image3, rects.get(2).x, 25, 128, 128, this);
}
g.fillRect(rects.get(3).x, 50, 50, 50);
if (!visible) {
g.drawImage(image2, rects.get(1).x, 75, 32, 32, this);
}
g.drawImage(image, rects.get(0).x, 20, 128, 128, this);
g.fillRect(300, 50, 50, 50);
}
private void bgColor() {
setBackground(Color.BLACK);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Moving Object");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 500);
frame.add(new MovingObject());
frame.setVisible(true);
}
@Override
public void keyPressed(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.VK_SPACE) {
Thread animationThread = new Thread(() -> {
while (rects.get(1).x < MAX_X) {
if (!rects.isEmpty()) {
rects.get(1).x += SPEED;
repaint();
if (rects.get(1).intersects(rects.get(3))) {
visible = !visible;
rects.remove(3);
repaint();
break;
}
removeKeyListener(this);
}
try {
Thread.sleep(50); // Delay for smooth movement
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
animationThread.start();
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
更新:增加了一个定时器来发射激光,但这次的表现仍然和之前一样,出现了长度为3 的下标3 越界错误(更新后的代码如下:)
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
public class MovingObject extends JPanel implements KeyListener {
private ArrayList<Rectangle> rects = new ArrayList<>();
private final int SPEED = 7;
private BufferedImage image, image2, image3;
private boolean visible = false;
public MovingObject() {
rects.add(new Rectangle(20, 50, 128, 128));
rects.add(new Rectangle(80, 75, 32, 32));
rects.add(new Rectangle(130, 25, 128, 128));
rects.add(new Rectangle(200, 50, 50, 50));
rects.add(new Rectangle(300, 50, 50, 50));
try {
image = ImageIO.read(new File("C:/Users/hm_08/OneDrive/Desktop/ship3.png"));
image2 = ImageIO.read(new File("C:/Users/hm_08/OneDrive/Desktop/shot.png"));
image3 = ImageIO.read(new File("C:/Users/hm_08/OneDrive/Desktop/expl.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bgColor();
this.setFocusable(true);
addKeyListener(this);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (visible) {
g.drawImage(image3, rects.get(2).x, 25, 128, 128, this);
}
g.fillRect(rects.get(3).x, 50, 50, 50);
if (!visible) {
g.drawImage(image2, rects.get(1).x, 75, 32, 32, this);
}
g.drawImage(image, rects.get(0).x, 20, 128, 128, this);
g.fillRect(300, 50, 50, 50);
}
private void bgColor() {
setBackground(Color.BLACK);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Moving Object");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 500);
frame.add(new MovingObject());
frame.setVisible(true);
}
@Override
public void keyPressed(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.VK_SPACE) {
Timer timer = new Timer(25, e -> {
if (!rects.isEmpty()) {
rects.get(1).x += SPEED;
repaint();
System.out.println(rects.size());
if (rects.get(1).intersects(rects.get(3))) {
visible = !visible;
rects.remove(3);
repaint();
}
removeKeyListener(this);
}
});
timer.start();
}
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
解决方案
你应用程序最严重的问题在于混用不同的“矩形”。在名为 recs 的列表里,既有与飞船对应的矩形,也有“目标”矩形。删除元素时,随着你使用固定的索引,索引就开始出问题。然后你提到动画不会停止,但没有相应的机制来让它停止。你只检查与位置“3”处的“对象”的碰撞。至于激光呢?无论如何,我做了一个小应用,给你一个关于“事情可能会如何发展”的思路。希望对你有帮助。
public class Demo extends JFrame {
MyContentPane contentPane;
Timer timerLaser;
int SPEED = 1;
String type;
boolean firstIteration = true;
Rectangle removed = null;
public Demo( String name ) {
super( name );
}
void ini() {
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
setSize( 800, 500 );
contentPane = new MyContentPane();
setContentPane( contentPane );
contentPane.addRect( 200, 250, 50, 50 );
contentPane.addRect( 470, 25, 128, 128 );
contentPane.setShip( 20, 50, 128, 128 );
setVisible( true );
addKeyListener( new KeyAdapter() {
@Override
public void keyPressed( KeyEvent event ) {
if( event.getKeyCode() == KeyEvent.VK_SPACE ) {
type = "laser";
execute();
}
}
} );
}
void execute() {
contentPane.setThereIsNow( true );
Rectangle aux = contentPane.getAux();
Rectangle ship = contentPane.getShip();
timerLaser = new Timer( 25, e -> {
if( type.equals( "laser" ) ) {
if( firstIteration ) {
contentPane.setAux( ship.x + ship.width, ship.y + 62, 1, 4 );
firstIteration = false;
}
if( aux.width < 20 ) {
aux.width += SPEED;
}
else {
aux.x += SPEED;
}
for( Rectangle rec : contentPane.getRectangles() ) {
if( rec.intersects( aux ) ) {
removed = rec;
contentPane.deleteRect( rec );
firstIteration = true;
type = "";
break;
}
}
repaint();
}
else {
if( firstIteration ) {
contentPane.setAux( removed.x, removed.y, removed.width, removed.height );
firstIteration = false;
}
aux.x -= 1;
aux.width += 2;
aux.y -= 1;
aux.height += 2;
repaint();
if( removed.x - aux.x > 40 ) {
timerLaser.stop();
contentPane.setThereIsNow( false );
firstIteration = true;
type = "laser";
}
}
});
timerLaser.start();
}
public static void main( String[] args ) {
Demo frame = new Demo( "Moving Object" );
frame.ini();
}
}
public class MyContentPane extends JComponent {
private ArrayList<Rectangle> rects;
private Rectangle ship;
private Rectangle aux;
boolean isLaser = true, thereIsNow = false;
int auxX, auxY, auxWidth, auxHeigth;
Timer timerLaser, timerExplosion;
public MyContentPane() {
rects = new ArrayList<>();
aux = new Rectangle();
}
void addRect( int x, int y, int w, int h ) {
rects.add( new Rectangle( x, y, w, h ) );
}
void setShip( int x, int y, int w, int h ) {
ship = new Rectangle( x, y, w, h );
}
void setAux( int x, int y, int w, int h ) {
aux.x = x;
aux.y = y;
aux.width = w;
aux.height = h;
}
@Override
public void paintComponent( Graphics g ) {
super.paintComponent( g );
Graphics2D gr = (Graphics2D) g;
gr.clearRect( 0, 0, getWidth(), getHeight());
gr.fillRect( ship.x, ship.y, ship.width, ship.height );
for( Rectangle rect : rects ) {
gr.fillRect( rect.x, rect.y, rect.width, rect.height );
}
if( thereIsNow ) {
if( isLaser ) {
gr.setColor( Color.yellow );
}
else {
gr.setColor( Color.red );
}
gr.fillRect( aux.x, aux.y, aux.width, aux.height );
}
}
void deleteRect( Rectangle rec ) {
rects.remove( rec );
}
ArrayList<Rectangle> getRectangles() {
return rects;
}
Rectangle getShip() {
return ship;
}
Rectangle getAux() {
return aux;
}
void setThereIsNow( boolean bool ) {
thereIsNow = bool;
}
}
PS:附言:把图片替换成矩形,因为这会影响动画代码,你需要对它进行调整,以使它能够与 gif 一起工作吗?
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。