我试图制作一个演示飞船射击游戏。每当我按空格键时,我在Image
方法中绘制一个新的抛射物(paintComponent(Graphics g)
)并调用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();
}
答案 0 :(得分:5)
你的moveProjectile方法通过在X坐标上加2来水平移动射弹
this.projectileX += 2;
但是,您的paint方法会使用您的玩家X坐标覆盖此值:
projectileX = playerX + player.getWidth(null);
所以每当你画出你的射弹时,它都与玩家在同一个地方。你需要首先使用玩家坐标绘制射弹,然后移动它而不重置其X坐标。
当发射射弹时,你应该开始一个线程。因此,在空格键的处理程序中,启动线程并将其传递给播放器坐标。这是你的起点。然后在线程的run方法中,移动抛射物并在循环中等待一段时间。
答案 1 :(得分:1)
while (projectileX < getWidth())
{
projectileX += 2;
}
所有这一切都是设置projectile = getWidth()+ 1(或可能+ 2)。 同样,你的moveProjectile方法有:
while (projectileX < this.getWidth())
{
this.projectileX += 2;
repaint();
}
同样的事情也是如此。请注意,循环体中的repaint()基本上什么都不做,因为你阻塞了事件线程,直到moveProjectile()方法返回