2014-01-13 3 views
0

Я разработал простую игру в java, используя AWT и Swing. Все, что вы делаете, это контролировать квадрат с пробелом, который прыгает вверх и вниз на бесконечном потоке платформ.Странное поведение с столкновением платформы и прыжками

Weeee!

Все работает отлично, но когда игрок прыгает с платформы, держит пробел, и приземляется на другой платформе, он/она будет случайным образом подпрыгивать или просто падение через платформу. Из того, что я могу сказать, ошибка лежит где-то с поведением Игрока.

Вот весь код нужно проверить:

import java.awt.Color; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Point; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 

public class main { 

    private static JFrame gui; 
    private static Container pane; 
    private static JPanel panel;  

    public static void main(String[] args) { 
     gui = new JFrame(); 
     gui.setSize(500,500); 
     gui.setTitle("An Experiment"); 
     gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     pane=gui.getContentPane(); 
     panel = new ColorPanel(Color.WHITE, 500, 500); 
     pane.add(panel); 
     gui.setVisible(true); 
     gui.pack(); 
    } 

    //**************** 
    //ColorPanel class 
    //**************** 

    private static class ColorPanel extends JPanel{ 
     private static final long serialVersionUID = -1101242028703991986L; 
     private Timer timer, dtimer; 
     private KeyListener k; 
     private Platform platform; 
     private Player player; 
     private int difficulty, score; 

     public ColorPanel(Color backColor, int width, int height){ 
      setBackground(backColor); 
      setPreferredSize(new Dimension(width, height)); 
      difficulty=-1; 
      score=0; 

      platform = new Platform(new Point(240,250), 50); 

      player=new Player(width/2, height/2-100); 

      k=new keyboardListener(); 
      addKeyListener(k); 
      setFocusable(true); 

      timer = new javax.swing.Timer(15, new timerListener()); 
      timer.start(); 

      dtimer = new javax.swing.Timer(50000, new difficultyListener()); 
      dtimer.start(); 
     } 

     public void paintComponent(Graphics g){ 
      super.paintComponent(g); 
      if(player.getY()<500){ 
       platform.draw(g); 
       player.draw(g); 
      }else{ 
       timer.stop(); 
       dtimer.stop(); 
       setBackground(Color.BLACK); 
       g.setColor(Color.RED); 
       g.drawString("Game Over.", 215, 230); 
       g.setColor(Color.YELLOW); 
       g.drawString("Platforms cleared: "+score, 200, 240); 
       g.drawString("End difficulty: "+Math.abs(difficulty), 200, 250); 

      } 
     } 

     private class timerListener implements ActionListener{ 
      public void actionPerformed(ActionEvent e){   
       //Player control 
       player.move(platform); 

       repaint(); 
      } 
     } 

     private class difficultyListener implements ActionListener{ 
      public void actionPerformed(ActionEvent e){ 
       difficulty--; 
       if(difficulty<=-10){ 
        dtimer.stop(); 
       } 
      } 
     } 
     private class keyboardListener implements KeyListener{ 
      @Override 
      public void keyPressed(KeyEvent e){ 
       //space=32 
       if(e.getKeyCode()==32){ 
        player.setJumping(true); 
       } 
      } 
      @Override 
      public void keyReleased(KeyEvent e){ 
       if(e.getKeyCode()==32){ 
        player.setJumping(false); 
       } 
      } 
      @Override 
      public void keyTyped(KeyEvent e) { 
      } 
     } 
    } 

    //************ 
    //Player class 
    //************ 

    private static class Player { 

     private int x, y, w, h, initialSpeed, speed, endingSpeed, acceleration, jumpHeight, timeCount; 
     private boolean isJumping, onPlatform; 
     private Timer accel; 

     public Player(int x1, int y1){ 
      x=x1; 
      y=y1; 
      w=15; 
      h=15; 
      isJumping=false; 
      onPlatform=false; 
      speed=3; 
      accel=new Timer(50, new timerListener()); 
     } 

     public void draw(Graphics g){ 
      g.drawRect(x, y, w, h); 
     } 

     public void move(Platform p){ 
      //platform collision 
      onPlatform=false; 
      if((x>p.getP1().getX() && x<p.getP2().getX()) || (x+w>p.getP1().getX() && x+w<p.getP2().getX())){ 
       if(Math.abs(y+h-p.getP1().getY())<2){ 
        onPlatform=true; 
       } 
      } 
      //speed update and movement 
      if(isJumping && y>0 && jumpHeight>=-140){ 
       y+=speed; 
       jumpHeight+=speed; 
      }else if(onPlatform){ 
       speed=0; 
      }else if(!onPlatform){ 
       jumpHeight=0; 
       if(!isJumping && speed!=3){ 
        setSpeed(3); 
       } 
       y+=speed; 
      } 
      if(jumpHeight<-140){ 
       jumpHeight=0; 
      } 
     } 

