2014-01-23 3 views
0

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

Main.java

package minwoo.main; 

import javax.swing.JFrame; 

public class Main extends JFrame { 

// just to set up the game  
public static void main(String[] args) { 

    JFrame start = new JFrame("space game"); 
    start.setVisible(true); 
    start.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    start.setContentPane(new GamePanel()); 
    start.pack(); 
    start.setLocationRelativeTo(null); 

} 

} 

GamePanel.java

package minwoo.main; 

    import java.awt.Color; 
    import java.awt.Dimension; 
    import java.awt.Graphics; 
    import java.awt.Graphics2D; 
    import java.awt.event.KeyEvent; 
    import java.awt.event.KeyListener; 
    import java.awt.image.BufferedImage; 

    import javax.swing.JPanel; 

    public class GamePanel extends JPanel implements Runnable, KeyListener { 

// size 
public final static int WIDTH = 400; 
public final static int HEIGHT = 400; 


//player 
Player player; 

//the loop variables 
private Thread thread; 
private boolean running = false; 

//image 
BufferedImage image; 
Graphics2D g; 

int FPS = 30; 
double avFPS; 




//the constructor 
public GamePanel() { 
    addKeyListener(this); 
    setPreferredSize(new Dimension(WIDTH,HEIGHT)); 
    setFocusable(true); 
    requestFocus(); 

    player = new Player(); 


} 

//functions 
public void addNotify() { 
    super.addNotify(); 
    if(thread == null) { 
     thread = new Thread(this); // declares the thread. 
     thread.start(); 
    } 

} 

public void run() { 
    running = true; 

    image = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB); 
    g = (Graphics2D) image.getGraphics(); 

    long startTime; 
    long waitTime; 
    long ms; 
    long targetTime = 1000/30; // shows how much is needed to get 30 ticks 

    long frameCount = 0; 
    long max_Frame = 30; // maximum amount of frames you are allowed to reach. 
    long totalTime = 0; 


    while(running) { // start of the game loop 
     startTime = System.nanoTime(); // takes note of the current time 

     update(); 
     render(); 
     draw(); 


     // System.nanoTime() at this point takes note of current time, which 
     //is different from what it was few nanoseconds ago. 
     ms = (System.nanoTime() - startTime)/1000000; 
     // shows how much time has passed, and it is converted to miliseconds. 
     waitTime = targetTime - ms; 
     /** 
     * let me give you an example. 
     * ms is 25 milliseconds, but my target is 30 seconds. To get to 
     * that target time, we have to give up 5 seconds. 
     * **/ 
     if(waitTime < 0) { waitTime = 5; } //sets default if waitTime is 
     // negative. 

     try { 

     Thread.sleep(waitTime); 
    } catch (InterruptedException e) { 

     e.printStackTrace(); 
    } 

    totalTime += System.nanoTime() - startTime; // accumulates 
    // total time it took for the whole process. 

    frameCount++; // frame is counted 

    if(frameCount == max_Frame) { 
     avFPS = 1000.0/((totalTime/frameCount)/1000000); 
     frameCount = 0; 
     totalTime =0; 
    } 


    }// end of the game loop 


} // end of run() 



@Override 
public void keyTyped(KeyEvent e) { 

} 


private void update() { 
    player.update(); 
} // end of update() 

private void render() { 

    g.setColor(Color.WHITE); 
    g.fillRect(0, 0,WIDTH,HEIGHT); 
    g.setColor(Color.BLACK); 
    g.drawString("FPS: " + avFPS,150,100); 
    player.draw(g); 
}// end of render() 

@Override 
public void keyPressed(KeyEvent e) { 
    int Key = e.getKeyCode(); 
    if(Key == KeyEvent.VK_RIGHT) { 
     player.Direction_X(Player.SPEED); 
    } 
    if(Key == KeyEvent.VK_LEFT) { 
     player.Direction_X(Player.SPEED); 
    } 
    if(Key == KeyEvent.VK_UP) { 
     player.Direction_Y(Player.SPEED); 
    } 
    if(Key == KeyEvent.VK_DOWN) { 
     player.Direction_Y(Player.SPEED); 
    } 

} 

@Override 
public void keyReleased(KeyEvent e) { 
    // TODO Auto-generated method stub 
    if(e.getKeyCode() == KeyEvent.VK_RIGHT) { 
     player.Direction_X(Player.SPEED); 
    } 
    if(e.getKeyCode() == KeyEvent.VK_LEFT) { 
     player.Direction_X(-Player.SPEED); 
    } 
    if(e.getKeyCode() == KeyEvent.VK_UP) { 
     player.Direction_Y(Player.SPEED); 
    } 
    if(e.getKeyCode() == KeyEvent.VK_DOWN) { 
     player.Direction_Y(-Player.SPEED); 
    } 

} 

