Snake Game. Handle keyPressed method - java

I got the snake running down, now I try to get the keypressed() method to work. I don't think it's listening from the keyboard. My idea is for example if the the down key is pressed, the variable direction is set to 1 and the switch case statement would handle that. I doubt that the direction variable was't read by the switch case.
My main class:
package com.bin.snake;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Game extends JPanel{
boolean playingSnake = true;
Snake snake = new Snake();
public Game() {
addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
snake.keyPressed(e);
}
});
setFocusable(true);
}
public void paint(Graphics g) {// inherit paint method of JPanel class with
// parameter g type Graphics
// parameter g is the object to paint things
super.paint(g); // erase latest image
Graphics2D g2d = (Graphics2D) g; // casting g to Graphics2D type
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// rendering
// image
snake.paint(g2d);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Snake!");
frame.setVisible(true);
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Game game = new Game();
frame.add(game);
while (true) {
game.updateGame();
game.repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void updateGame() {
snake.moveSnake();
}
}
My Snake Class:
package com.bin.snake;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
public class Snake {
private Game game;
int iSnakeLength = 10;
int direction = 1;
final int SIDE = 13;
int[] snakeY = new int[2000];
int[] snakeX = new int[2000];
int xs = 0;
int ys = 0;
public void moveSnake() {
switch (direction) {
case 0:// up
snakeY[0] -=1.5;
break;
case 1:// down
snakeY[0] += 1.5;
break;
case 2:// right
snakeX[0] += 1.5;
break;
case 3:// left
snakeX[0] -=1.5;
break;
}
for (int i = iSnakeLength; i > 0; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
}
public void paint(Graphics2D g) {
g.fillRect(snakeX[0], snakeY[0], SIDE, SIDE);
for (int i = 0; i < iSnakeLength; i++) {
g.fillRect(snakeX[i + 1], snakeY[i + 1], SIDE, SIDE);
}
}
public void keyPressed(KeyEvent e){
if(e.getKeyCode() == KeyEvent.VK_DOWN){
direction = 1;
}
if(e.getKeyCode() == KeyEvent.VK_UP){
direction = 0;
}
if(e.getKeyCode() == KeyEvent.VK_LEFT){
direction = 3;
}
if(e.getKeyCode() == KeyEvent.VK_RIGHT){
direction = 2;
}
}
}

I don't think it's listening from the keyboard. My idea
KeyEvents are only dispatched to the component with focus. A JPanel is not focusable by default.
To make a panel focusable you use:
panel.setFocusable( true );
Other comments:
Custom painting is done by overriding the paintComponent(...) method, not the paint() method. Read the Swing tutorial on Custom Painting for more information and examples.
You should NOT be using a KeyListener. Swing was designed to be used with Key Bindings. Read the Swing tutorial on How to Use Key Bindings. You can also check out Motion Using the Keyboard which contains working examples of moving a component using Key Bindings.
For animation you should be using a Swing Timer to schedule the animation. Check the table of contents from the tutorial links I have already provided. There is a section on How to Use Swing Timers.

Related

How to make a rectangle move with multiple direction keys at once?

Hi this may be very stupid, but please try to understand that I am an absolute beginner at Java programming. I have been trying to learn it on my own from the internet.
I was trying to make a simple Applet that can move a square using the KeyListener.
First I made a version that can only detect one key at a time. So I looked up a tutorial on YouTube (https://www.youtube.com/watch?v=5UaEUrbpDPE). It used an ArrayList to somehow handle the issue with what was referred to as "Ghosting". The tutorial showed flawless results but my code resulted in some weird problems:
Initially the square moved smoothly in any direction for some time. The square could mainly be moved down and right. After pressing up or left a few times the square could no longer be moved!!!
Can anyone please guide me on what I am doing wrong or how else this could have been accomplished?
Here is the code that I began with (One button at a time detection):
package boxHero;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class boxGame extends Applet implements KeyListener {
private Rectangle rect;
private int x = 20, y = 20, recW = 50, recH = 50;
public void init() {
setSize(600, 500);
setBackground(Color.BLACK);
this.addKeyListener(this);
rect = new Rectangle (x, y, recW, recH);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setColor(Color.YELLOW);
g2.fill(rect);
}
#Override
public void keyPressed(KeyEvent e) {
// Can't detect more than one key at a time
if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
rect.setLocation(rect.x + 10, rect.y);
}
else if(e.getKeyCode() == KeyEvent.VK_LEFT) {
rect.setLocation(rect.x - 10, rect.y);
}
else if(e.getKeyCode() == KeyEvent.VK_UP) {
rect.setLocation(rect.x, rect.y - 10);
}
else if(e.getKeyCode() == KeyEvent.VK_DOWN) {
rect.setLocation(rect.x, rect.y + 10);
}
repaint();
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
}
Here's the code from the YouTube tutorial:
package boxHero;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
public class boxGame2 extends Applet implements KeyListener {
private Rectangle rect; // Declaring a rectangle object
private ArrayList<Integer> keysDown;
private int x = 20, y = 20, recW = 50, recH = 50;
public void init() {
setSize(600, 500); // Initial screen size
setBackground(Color.BLACK); // Setting background
this.addKeyListener(this); // Adding KeyListener
keysDown = new ArrayList<Integer>();
rect = new Rectangle (x, y, recW, recH); // Instantiating and Initializing(setting values) for our Rectangle
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
// Graphics for our rectangle
g2.setColor(Color.YELLOW);
g2.fill(rect);
}
public void moveRect() {
int x = rect.x;
int y = rect.y;
if(keysDown.contains(KeyEvent.VK_UP)) {
y -= 10;
}
if(keysDown.contains(KeyEvent.VK_DOWN)) {
y += 10;
}
if(keysDown.contains(KeyEvent.VK_LEFT)) {
x -= 10;
}
if(keysDown.contains(KeyEvent.VK_RIGHT)) {
x += 10;
}
rect.setLocation(x, y);
repaint();
}
#Override
public void keyPressed(KeyEvent e) {
if(!keysDown.contains(e.getKeyCode()) && e.getKeyCode() != 86) {
keysDown.add(new Integer(e.getKeyCode()));
}
moveRect();
}
#Override
public void keyReleased(KeyEvent e) {
keysDown.remove(e);
}
#Override
public void keyTyped(KeyEvent e) {
}
}
The diference between your code and the tutorial is, that the tutorial uses a list of keys that are currently pressed, while you only check out, WHICH key is pressed.
Make an ArrayList of keys like in the tutorial, then add each key when pressed and remove it, as soon as released. Then you can move your rectangle for every key that is contained in your list.
In your keyPressed() event, you add e.getKeyCode() to your keysDown list. But in your keyReleased() event, you only try to remove e from your list, which should result in nothing ever getting removed and all keys remaining pressed. So the reason it doesn't move after a few presses is that you are basically pressing left, right, up and down at once, causing them to cancel each other out.
Also, you should make a habit of using Integer.valueOf(x) instead of new Integer(x), since it caches values in the range of [-128;127], resulting in much better performance when creating wrappers for values in that range.

Player sprite won't move in Java 2D game (repaint)

I am new to Java and I am trying to make a simple game for fun.
I first tried to put repaint into paintComponent(), it worked until I tried to add some background.
Does anyone know how to let my player move with or without 'repaint'?
Screen class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Frame extends JFrame implements KeyListener
{
Map map;
public static void main(String[] args)
{
Frame frame = new Frame();
frame.addKeyListener(new Frame());
frame.setVisible(true);
}
public Frame()
{
setInit();
}
private void setInit()
{
map = new Map();
add(map);
setSize(800, 800);//frame size 300 width and 300 height
setTitle("Eerste Game");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setResizable(false);
setLayout(new GridLayout(1,1,0,0));
setFocusable(true);
setVisible(true);
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
map.movePlayer(keyCode);
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
}
Map class
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
class Map extends JPanel
{
Player player;
BufferedImage map;
public Map() {
player = new Player();
try{map = ImageIO.read(new File("img/map.png"));}catch (Exception e){};
}
public void movePlayer(int keyPressed)
{
player.move(keyPressed);
revalidate();
repaint();
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(player.img,player.getX(),player.getY(), null);
}
}
Player class
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
class Player
{
BufferedImage img = null;
private int x = 100;
private int y = 100;
public Player()
{
try{img = ImageIO.read(new File("img/bob.png"));}catch (Exception e){}
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public void move(int keyPressed)
{
if(keyPressed == KeyEvent.VK_W) {
// handle up
y = y - 5;
}
if (keyPressed == KeyEvent.VK_A) {
// handle links
x = x - 5;
}
if (keyPressed == KeyEvent.VK_S) {
// handle onder
y = y + 5;
}
if (keyPressed == KeyEvent.VK_D ) {
// handle right
x = x + 5;
}
}
}
You're unnecessarily creating a new Frame object as the KeyListener, and so the KeyListener events all go to a different Frame instance, not the one being shown. Change
frame.addKeyListener(new Frame());
to:
frame.addKeyListener(frame);
So that now the KeyListener drives the true displayed Frame instance of interest.
Other issues, this is not good:
catch (Exception e){}
Always catch specific exceptions and almost always, you should handle them. At least do something like this:
catch (IOException e) {
e.printStacktrace();
}
You do:
frame.addKeyListener(new Frame());
Which creates a new frame instead of adding the current frame as the Listener.
So you change it tO
frame.addKeyListener(frame);

Learning KeyEvents

I am relatively new to java and was trying to learn how to make a program where there is this circle and I can move it around using the arrow keys. After shifting through a bunch of examples I was able to put something together. Although I am unsure how to create a KeyEvent. Any help with what I am missing would be awesome.
This is what I have so far.
import javax.swing.WindowConstants;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.event.KeyEvent;
#SuppressWarnings("serial")
public class Game extends JPanel
{
int x = 0;
int y = 0;
private void moveBallUP() {
x = x + 0;
y = y + 1;
}
private void moveBallDOWN() {
x = x + 0;
y = y - 1;
}
private void moveBallLEFT() {
x = x + 1;
y = y + 0;
}
private void moveBallRIGHT() {
x = x - 1;
y = y + 0;
}
#Override
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.red);
g2d.fillOval(y, x, 50, 50);
}
public static void main(String[] args) throws InterruptedException
{
JFrame frame = new JFrame("Sample Frame");
Game game = new Game();
frame.add(game);
frame.setSize(300, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
if (event.getKeyCode() == KeyEvent.VK_UP)
{
game.moveBallUP();
game.repaint();
Thread.sleep(10);
}
if (event.getKeyCode() == KeyEvent.VK_DOWN)
{
game.moveBallDOWN();
game.repaint();
Thread.sleep(10);
}
if (event.getKeyCode() == KeyEvent.VK_LEFT)
{
game.moveBallLEFT();
game.repaint();
Thread.sleep(10);
}
if (event.getKeyCode() == KeyEvent.VK_RIGHT)
{
game.moveBallRIGHT();
game.repaint();
Thread.sleep(10);
}
}
}
There are several steps to solving this: first, use a KeyListener. Add the following code to the Game class; this will represent which buttons are pressed:
private boolean upPressed=false;
private boolean downPressed=false;
private boolean leftPressed=false;
private boolean rightPressed=false;
Then, add this to the main method:
frame.addKeyListener(new KeyListener() {
#Override
public void keyReleased(KeyEvent event) {
switch (event.getKeyCode()) {
case KeyEvent.VK_UP:
game.upPressed=false;
break;
case KeyEvent.VK_DOWN:
game.downPressed=false;
break;
case KeyEvent.VK_LEFT:
game.leftPressed=false;
break;
case KeyEvent.VK_RIGHT:
game.rightPressed=false;
break;
}
}
#Override
public void keyTyped(KeyEvent event) {
}
#Override
public void keyPressed(KeyEvent event) {
switch (event.getKeyCode()) {
case KeyEvent.VK_UP:
game.upPressed=true;
break;
case KeyEvent.VK_DOWN:
game.downPressed=true;
break;
case KeyEvent.VK_LEFT:
game.leftPressed=true;
break;
case KeyEvent.VK_RIGHT:
game.rightPressed=true;
break;
}
}
});
Basically, you are setting the variables we created to true when the buttons are pressed down and false when they are released. Finally, add a Timer in the main method:
Timer timer = new Timer(10,(e)->{
if (game.upPressed)
{
game.moveBallUP();
game.repaint();
}
if (game.downPressed)
{
game.moveBallDOWN();
game.repaint();
}
if (game.leftPressed)
{
game.moveBallLEFT();
game.repaint();
}
if (game.rightPressed)
{
game.moveBallRIGHT();
game.repaint();
}
});
timer.start();
This will fire every 10 milliseconds and call your move methods if the buttons are pressed.
I have tested this and know that it works, however your move methods move the circle in the wrong directions. I assume you can fix that.
EDIT: The mistake is in this line:
g2d.fillOval(y, x, 50, 50);
Change it to:
g2d.fillOval(x,y , 50, 50);

My picture is moving too slowly

I am currently making a kind of adventure 2D game project for university.
I have drawn an array of pictures(walls,floor etc) and then the movable hero figure. The problem: without the array the figure is moving fine but with the array the movement starts to lag hard. Is it my Pc? or is my drawing method too "heavy"? Please take a look:
import java.awt.Graphics;
import java.awt.Rectangle;
public class World {
public static int WorldW = 16 , WorldH = 16;
public SpielElement[][] element = new SpielElement[WorldW][WorldH];
public int[][] level0 ={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0},
{0,0,0,1,1,1,1,1,1,1,1,6,0,0,0,0},
{0,0,0,1,1,1,5,1,1,1,1,1,0,0,0,0},
{0,0,0,1,1,6,1,1,2,1,5,1,0,0,0,0},
{0,0,0,1,1,1,1,5,1,1,1,1,0,0,0,0},
{0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0},
{0,0,0,0,0,1,1,3,1,1,0,0,0,0,0,0},
{0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
public int[][] level1 ={{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,1,0,0,0,0,1,1,1,1,2,0,1,0},
{0,4,0,1,0,0,5,1,1,1,1,1,1,0,1,0},
{0,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0},
{0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,0},
{0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0},
{0,1,1,1,0,0,1,1,1,1,1,0,0,1,0,0},
{0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0},
{0,1,0,1,1,1,1,1,1,1,1,1,0,0,3,0},
{0,1,0,1,0,0,0,0,0,1,0,1,0,0,1,0},
{0,1,0,1,1,1,1,0,0,1,0,1,0,0,1,0},
{0,1,0,1,0,0,1,0,0,1,0,1,1,1,1,0},
{0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,0},
{0,1,1,1,1,6,1,1,0,1,0,0,1,0,0,0},
{0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
public World(){
create();
}
public void create(){
for(int x = 0; x<WorldW; x++){
for(int y = 0; y<WorldH; y++){
element[x][y] = new SpielElement(x,y,level0[y][x]);
}
}
}
public void generate(Graphics g){
for(int x = 0; x<WorldW; x++){
for(int y = 0; y<WorldH; y++){
element[x][y].zeichne(g);
}
}
}
}
Well the int array is to define which kind of picture I need to draw and
i intend to first create all the Panels (SpielElement) and then draw them
Here is how i Draw them:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class SpielElement extends JPanel{
int posX,posY,type ;
BufferedImage wand, boden, tuer, schluessel;
public SpielElement(int x, int y,int z){
this.posX = x*40;
this.posY = y*40;
this.type = z;
try {
wand = ImageIO.read(SpielElement.class.getResource("/img/wand.png"));
boden = ImageIO.read(SpielElement.class.getResource("/img/boden.png"));
tuer = ImageIO.read(SpielElement.class.getResource("/img/tuer.png"));
schluessel = ImageIO.read(SpielElement.class.getResource("/img/schluessel.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void zeichne(Graphics g){
switch(type){
case 0: g.drawImage(wand,posX,posY,boden.getWidth(),wand.getHeight(),null);
break;
case 1:g.drawImage(boden,posX,posY,boden.getWidth(),boden.getHeight(),null);
break;
case 2: g.drawImage(schluessel,posX,posY,schluessel.getWidth(),schluessel.getHeight(),null);
break;
case 3: g.drawImage(tuer,posX,posY,tuer.getWidth(),tuer.getHeight(),null);
break;
case 4: g.drawImage(boden,posX,posY,boden.getWidth(),boden.getHeight(),null);
break;
case 5:g.drawImage(boden,posX,posY,boden.getWidth(),boden.getHeight(),null);
break;
case 6: g.drawImage(boden,posX,posY,boden.getWidth(),boden.getHeight(),null);
break;
}
}
}
I hope u get what I am thinking by reading the code and hopefully see what is wrong. There are no Syntax errors whatsoever but its so damn slow. In the end added all of this onto a JPanel Board which is added on a JFrame
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Board extends JPanel implements KeyListener{
private final int BREITE = 700;
private final int HOEHE = 700;
Hunter Held ;
World Welt;
public Board(){
super();
Held = new Hunter(200,200);
Welt = new World();
this.setBackground(Color.BLACK);
}
public void paint(Graphics g){
super.paint(g);
Welt.generate(g);
Held.draw(g);
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if (e.getKeyCode() == KeyEvent.VK_LEFT)
Held.posX = Held.posX - 10;
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
Held.posX = Held.posX + 10;
if (e.getKeyCode() == KeyEvent.VK_UP)
Held.posY = Held.posY - 10;
if (e.getKeyCode() == KeyEvent.VK_DOWN)
Held.posY = Held.posY + 10;
this.repaint();
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}
the Hero(Held) is drawn the exact way like the other images with its Coordinates beeing altered everytime i press keys and thus repainted.
I will refrain from further code dumping at this point. This is how it looks like in the end:
http://puush.me/account?pool=1468274
(Sorry no reputation yet)
The figure on Scrren moves on KeyInput but with lags...
This is my first question and i hope it is detailed enough.
Sry in advance if my problem is stupid only started 2 weeks ago with programming in general.
Constructive critizism is adviced. sry for code Dumping...
Until I saw you mentioned JPanel and JFrame, I thought it was an Android related question...
Anyway maybe you should draw them in a new thread, on an invisible canvas/image/cache, whatever... then bring it to front and draw another frame in background.
Sorry, I don't know how to do it with Swing, but I think that's how all animation frameworks work. In Android people do all these dirty work in background thread...

KeyListener not responding in Java swing

I'm making a game, and I have a Main Menu that works perfectly. When I select one of the options, it brings up another Menu in a new window. However in this new window, the KeyListener is not responding. If I click back to the Main Menu window, the KeyListener is still working there. Here is the code:
MainMenu:
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.io.*;
import javax.imageio.*;
public class DisplayMainMenu extends JFrame implements KeyListener{
static int width = 799, height = 463;
int arrowPos = 310;
boolean clear = true;
BufferedImage menu = null;
BufferedImage arrow = null;
LevelSkip test = new LevelSkip();
boolean done = false;
static DisplayMainMenu main;
public static void main(String[] args){
main = new DisplayMainMenu();
main.setResizable(false);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setVisible(true);
main.init();
}
public void init() {
try{
menu = ImageIO.read(new File("Main Menu.png"));
arrow = ImageIO.read(new File("arrow.png"));
}catch(IOException ie) {
System.out.println(ie.getMessage());
}
this.setSize(width, height);
this.addKeyListener(this);
clear = true;
paint(getGraphics());
}
public void paint (Graphics g){
if(clear==true){
g.drawImage(menu,0,0,null);
clear = false;
}
g.drawImage(arrow,275,arrowPos,null);
}
public void keyPressed(KeyEvent e){
String key = e.getKeyText(e.getKeyCode());
if(key == "Up"){
clear = true;
if (arrowPos > 310)
arrowPos -= 30;
else
arrowPos = 370;
paint(getGraphics());
}
if(key == "Down"){
clear = true;
if (arrowPos < 370)
arrowPos += 30;
else
arrowPos = 310;
paint(getGraphics());
}
if(key == "Space"){
done = true;
switch(arrowPos){
case 310: System.out.println("RUN NEW GAME"); test.init();
break;
case 340: System.out.println("RUN HIGH SCORES");
break;
case 370: System.exit(0);
}
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
LevelSkip:
import java.awt.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import java.io.*;
import javax.imageio.*;
public class LevelSkip extends JFrame implements KeyListener {
static int width = 799, height = 463;
int arrowPos = 109;
boolean clear = true;
BufferedImage menu = null;
BufferedImage arrow = null;
public void init() {
LevelSkip main = new LevelSkip();
main.setSize(width, height);
main.requestFocusInWindow();
main.addKeyListener(main);
main.setResizable(false);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setVisible(true);
try{
menu = ImageIO.read(new File("level skip.png"));
arrow = ImageIO.read(new File("arrow2.png"));
}catch(IOException ie) {
System.out.println(ie.getMessage());
}
clear = true;
paint(main.getGraphics());
}
public void paint (Graphics g){
if(clear==true){
g.drawImage(menu,0,0,null);
clear = false;
}
g.drawImage(arrow,arrowPos,355,null);
}
public void keyPressed(KeyEvent e){
String key = e.getKeyText(e.getKeyCode());
if(key == "Left"){
clear = true;
if (arrowPos > 109)
arrowPos -= 260;
else
arrowPos = 629;
paint(getGraphics());
}
if(key == "Right"){
clear = true;
if (arrowPos < 629)
arrowPos += 260;
else
arrowPos = 109;
paint(getGraphics());
}
if(key == "Space"){
switch(arrowPos){
case 109: System.out.println("ADD 1 TO LEVEL AND RUN BATTLE");
break;
case 369: System.out.println("ADD 5 TO LEVEL AND RUN BATTLE");
break;
case 629: System.out.println("ADD 10 TO LEVEL AND RUN BATTLE");
}
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
I'm not exactly sure what the problem is, the Level Skip window displays fine, it just doesn't register any key presses.
If you've searched on this problem at all, you'll see that it almost always means that the component being listened to doesn't have focus. 90% of the time the solution is to use Key Bindings.
Your other problem is that you're comparing Strings ==. You don't want to do this. Use the equals or the equalsIgnoreCase(...) method instead. Understand that == checks if the two objects are the same which is not what you're interested in. The methods on the other hand check if the two Strings have the same characters in the same order, and that's what matters here. So instead of
if (fu == "bar") {
// do something
}
do,
if (fu.equals("bar")) {
// do something
}
or,
if (fu.equalsIgnoreCase("bar")) {
// do something
}
You're also
calling paint(...) directly, something you should almost never do.
Drawing in a top level window's paint(...) method which you also should avoid instead of drawing in a JPanel's (or other JComponent) paintComponent(...) method.
Not calling the paint or paintComponent's super method at the start of the method
Putting program logic in a paint or paintComponent method.
etc...
You will want to go through the Swing tutorials before going much further to learn from the pros.

Categories