Yritän tehdä breakout kloonia mutta en saa key bindingseja toimimaan. KeyListenerillä toimisi muuten hyvin mutta kun tein valikon tuohon niin ilmeisesti sen jälkeen itse peli ei enään saa focusta. Eli siis voisikohan joku kertoa jotenkin suht selväsanaisesti miten key bindingsit toimii.
Tässä vielä lähdekoodia:
Edit. Sainpas toimimaan. Alla toimiva koodi jos jollain tulee sama ongelma.
package net.viped; import java.awt.Canvas; import java.awt.Color; import java.awt.Event; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.Polygon; import java.awt.Rectangle; import java.awt.Shape; import java.awt.event.ActionEvent; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.geom.AffineTransform; import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import java.awt.geom.RectangularShape; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.KeyStroke; import javax.swing.text.JTextComponent.KeyBinding; import com.sun.j3d.utils.geometry.Sphere; public class Game extends JPanel { private int BRICKSX = 40; private int BRICKSY = 5; int width = 800; int height = 640; BufferedImage backbuffer; Graphics2D g2d; boolean gameOn = false; Brick[][] bricks = new Brick[BRICKSX][BRICKSY]; BufferedImage brickImg; Saie gameloop = new Saie(); private double ballX; private double ballY; private int speed = 30; private boolean right = false; private boolean left = false; private boolean down = false; private boolean up = false; private double dx; private double dy; Ellipse2D ball; private int batx = 100; private int baty = 600; private int batWidth = 50; private Rectangle2D bat = new Rectangle2D.Double(batx, baty, batWidth, 10); private long time1; private long time2; private long time3; Action leftAction = new LeftAction(); public Game() { setFocusable(true); addBindings(); try { brickImg = ImageIO.read(new File("res/brick.png")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } initBoard(); } public void addBindings() { this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("LEFT"), "leftAction"); this.getActionMap().put("leftAction", new LeftAction()); this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released LEFT"), "leftActionReleased"); this.getActionMap().put("leftActionReleased", new LeftActionReleased()); this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("RIGHT"), "rightAction"); this.getActionMap().put("rightAction", new RightAction()); this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released RIGHT"), "rightActionReleased"); this.getActionMap().put("rightActionReleased", new RightActionReleased()); this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("UP"), "upAction"); this.getActionMap().put("upAction", new UpAction()); this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released UP"), "upActionReleased"); this.getActionMap().put("upActionReleased", new UpActionReleased()); this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("DOWN"), "downAction"); this.getActionMap().put("downAction", new DownAction()); this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("released DOWN"), "downActionReleased"); this.getActionMap().put("downActionReleased", new DownActionReleased()); this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("R"), "restartAction"); this.getActionMap().put("restartAction", new RestartAction()); } public void initBoard() { backbuffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); g2d = backbuffer.createGraphics(); for (int i = 0; i < BRICKSY; i++) { for (int j = 0; j < BRICKSX; j++) { bricks[j][i] = new Brick(); bricks[j][i].setState(0); bricks[j][i].setBounds(j * 40, i*20, 40, 20); } } ball = new Ellipse2D.Double(ballX, ballY, 10, 10); initGame(); gameloop.start(); } public void initGame() { for (int i = 0; i < BRICKSY; i++) { for (int j = 0; j < BRICKSX; j++) { bricks[j][i].setState(0); bricks[j][i].setBounds(j * 40, i*20, 40, 20); } } dx = -2; dy = -2; ballX = 250; ballY = 250; gameOn = true; } public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; super.paint(g); for (int i = 0; i < BRICKSY; i++) { for (int j = 0; j < BRICKSX; j++) { if (bricks[j][i].isAlive()) { g.drawImage(bricks[j][i].getImg(bricks[j][i].getState()), j * 40, i*20, this); g.setColor(Color.yellow); } else if (!bricks[j][i].isAlive()) { g.setColor(Color.black); g.fillRect(j * 40, i*20, 40, 20); } } } g2d.draw(bat); g2d.draw(ball); g.setColor(Color.red); AffineTransform identity = new AffineTransform(); g2d.draw(ball); // g.drawImage(backbuffer, 0, 0, this); g.dispose(); } public class Saie extends Thread { public void run() { while (gameOn) { try { Thread.sleep(speed+1); } catch (Exception e) { } // COLLISION DETECTION BRICKS for (int i = 0; i < BRICKSY; i++) { for (int j = 0; j < BRICKSX; j++) { if (bricks[j][i].intersects(ball.getBounds2D()) && bricks[j][i].isAlive()) { dy = dy * -1; if (bricks[j][i].getState() < 3) { bricks[j][i].setState(bricks[j][i].getState() + 1); } else { bricks[j][i].setAlive(false); } } } } // BAT CONTROLS if (right) { batx += 3; bat.setRect(batx, baty, batWidth, 10); } if (left) { batx -= 3; bat.setRect(batx, baty, batWidth, 10); } // BALL CONTROLLING if (ballX < 0) { dx = dx * -1; } if (ballX > width - 10) { dx = dx * -1; } if (ball.intersects(bat)) { double angle = ballX/batx; System.out.println(dy); dy = dy * -1; } if (ballY < 0) { dy = dy * -1; } ballY = ballY + dy; ballX = ballX + dx; ball.setFrame(ballX, ballY, 10, 10); repaint(); } } } final class LeftAction extends AbstractAction { public void actionPerformed(ActionEvent e) { left = true; } } final class LeftActionReleased extends AbstractAction { public void actionPerformed(ActionEvent e) { left = false; } } final class RightAction extends AbstractAction { public void actionPerformed(ActionEvent e) { right = true; } } final class RightActionReleased extends AbstractAction { public void actionPerformed(ActionEvent e) { right = false; } } final class UpAction extends AbstractAction { public void actionPerformed(ActionEvent e) { speed--; } } final class UpActionReleased extends AbstractAction { public void actionPerformed(ActionEvent e) { System.out.println(speed); } } final class DownAction extends AbstractAction { public void actionPerformed(ActionEvent e) { speed++; } } final class DownActionReleased extends AbstractAction { public void actionPerformed(ActionEvent e) { right = false; } } final class RestartAction extends AbstractAction { public void actionPerformed(ActionEvent e) { initGame(); } } }
Aihe on jo aika vanha, joten et voi enää vastata siihen.