     public void setJumping(boolean b){ 
      if(onPlatform && b && jumpHeight>=-140){ 
       isJumping=true; 
       speed=-4; 
      }else{ 
       isJumping=false; 
       setSpeed(3); 
      } 
     } 

     public int getY(){ 
      return y; 
     } 

     public void setSpeed(int s){ 
      //speed=starting speed + acceleration*time 
      timeCount=0; 
      initialSpeed=speed; 
      endingSpeed=s; 
      if(speed>s){ 
       acceleration=-1; 
      }else{ 
       acceleration=1; 
      } 
      accel.start(); 
     } 

     private class timerListener implements ActionListener{ 
      public void actionPerformed(ActionEvent e){ 
       timeCount++; 
       if(Math.abs(speed-endingSpeed)<=0.5){ 
        accel.stop(); 
       }else if(acceleration<0 && initialSpeed+acceleration*timeCount>0){ 
        speed--; 
       }else{ 
        speed=initialSpeed+acceleration*timeCount; 
       } 
      } 
     } 

    } 

    //************** 
    //Platform class 
    //************** 

    private static class Platform { 

     private Point p1, p2; 

     public Platform(Point p, int l){ 
      p1=p; 
      p2=new Point((int)(p1.getX()+l), (int)(p1.getY())); 
     } 

     public Point getP1(){ 
      return p1; 
     } 
     public Point getP2(){ 
      return p2; 
     } 

     public void draw(Graphics g){ 
      g.drawLine((int)(p1.getX()), (int)(p1.getY()), (int)(p2.getX()), (int)(p2.getY())); 
     } 

    } 

} 
+0

* «Если вы хотите, чтобы полный исходный код действительно запускал игру, ...» * Никто (стоит слушать) этого хочет. Чтобы лучше помочь, опубликуйте [MCVE] (http://stackoverflow.com/help/mcve) как [править вопрос] (http://stackoverflow.com/posts/21081972/edit). –

+0

В стороне, публикация адреса электронной почты на общедоступной веб-странице является приглашением на спам. Я редактировал вопрос, чтобы удалить адрес. –

+0

..Почему вы отредактировали вопрос для ссылки на Jar? –

ответ

2

Это трудно быть на 100% уверен, но то, что он «выглядит» как это происходит, как вы есть борьба между тем, что пространства событие хочет сделать и что ваша «гравитация» хочет сделать.

Помните, в то время как Space вниз, вы будете получать несколько ключевых событий в зависимости от ОС задержки клавиатуры/времени (вы можете получить несколько событий в секунду, например)

Вместо того чтобы позволить пользователю держать ключ вниз, как ...

private class keyboardListener implements KeyListener{ 
    @Override 
    public void keyPressed(KeyEvent e){ 
     //space=32 
     if(e.getKeyCode()==32){ 
      player.setJumping(true); 
     } 
    } 
    @Override 
    public void keyReleased(KeyEvent e){ 
     if(e.getKeyCode()==32){ 
      player.setJumping(false); 
     } 
    } 
    @Override 
    public void keyTyped(KeyEvent e) { 
    } 
} 

Попробуйте игнорируя любые новые Space события ...

что я хотел бы сделать, это добавить флагом называется что-то вроде hasJumped. Пока это true, вы просто игнорируете любые новые события перехода. Как только пользователь освободит Пробел, вы сбросите флаг, чтобы другое нажатие на Пробел вызвал бы новый прыжок.

В вас игровом движке, я бы сбросить jumping флаг так, что как только вы зарегистрировали факт, что скачок произошел, пока они не отпустите и нажмите Space опять же, это не вызовет переход .. .

private class keyboardListener implements KeyListener{ 
    @Override 
    public void keyPressed(KeyEvent e){ 
     //space=32 
     if(e.getKeyCode()==32){ 
      if (!player.hasJumped()) { 
       player.setJumping(true); 
      } 
     } 
    } 

    @Override 
    public void keyReleased(KeyEvent e){ 
     if(e.getKeyCode()==32){ 
      player.hasJumped(false); 
     } 
    } 
    //... 
} 

Я также рекомендую взглянуть на Key Bindings над KeyListener

Вы могли бы взглянуть на то, как, например, JApplet creates a ball that bounces and gets progressively less high in Java

+0

Но это именно то, чего я не хочу. Пользователь должен уметь удерживать пробел и отскакивать от платформы. Это должно произойти, чтобы игрок вместо того, чтобы нажимать пробел после посадки на крошечной платформе, может просто отскочить от него. – Spidermaninja

+0

Без runnable пример, невозможно точно знать, что происходит – MadProgrammer

+0

С запущенным примером невозможно узнать, что пойдет не так – MadProgrammer

Смежные вопросы