我正在尝试制作一款演示宇宙飞船射击游戏。每次我按下空格键时,我都会在 paintComponent(Graphics g)
方法中绘制一个新的射弹(Image
),并调用 moveProjectile()
方法。问题是 moveProjectile()
方法似乎已关闭。
MyJPanel.java
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class MyJPanel extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private Timer timer;
private Image backgroundImage;
private Image player;
private int playerX, playerY;
private int projectileX,projectileY;
private Image projectileImage;
private ArrayList<Image> projectiles = new ArrayList<Image>();
boolean flag = false;
public MyJPanel(Image backgroundImage, Image player,Image projectileImage)
{
this.backgroundImage = backgroundImage;
this.player = player;
this.projectileImage = projectileImage;
this.setLayout(null);
timer = new Timer(50, this);
timer.start();
this.addKeyListener(new KeyAdapter() // Listens for a keyboard event
{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_SPACE) // If pressing space - shoot
{
flag = true;
moveProjectile();
}
repaint();
}
});
// Mouse listener
this.addMouseMotionListener(new MouseMotionListener()
{
@Override
public void mouseMoved(MouseEvent e)
{
playerX = e.getX();
playerY = e.getY();
}
@Override
public void mouseDragged(MouseEvent e)
{
}
});
hideMouseCursor();
this.setFocusable(true);
this.setVisible(true);
} // End of JPanle constructor
public void paintComponent(Graphics graphics)
{
super.paintComponent(graphics);
graphics.drawImage(backgroundImage,0,0,this.getWidth(),this.getHeight(),null); // Draw the background
graphics.drawImage(player,playerX,playerY,null); // Draw the player
if (flag)
{
projectileX = playerX + player.getWidth(null);
projectileY = playerY + player.getHeight(null) / 2 - 27;
graphics.drawImage(projectileImage,projectileX,projectileY,null);
}
}
public void moveProjectile()
{
while (projectileX < this.getWidth())
{
this.projectileX += 2;
repaint();
}
}
public void hideMouseCursor() // Hides the mouse cursor
{
//Transparent 16 x 16 pixel cursor image.
BufferedImage cursorbackgroundImgage = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
// Create a new blank cursor.
Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
cursorbackgroundImgage, new Point(0, 0), "Blank Cursor");
// Set the blank cursor to the JPanel.
this.setCursor(blankCursor);
}
@Override
public void actionPerformed(ActionEvent actionEvent) // Without the method and the repaint() the mouse listener will not work
{
repaint();
}
public class ProjectileThread extends Thread
{
@Override
public void run()
{
projectileX = playerX + player.getWidth(null);
projectileY = playerY + player.getHeight(null) / 2;
}
}
public static void main(String[] args)
{
JFrame frame = new JFrame("A Game by me");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH); // Making the frame take a full screen
ImageIcon backgroundImageIcon = new ImageIcon("space_background_2.jpg");
Image backgroundImgage = backgroundImageIcon.getImage();
ImageIcon playerImageIcon = new ImageIcon("spaceship_1.png");
Image playerImage = playerImageIcon.getImage();
ImageIcon projectileIcon = new ImageIcon("spaceship_projectile_1.png");
Image projectileImage = projectileIcon.getImage();
frame.add(new MyJPanel(backgroundImgage,playerImage,projectileImage));
frame.setVisible(true);
}
} // End of MyJPanel
有一些变量和方法我不使用,所以请不要介意。代码中需要注意的地方:
if (e.getKeyCode() == KeyEvent.VK_SPACE) // If pressing space - shoot
{
flag = true;
moveProjectile();
}
repaint();
如果按空格 -> flag = true 表示
if (flag)
{
projectileX = playerX + player.getWidth(null);
projectileY = playerY + player.getHeight(null) / 2 - 27;
graphics.drawImage(projectileImage,projectileX,projectileY,null);
}
绘制射弹并将其移动到右侧。问题是它从来没有移到右边。相反,它跟随由鼠标移动的宇宙飞船。
如有任何建议,我们将不胜感激。
public class ProjectileThread extends Thread
{
public ProjectileThread(int playerX,int playerY)
{
projectileX = playerX + player.getWidth(null);
projectileY = playerY + player.getHeight(null) / 2;
}
@Override
public void run()
{
while (projectileX < getWidth())
{
projectileX += 2;
}
}
}
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_SPACE) // If pressing space - shoot
{
ProjectileThread projectileThread = new ProjectileThread(playerX,playerY);
projectileThread.start();
}
repaint();
}
最佳答案
您的 moveProjectile 方法通过在 X 坐标上添加 2 来水平移动射弹
this.projectileX += 2;
但是,您的绘制方法会使用玩家的 X 坐标覆盖该值:
projectileX = playerX + player.getWidth(null);
因此,每次绘制射弹时,它都位于相对于玩家的同一位置。您需要先使用玩家坐标绘制弹丸,然后在不重置其 X 坐标的情况下移动它。
您有一个线程,应该在射弹发射时启动。因此,在空格键的处理程序中,启动线程并向其传递玩家坐标。这是你的起点。然后在线程的run方法中,移动弹丸并循环等待一会儿。
关于java - 为什么我的射弹(图像对象)不移动? Java Swing ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35466485/