0
주말에 Pong의 클론을 만들려고했습니다. 처음 키 듣기가 효과가 있었지만 이후에는 듣지 못했습니다.KeyListener가 창에서 작업을 중단했습니다
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.util.Random;
import javax.swing.JFrame;
public final class PingPong extends Canvas implements KeyListener {
private static final long serialVersionUID = 381061428448529952L;
public static final long FPS_LIMIT = 500;
public static final int BALL_SIZE = 10;
public static final int BALL_SPEED = 3;
public static final int BAT_LENGTH = 64;
public static final int BAT_WIDTH = 16;
public static final int BAT_POSITION_SHIFT_X = 16;
public static final int BAT_SPEED = 2;
private long fps_;
public void run() {
long last = System.currentTimeMillis();
long now;
long delta = 0;
this.resetGame_();
while(true) {
now = System.currentTimeMillis();
delta = now - last;
if(delta >= 1000/FPS_LIMIT) {
this.process_();
this.draw_();
this.fps_ = 1000/delta;
last = now;
}
}
}
enum EDirection { LEFT, RIGHT }
int ballPosX;
int ballPosY;
EDirection ballDirection;
float ballRoll = 0;
int firstBatPosY;
int leftScore = 0;
int secondBatPosY;
int rightScore = 0;
private void process_() {
if(ballDirection == null) {
Random rnd = new Random();
ballDirection = rnd.nextBoolean() == true ? EDirection.LEFT : EDirection.RIGHT;
}
/*
* Bats
*/
if(this.keyW)
firstBatPosY -= BAT_SPEED;
else if(this.keyS)
firstBatPosY += BAT_SPEED;
if(this.keyUp)
secondBatPosY -= BAT_SPEED;
else if(this.keyDown)
secondBatPosY += BAT_SPEED;
if(firstBatPosY < 0)
firstBatPosY = 0;
if(secondBatPosY < 0)
secondBatPosY = 0;
/*
* Ball
*/
switch(ballDirection) {
case LEFT:
ballPosX -= BALL_SPEED;
break;
case RIGHT:
ballPosX += BALL_SPEED;
break;
}
ballPosY += ballRoll;
if(ballPosX <= 0) {
ballDirection = EDirection.RIGHT;
} else {
switch(ballDirection) {
case LEFT:
if(ballPosX <= BAT_POSITION_SHIFT_X + BAT_WIDTH) {
if((ballPosY >= firstBatPosY && ballPosY <= firstBatPosY + BAT_LENGTH)
|| (ballPosY + BALL_SIZE >= firstBatPosY && ballPosY + BALL_SIZE <= firstBatPosY + BAT_LENGTH)) {
ballDirection = EDirection.RIGHT;
break;
} else {
if(ballPosX <= 0) {
rightScore++;
this.resetGame_();
}
}
}
break;
case RIGHT:
if(ballPosX >= super.getWidth() - BAT_POSITION_SHIFT_X - BAT_WIDTH) {
if((ballPosY >= secondBatPosY && ballPosY <= secondBatPosY + BAT_LENGTH)
|| (ballPosY + BALL_SIZE >= secondBatPosY && ballPosY + BALL_SIZE <= secondBatPosY + BAT_LENGTH)) {
ballDirection = EDirection.LEFT;
break;
} else {
if(ballPosX >= super.getWidth()) {
leftScore++;
this.resetGame_();
}
}
}
break;
}
}
}
private void draw_() {
BufferStrategy bs = super.getBufferStrategy();
if(bs == null) {
super.createBufferStrategy(2);
super.requestFocus();
return;
}
Graphics gfx = bs.getDrawGraphics();
gfx.setColor(Color.BLACK);
gfx.fillRect(0, 0, super.getWidth(), super.getHeight());
gfx.setColor(Color.GRAY);
gfx.fillRect(super.getWidth()/2 - 5, 10, 10, super.getHeight() - 20);
gfx.setColor(Color.WHITE);
gfx.fillRect(ballPosX, ballPosY, BALL_SIZE, BALL_SIZE);
gfx.fillRect(BAT_POSITION_SHIFT_X, firstBatPosY, BAT_WIDTH, BAT_LENGTH);
gfx.fillRect(super.getWidth() - BAT_POSITION_SHIFT_X - BAT_WIDTH, secondBatPosY, BAT_WIDTH, BAT_LENGTH);
gfx.setColor(Color.WHITE);
gfx.drawString(String.valueOf(this.fps_), 10, 20);
gfx.drawString(String.valueOf(leftScore), super.getWidth()/2/2, 64);
gfx.drawString(String.valueOf(rightScore), super.getWidth() - (super.getWidth()/2/2), 64);
gfx.dispose();
bs.show();
}
private void resetGame_() {
ballPosX = super.getWidth()/2 - BALL_SIZE/2;
ballPosY = super.getHeight()/2 - BALL_SIZE/2;
ballDirection = null;
ballRoll = 0;
firstBatPosY = super.getHeight()/2 - BAT_LENGTH/2;
secondBatPosY = super.getHeight()/2 - BAT_LENGTH/2;
}
boolean keyW, keyS, keyUp, keyDown;
@Override
public void keyPressed(KeyEvent _key) {
switch(_key.getKeyCode()) {
case KeyEvent.VK_W: keyW = true; break;
case KeyEvent.VK_S: keyS = true; break;
case KeyEvent.VK_UP: keyUp = true; break;
case KeyEvent.VK_DOWN: keyDown = true; break;
}
}
@Override
public void keyReleased(KeyEvent _key) {
switch(_key.getKeyCode()) {
case KeyEvent.VK_W: keyW = false; break;
case KeyEvent.VK_S: keyS = false; break;
case KeyEvent.VK_UP: keyUp = false; break;
case KeyEvent.VK_DOWN: keyDown = false; break;
}
}
@Override
public void keyTyped(KeyEvent _key) {
}
public static void main(String[] args) {
PingPong game = new PingPong();
JFrame frame = new JFrame("DrMGC's Ping-Pong");
frame.setSize(1024, 512);
frame.setLayout(new BorderLayout());
frame.setFocusable(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addKeyListener(game);
frame.add(game, BorderLayout.CENTER);
frame.setVisible(true);
game.run();
}
}
keyPressed() 메소드가 프레임 키를 통한 호출이 아닌 경우에도 리스닝은 작동하지 않습니다. 즉, 키의 코드에 문제가 없습니다.
그럼 당신이 실제로'keyXxx' 방법에서 아무것도 _do_하지 않습니다에. 변수에 값을 할당하는 것만으로 아무런 영향을 미치지 않습니다. –
이 'Swing'또는 'AWT'입니까? 이 두 가지 API를 함께 사용해야하는 이유는 무엇입니까? 'Swing' 또는'AWT'를 사용 합니다만,'AWT'에 속하는'Canvas' 대신에'JPanel/JComponent'를 그려야합니다. 또한, KeyListener (주로 포커스 관련 문제로 어려움을 겪고있는)를 통해 [KeyBindings] (http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html)를 사용하십시오. :-)이 작은 [ 예] (http://stackoverflow.com/a/18045209/1057230), [Motion using Keyboard] (http://tips4java.wordpress.com/2013/06/09/ 모션 - 키보드 사용하기), @camickr –