我的java(JFrame)播放器移动脚本赢得';行不通
我正在制作一个自上而下的2d生存游戏,玩家必须躲避敌人的炮弹才能生存,但我遇到了一个问题,可能会稍微影响我第一个真正java项目的游戏性,这个问题是玩家不能以任何形式移动,如果炮弹已经实现,那么玩家在产卵到这个世界后会立即失败 代码如下:我的java(JFrame)播放器移动脚本赢得';行不通,java,swing,jframe,keylistener,Java,Swing,Jframe,Keylistener,我正在制作一个自上而下的2d生存游戏,玩家必须躲避敌人的炮弹才能生存,但我遇到了一个问题,可能会稍微影响我第一个真正java项目的游戏性,这个问题是玩家不能以任何形式移动,如果炮弹已经实现,那么玩家在产卵到这个世界后会立即失败 代码如下: package maximiza; import java.awt.*; import java.awt.event.KeyEvent; import javax.swing.*; public class Game extends JFrame {
package maximiza;
import java.awt.*;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class Game extends JFrame {
private static final long serialVersionUID = 1L;
public int xPosition = 240;
public int yPosition = 240;
public int speed = 10;
public int playerSize = 20;
public Game()
{
setTitle("Maximiza");
setSize(500, 500);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void paint(Graphics g)
{
g.setColor(Color.yellow);
g.fillRect(xPosition, yPosition, playerSize, playerSize);
}
public void init()
{
addKeyListener(new Input(this));
}
public static void main(String [] args)
{
boolean living = true;
Game g = new Game();
g.init();
while(living)
{
g.paint(null);
}
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == KeyEvent.VK_UP) {
yPosition += speed;
} else if(key == KeyEvent.VK_DOWN) {
yPosition -= speed;
}
}
public void keyReleased(KeyEvent e) {
}
}
输入脚本:
package maximiza;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class Input extends KeyAdapter {
Game game;
public Input(Game game) {
this.game = game;
}
public void keyPressed(KeyEvent e) {
game.keyPressed(e);
}
public void keyReleased(KeyEvent e) {
game.keyReleased(e);
}
}
感谢您提供的帮助。首先有几个问题:
JFrame
,您可以创建一个JPanel
,只需将其添加到JFrame
paint
,而是像JPanel
一样使用JComponent
并重写paintComponent
,不要忘记调用super.paintComponent
作为重写方法中的第一条语句。另外,切勿直接调用paint
或paintComponent
,而应使用JComponent#repaint()
阅读上述内容setSize
使用适当的布局管理器,在需要向布局管理器提供尺寸提示的地方覆盖getPreferredSize
,然后在将框架设置为可见之前调用JFrame#pack()
KeyListener
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class Game {
private GamePanel gamePanel;
public Game() {
createAndShowUI();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(Game::new);
}
private void createAndShowUI() {
JFrame frame = new JFrame("Maximiza");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gamePanel = new GamePanel();
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "UP pressed");
gamePanel.getActionMap().put("UP pressed", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.moveUp(); // this would be something like gameObject.moveDown()
}
});
gamePanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "DOWN pressed");
gamePanel.getActionMap().put("DOWN pressed", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.moveDown(); // this would be something like gameObject.moveDown()
}
});
frame.add(gamePanel);
frame.pack();
frame.setVisible(true);
// a more approrpiate game loop can be used as we only need to call repaint 60 times per second not more or less.
// fixed step: https://stackoverflow.com/questions/13739693/java-swing-based-game-framework-any-advice/13740162#13740162
// variable step: https://github.com/davidkroukamp/SwingGameLibrary/blob/main/src/za/co/swinggamelibrary/GameLoop.java
Thread gameLoop = new Thread(() -> {
boolean living = true;
while (living) {
gamePanel.repaint();
// lets sleep a bit not to eat up processor time unnecessarily needs a better implementation of a game loop but thread sleep will do okay for now
try {
Thread.sleep(16);
} catch (InterruptedException ex) {
}
}
});
gameLoop.start();
}
public class GamePanel extends JPanel {
// these properties should go into its own game object which is separated from the game panel, and can simply be added to the game panel via a list
// and in the paintComponent method you simply iterate all the game objects and draw them
// https://github.com/davidkroukamp/SwingGameLibrary-Samples/blob/main/sample1/src/sgltest/Player.java
public int xPosition = 240;
public int yPosition = 240;
public int speed = 10;
public int playerSize = 20;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// can make graphics look better too using some rendering hints https://github.com/davidkroukamp/SwingGameLibrary/blob/main/src/za/co/swinggamelibrary/Graphics2DHelper.java
// should move to game object inside a render(Graphics2D g2d) method which gets called for each game object passing in the graphics parameter
g.setColor(Color.yellow);
g.fillRect(xPosition, yPosition, playerSize, playerSize);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
// these methods would go into the game object class too under a single move methid which checks booleans on whether to move up or down or whatever
public void moveUp() {
yPosition -= speed; // this could probably just set a boolean which your game object will check and update its position accordingly via a move() method thats called before gamePanel.repaint in the thread
}
public void moveDown() {
yPosition += speed; // this could probably just set a boolean which your game object will check and update its position accordingly via a move() method thats called before gamePanel.repaint in the thread
}
}
}