[英]My java(JFrame) player movement script won't work
我正在制作一款自上而下的 2d 生存游戲,玩家必須躲避敵人的射彈才能生存,但我遇到了一個問題,可能會稍微影響我的第一個真正的 java 項目的游戲玩法,這個問題是玩家不能以任何形狀或形式移動,如果已經實施了射彈,那么玩家將在生成到這個世界后立即失敗。
這是代碼:
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
我自己正在創建自己的Swing 游戲庫,您可以將其用作未來努力或可能面臨的問題的參考,例如添加游戲循環,將游戲對象邏輯與游戲面板/屏幕分離,反別名等
下面是您的代碼,其中包含為幫助您入門而實施的上述建議,以及一些評論,指出您還可以添加或更改哪些內容,從而使您的游戲隨着游戲的發展更具可重用性:
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
}
}
}
重申一下,您可以進行更多更改(我已經對代碼進行了評論以給您提示),但我沒有為您做這些,因為那只是一個劇透::)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.