//draw() 
private void draw() { 
    Graphics g2 = this.getGraphics(); 
    g2.drawImage(image,0,0,null); 
    g2.dispose(); 
}// end of draw() 







    }// end of GamePanel class 

Player.java

package minwoo.main; 
import java.awt.BasicStroke; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
public class Player { 

//fields 
private int x; 
private int y; 
private int r; 

private int dx; 
private int dy; 
public static final int SPEED = 5; 

private int lives; 

private Color character_Color = Color.WHITE; 
private Color hit_Color = Color.RED; 

// constructor 
public Player() { 

    x = GamePanel.WIDTH/2; 
    y = GamePanel.HEIGHT/2; 

    r = 5; 

    dx = 0; 
    dy = 0; 




    lives = 3; 
} // end of constructor 

//movements 
public void Direction_X(int speed) { 

    dx = speed; 
} 


public void Direction_Y(int speed) 
{ 
    dy = speed;} 




//functions 
public void update() { 

    move(); 

    //to keep the bounds 
    if(x < r) { x = r;} 
    if(y < r) {y = r;} 
    if(x > GamePanel.WIDTH - r) { x = GamePanel.WIDTH - r; 
    } 
    if(y > GamePanel.HEIGHT - r) { y = GamePanel.HEIGHT - r; } 

}// end of update() 

private void move() { 

    x += dx; 
    y += dy; 

} 

public void draw(Graphics2D g) { 

    g.setColor(character_Color); 
    g.fillOval(dx, dy,2*r,2*r); // circle in the centre. 

    g.setStroke(new BasicStroke(3)); 
    g.setColor(character_Color.darker()); 
    g.drawOval(dx, dy,2*r,2*r); 
    g.setStroke(new BasicStroke(1)); 

} 

} 
+0

Dont сделать 'Графика g2 = this.getGraphics(); ', это не так, как выполняется обычная покраска. Познакомьтесь подробнее с [Выполнение пользовательской живописи] (http://docs.oracle.com/javase/tutorial/uiswing/painting/). Вы также можете взглянуть на [Кодовые обозначения для языка программирования Java] (http://www.oracle.com/technetwork/java/codeconv-138413.html), поскольку другие разработчики с меньшей вероятностью имеют психотический момент при чтении кода. Также не удаляйте ресурсы, которые вы не создали ... – MadProgrammer

+0

'Я искал все это и адаптировал решения для людей, но это не работает.'- если вы искали, вы узнаете, что почти все советуют использовать« Key Bindings »и NOT KeyListener. Итак, почему ваш код по-прежнему использует KeyListener? Видимо, вы не слушаете приведенный совет. – camickr

+0

Ну, что касается клавишных привязок, мне просто интересно узнать, как заставить его работать, если я использую KeyListener. Если это сработает, я переключусь на Key Bindings. Я просто хочу посмотреть, будет ли он работать с помощью KeyListener. Это все. – JollyGent

ответ

1

Ваша основная про это я проблема вы красите значение дельты не значение позиции ...

g.fillOval(dx, dy, 2 * r, 2 * r); 
      ^---^---These are the deltas, not the position... 

Других проблемы, которые будут/могут иметь ...

  • Использование getGraphics вместо переопределения paintComponent. getGraphics может вернуть null, и все, что вы нарисовали ему, будет очищено в следующий раз, когда произойдет цикл краски. Swing использует систему пассивной окраски и может запускать рецензенты без ваших взаимодействий.
  • Использование KeyListener. Вам, как правило, будет проще использовать Key Bindings API, который не страдает от тех же проблем с фокусом, что KeyListener страдает
  • Будьте внимательны, используя Thread, чтобы обновить состояние игры, так как возможно, что перекраска может произойти, когда вы 'изменение штата, и вы получите грязную краску.
  • Использование «магических» чисел (то есть GamePanel.WIDTH). Если изменить размер окна, это значение не будет иметь никакого значения. Вместо этого используйте эмпирические значения, передайте фактическую ширину и высоту контейнера по методу move
  • Ваши звонки keyPressed и завинчиваются кодом вашего движения. Можно нажать Слева и иметь мяч подпрыгивать вправо ... то же самое касается других направлений, возможно, чтобы мяч отскочил в противоположном направлении, прежде чем двигаться в правильном направлении. В качестве другого примера, если я удерживая левой, мяч будет двигаться вправо ...

Посмотрите на

+0

Я использовал привязки клавиш вместо прослушивателей клавиш, но я хочу спросить - есть ли альтернатива Key Keyings, выпущенная Key? 'im.put (KeyStroke.getKeyStroke (KeyEvent.KEY_RELEASED, 0),« выпущено »);' не работает – JollyGent

+0

Проверьте getKeyStroke (int keyCode, int modifiers, boolean onKeyReleased) – MadProgrammer

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