Как я могу сделать так, чтобы моя игра упала, когда я покинул платформу, которую я создал?

#java #gravity

#Ява #гравитация

Вопрос:

Я хочу, чтобы, когда мой плеер сойдет с платформы (в классе PlatformerPanel метода checkCollision ()), он упадет, а затем что-то сделает, когда исчезнет с экрана, я еще не настроил экран окончания игры, но это то, что я планирую сделать. В любом случае, проблема в том, что по какой-то причине он движется слишком быстро и падает слишком рано, а также при нажатии клавиши со стрелкой во время падения он вернется на платформу.

Пожалуйста, попытайтесь помочь мне преодолеть это или придумать новый, простой для понимания способ сделать это/сделать так, чтобы это работало так, как я планирую.

ПРАВКА 1: Я исправил то, что происходит слишком рано, так что не беспокойтесь об этом

 ``` public class PlatformerMain {  public static void main(String[] args) {  PlatformerGameFrame platformerGame = new PlatformerGameFrame();  } }  import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*;  public class PlatformerGameFrame extends JFrame{    PlatformerGamePanel panel;    PlatformerGameFrame() {  panel = new PlatformerGamePanel();  this.add(panel);  this.setTitle("Platformer Game");  this.setResizable(false);  this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);  this.pack();  this.setVisible(true);  this.setLocationRelativeTo(null);  this.getContentPane().setBackground(new Color(0,0,0));  } } import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*;  public class PlatformerGamePanel extends JPanel implements Runnable{  PlatformerPlayer player1;  PlatformerMap map1;  static final int SCREEN_WIDTH = 1000;  static final int SCREEN_HEIGHT = 600;  static final int PLAYER_WIDTH = 50;  static final int PLAYER_HEIGHT = 60;  static final Dimension SCREEN_SIZE = new Dimension(SCREEN_WIDTH,SCREEN_HEIGHT);  static boolean falling = false;  Image backgroundImage;  Thread gameThread;  Image image;  Graphics graphics;  PlatformerMap map;    public PlatformerGamePanel() {  java.net.URL imgIcon = Main.class.getResource(  "/Resources/spaceImage.jpg");  backgroundImage = new ImageIcon(imgIcon).getImage();  newPlayer();  newMap();    this.setFocusable(true);  this.addKeyListener(new KeyListener() {   @Override  public void keyTyped(KeyEvent e) {}   @Override  public void keyPressed(KeyEvent e) {  player1.KeyPressed(e);  }   @Override  public void keyReleased(KeyEvent e) {  player1.KeyReleased(e);  }    });  this.setPreferredSize(SCREEN_SIZE);  this.setOpaque(true);    gameThread = new Thread(this);  gameThread.start();        }    public void paint(Graphics g) {  image = createImage(getWidth(),getHeight());  graphics = image.getGraphics();  draw(graphics);  g.drawImage(image, 0,0, null);  }  public void draw(Graphics g) {  Graphics2D g2D = (Graphics2D) g;  g2D.drawImage(backgroundImage, 0,0, null);  player1.paint(g);  map.paint(g);  }    public void newPlayer() {  player1 = new PlatformerPlayer((SCREEN_WIDTH/2)-(PLAYER_WIDTH/2), (SCREEN_HEIGHT/2)-(PLAYER_WIDTH/2), PLAYER_WIDTH, PLAYER_HEIGHT);  }    public void newMap() {  map = new PlatformerMap();  }    public void checkCollision() {  if(player1.x gt; SCREEN_WIDTH-PLAYER_WIDTH) {  player1.x = SCREEN_WIDTH-PLAYER_WIDTH;  }  else if(player1.x lt; 0) {  player1.x = 0;  }  if(!(player1.x gt;map.PLATFORM_WIDTH)) {  if(player1.y gt; SCREEN_HEIGHT-250) {  player1.y = SCREEN_HEIGHT-250;  }  } else if(player1.x gt; map.PLATFORM_WIDTH) {  gravity();  }  }  public void falling() {    }  public void gravity() {  player1.gravity();  }    public void move() {  player1.move();  }    public void run() {  long lastTime = System.nanoTime();  double amountOfTicks = 120.0;  double ns = 1000000000 / amountOfTicks;  double delta = 0;  while(true) {  long now = System.nanoTime();  delta  = (now - lastTime)/ns;  lastTime = now;  if(delta gt;= 1) {  move();  checkCollision();  gravity();  repaint();  delta--;  }    }  }     } import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*;  public class PlatformerPlayer extends Rectangle {    /*static int playerPosX = 100;  static int playerPosY = 100;*/  static double velocityY = 0;  static double velocityX = 0;  static int vertical_position;   static final int TERMINAL_VELOCITY = 200;  static final int PLAYER_WIDTH = 50;  static final int PLAYER_HEIGHT = 50;  static int speed = 2;  protected boolean falling = true;  protected boolean jumping = false;  double gravity = 0.05;    public PlatformerPlayer(int x, int y, int PLAYERWIDTH, int PLAYERHEIGHT) {  super(x,y,PLAYERWIDTH,PLAYERHEIGHT);  }      public void KeyPressed(KeyEvent e) {  if(e.getKeyCode()==KeyEvent.VK_LEFT) {  setXDirection(-speed);  move();  }  else if(e.getKeyCode()==KeyEvent.VK_RIGHT) {  setXDirection(speed);  move();  }  }  public void KeyReleased(KeyEvent e) {  if(e.getKeyCode()==KeyEvent.VK_LEFT) {  setXDirection(0);  move();  }  else if(e.getKeyCode()==KeyEvent.VK_RIGHT) {  setXDirection(0);  move();  }  }  public void paint(Graphics g) {  Graphics2D g2D = (Graphics2D) g;  g2D.setColor(Color.red);  g2D.fillRect(x, y, PLAYER_WIDTH, PLAYER_HEIGHT);  }     public void setYDirection(int YDirection) {  velocityY = YDirection;  }  public void setXDirection(int XDirection) {  if(speed gt; 10) {  speed = 10;  }  velocityX = XDirection;  }  public void move() {  y  = velocityY;  x  = velocityX;  }  public void gravity() {  velocityY  = gravity;  if (velocityY gt; TERMINAL_VELOCITY)  {  velocityY = TERMINAL_VELOCITY;  }  vertical_position -= velocityY;  }    } import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*;  public class PlatformerMap extends Rectangle {  int PLATFORM_WIDTH = 600;  int PLATFORM_HEIGHT = 150;  public PlatformerMap() {    }  public void paint(Graphics g) {  Graphics2D g2D = (Graphics2D) g;  g2D.setColor(Color.gray);  g2D.fillRect(100,400,PLATFORM_WIDTH,PLATFORM_HEIGHT);  } }  
   

Комментарии:

1. Трудно дать точный ответ, не прочитав и полностью не поняв весь ваш код (а у меня нет на это времени), поэтому позвольте мне вместо этого дать несколько советов: 1) попробуйте пройти через ваш код с помощью отладчика, чтобы проверить, почему игрок падает слишком рано (установите точку останова в коде, который инициирует падение), 2) как только игрок падает, отключите/игнорируйте любой ввод ключа, который вам не нужен,

2. 3) если ваш игрок падает слишком быстро, проверьте свой расчет силы тяжести: velocityY = gravity; кажется неправильным, так как отсутствует компонент времени (есть разница между добавлением 0,05 к скорости каждые 10 мс или каждые мс и т.д.). Вы обновляете состояние игры только один раз за тик, но обратите внимание, что delta оно может быть gt; 1, поэтому любое движение должно учитывать это для плавной анимации. 4) Обратите внимание, что вы в основном звоните gravity() дважды, если игрок падает: 1 checkCollision(); раз, а затем снова непосредственно в вашем основном цикле.

3. Спасибо вам за то, что вы сделали все возможное, не глядя на мой код, я приму во внимание то, что вы сказали, но я все еще ищу ответ, в котором кто-то может посмотреть на мой код и предложить свои предложения.