So I am trying to make a snake game for my final project in my programming class. I am trying to add to the snake using an array, since using an array of objects is one of the requirements for the project. But I can't figure out how to make it work. Can anyone tell me what I am doing wrong?
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class FinalApplet extends Applet implements KeyListener {
private Image grass;
private Image mouse;
private Snake[] mySnake = new Snake[100];
private int x;
private int y;
public void init() {
grass = getImage(getCodeBase(), "grass.jpg");
mouse = getImage(getCodeBase(), "mouse.png");
addKeyListener(this);
}
public void update (Graphics g) {
paint(g);
}
public void paint(Graphics g) {
Image buffer = createImage(getWidth(), getHeight());
Graphics z = buffer.getGraphics();
z.drawImage(grass, 0, 0, this);
z.drawImage(mouse, 200, 130, this);
z.setColor(Color.RED);
z.fillRect(x, y, 20, 20);
g.drawImage(buffer, 0, 0, this);
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
y = y + 1;
repaint();
}
else if (e.getKeyCode() == KeyEvent.VK_UP) {
y = y - 1;
repaint();
}
else if(e.getKeyCode() == KeyEvent.VK_LEFT){
x = x - 1;
repaint();
}
else if (e.getKeyCode() == KeyEvent.VK_RIGHT){
x = x + 1;
repaint();
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
I suppose your snake starts with at least a length of 1, for it to be shown. That means that your array in its first element has a starting coordinate. All other cells of the array are empty (or null whichever you are using) and hence should not be painted on your canvas, i.e. should not be shown to your user.
A solution could be that every time your snake moves, you update each cell of your array (taking into account that each cell is a section of your snake) with its new position.
When the snake overlaps with the position of a "mouse" then the next available cell on your array should have the last position of your last (now before last) cell, taking into account that it should not move until its previous cell has moved and that only cells that have an actual value should be painted.
I hope this helps, but you should try and post more code so we could help with specific programming problems.
Related
After using a double buffer which I will show below after using imported images they still occasionally flicker. The flickering occurs only in the animated GIF sprites and not in solid tiles such as the ground of the program. I thought it may be the fact that when changing image from a standing position to the moving position of the player there is a moment with no image so it disappears but that cannot be right since the player flickers even when not changing image and just moving.
Base code of the program (compressed a lot of it and removed a bunch for simplicity of reading) :
import javax.swing.*;
import java.awt.*;
public class FrontHand extends JFrame implements Runnable{
public static void main(String []args){
// Start Main Thread
FrontHand Thread1 = new FrontHand();
Thread1.run();
}
// Define Frame Properties
private FrontHand(){
ImageImport.main();
setSize(1600, 900);
setResizable(false);
setFocusable(true);
setVisible(true);
requestFocus();
addKeyListener(new AL());
addMouseListener(new ML());
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
// Frame Double Buffer
public void paint(Graphics g){
Image dbImage = createImage(getWidth(), getHeight());
Graphics dbg = dbImage.getGraphics();
paintComponents(dbg);
g.drawImage(dbImage, 0, 0, this);
}
// Call paint functions
public void paintComponents(Graphics g){
// draw GUI
InVar.GUI.paintIcon(this, g, 0, 0);
// draw Ground Tiles
for (int i = 0; i != 10; i++) {
for (int n = 0; n != 22; n++) {
InVar.grass_tile.paintIcon(this, g, n * 62 + 118, 106 + i * 62);
// g.drawRect(n * 62 + 118, 106 + i * 62, 62, 62);
}
}
// Draw Player
InVar.player.paintIcon(this, g, InVar.player_x, InVar.player_y);
repaint();
}
// player movement
private void move(){PRETEBD THERE IS ADDITION AND SUBTRACTION TO THE PLAYER X AND Y HERE}
// check if there is any tiles left to move too and if null then redefine as non moving
if (InVar.p_m_x_counter == 0 && InVar.p_m_y_counter == 0){
InVar.player_moving = false;
// change the sprite of the player to the corresponding stationary one to the current player's sprite
if (InVar.player == InVar.player_m_up){
InVar.player = InVar.player_s_up;
}
else if (InVar.player == InVar.player_m_down){
InVar.player = InVar.player_s_down;
}
else if (InVar.player == InVar.player_m_left){
InVar.player = InVar.player_s_left;
}
else if (InVar.player == InVar.player_m_right){
InVar.player = InVar.player_s_right;
}
}
else{
InVar.player_moving = true;
}
}
#Override
public void run(){
while (InVar.game_running){
try{
Thread.sleep(5);
move();
}catch (InterruptedException e){System.out.println("Interrupted Exception Caught, ignore");}
}
}
}
The code that is used to import images :
ImageIcon a_1 = new ImageIcon(FrontHand.class.getResource("/Sprites/Tiles/GrassTile1.jpg"));
a_1.setImage(a_1.getImage());
InVar.grass_tile = a_1;
Before I was using .getScaledInstance for the animated GIF's which is what I also thought was causing the flickering but not using it and just externally changing the size of them did not fix the issue of the flickering.
how would I adjust the speed at which the ghost moves in this code? Is the required code already there and i just need to change values? or do I need to add anything? I am fairly new to coding so please try to put this in easiest form possible. thank you.
package basicgame;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class JavaGame extends JPanel {
int x, y;
// private Image dbImage;
//private Graphics dbg;
Image ghost;
Image bg;
public class AL extends KeyAdapter {
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == e.VK_LEFT) {
if (x <= 8)
x = 8;
else
x += -5;
}
if (keyCode == e.VK_RIGHT) {
if (x >= 435)
x = 435;
else
x += +5;
}
if (keyCode == e.VK_UP) {
if (y <= 18)
y = 18;
else
y += -5;
}
if (keyCode == e.VK_DOWN) {
if (y >= 325)
y = 325;
else
y += +5;
}
}
public void keyReleased(KeyEvent e) {
}
}
public JavaGame() throws Exception {
// Load images
ghost = ImageIO.read(new File("ghost.gif"));
bg = ImageIO.read(new File("myBkg.PNG"));
setFocusable(true);
// Game properties
addKeyListener(new AL());
x = 10;
y = 10;
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
repaint();
}
};
Timer timer = new Timer(10,al);
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// here, you have a 'drawimage' command for each object you're moving
// if you have 2 players, you have another drawImage for that one
// if you have a bullet, you have another for it. You have to keep
//track of each object's x,y coordinates and then draw the image at that position.
//you'll need some collision detection in there to see if bullets/players are
//in the same position and then act accordingly.
g.drawImage(bg, 0, 0, null);
g.drawImage(ghost, x, y, this);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
JFrame f = new JFrame("Java Game");
f.setSize(500, 500);
f.setResizable(false);
f.setVisible(true);
f.setBackground(Color.GRAY);
f.setContentPane(new JavaGame());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
The position is stored in the variables x and y. The "speed" of movement is described simply by the rate of change of these variables on keypress; a brief look at the code shows that this "speed" is set, rather clumsily, to 5. It appears in four different places--once for each direction vector. To change the "speed", you can just change all of these occurrences, but remember that if you forget to change some of them, the object will move at different speeds in different directions!
You could vastly improve this code by replacing all of your magic numbers with named variables. This includes not only the "speed", but also the movement boundaries: 8, 18, 435, and 325. Put these named variables inside the AL class or maybe the JavaGame class, depending on where they need to be available.
There's also an unrelated bug that I want to mention. Your current code will allow you to move out-of-bounds, and then on a subsequent keypress, move in the opposite direction indicated due to the "clipping". For example, say x = 10. If you press Left, you'll change x to 5. If you then press Left again, the boundary condition will trigger and you'll move right, setting x to 8. This is probably not desirable, so you should apply the movement first, then clip to the boundary.
Your AL class (consider a more descriptive name for this as well...) might then look something like this:
public class AL extends KeyAdapter {
private static final int SPEED = 5; // Controls the movement speed in all directions
// Variables controlling the movement boundaries
private static final int BOUND_LEFT = 8;
private static final int BOUND_RIGHT = 435;
private static final int BOUND_BOTTOM = 18;
private static final int BOUND_TOP = 325;
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == e.VK_LEFT) {
x -= SPEED; // Move left
if (x <= BOUND_LEFT) {
x = BOUND_LEFT; // If movement placed us out of bounds, move to boundary instead
}
}
if (keyCode == e.VK_RIGHT) {
x += SPEED;
if (x >= BOUND_RIGHT) {
x = BOUND_RIGHT;
}
}
if (keyCode == e.VK_UP) {
y += SPEED;
if (y >= BOUND_TOP) {
y = BOUND_TOP;
}
}
if (keyCode == e.VK_DOWN) {
y -= SPEED;
if (y <= BOUND_BOTTOM) {
y = BOUND_BOTTOM;
}
}
}
public void keyReleased(KeyEvent e) {
}
}
Working on an applet that draws 2 eyes and uses MouseMotionListener to move the they eyes. Also when the mouse exits the content pane, the eyes look straight. The one thing
I'm struggling with is I can't figure out how to restrict the pupils movements to stay within the eye. Any suggestions you guys have would be great.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class WatchMe extends JApplet
{
private int leftMouseX = 130;
private int leftMouseY = 155;
private int rightMouseX = 305;
private int rightMouseY = 155;
private boolean mouseEntered;
//init method
public void init()
{
//set background to green
getContentPane().setBackground(Color.green);
//add mouse listener
addMouseListener(new MyMouseListener());
//add a motion listener
addMouseMotionListener(new MyMouseMotionListener());
}
public void paint(Graphics g)
{
//call superclass paint method
super.paint(g);
//draw left eye
g.setColor(Color.yellow);
g.fillOval(75, 100, 150, 150);
//draw left pupil
g.setColor(Color.black);
g.fillOval(leftMouseX, leftMouseY, 40, 40);
//draw right eye
g.setColor(Color.yellow);
g.fillOval(250, 100, 150, 150);
//draw right pupil
g.setColor(Color.black);
g.fillOval(rightMouseX, rightMouseY, 40, 40);
//checks to see if the mouse is in the pane, if not
//sets the x,y coordinates to look straight
if (! mouseEntered)
{
leftMouseX = 130;
leftMouseY = 155;
rightMouseX = 305;
rightMouseY = 155;
repaint();
}
}
private class MyMouseListener implements MouseListener
{
public void mousePressed(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
mouseEntered = true;
repaint();
}
public void mouseExited(MouseEvent e)
{
mouseEntered = false;
repaint();
}
}
private class MyMouseMotionListener implements MouseMotionListener
{
public void mouseDragged(MouseEvent e)
{
leftMouseX = e.getX();
leftMouseY = e.getY();
rightMouseX = e.getX();
rightMouseY = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e)
{
leftMouseX = e.getX();
leftMouseY = e.getY();
rightMouseX = e.getX();
rightMouseY = e.getY();
repaint();
}
}
}
As a start I would recommend putting your eye dimensions in variables as shown below. This way you reduce the chance of errors when entering the same numbers more than once, and if you later decide to change the eye size or position, you only have to change it once.
public static final int LEFT_X = 75;
public static final int LEFT_Y = 100;
public static final int EYE_SIZE = 150;
We also need the left pupil to be independent of the mouse (so it doesn't follow the mouse out of the eye) so we'll do this:
private leftPupilX = 130;
private leftPupilY = 155;
Next you need to determine whether or not the mouse is currently in the left eye. This is what will restrict the pupil to the bounds of the eye. I've done this in a method for convenience.
public void setLeftEye() {
//Set the X Coord for the pupil
//Mouse is to the left of the eye
if(leftMouseX < LEFT_X) {
leftPupilX = LEFT_X;
//Mouse is to the right of the eye
} else if(leftMouseX > LEFT_X + EYE_SIZE) {
leftPupilX = LEFT_X + EYE_SIZE;
//Mouse is in eye
} else {
leftPupilX = leftMouseX;
}
//Set the Y Coord for the pupil
//Mouse is above the eye
if(leftMouseY < LEFT_Y) {
leftPupilY = LEFT_X;
//Mouse is below the eye
} else if(leftMouseY > LEFT_Y + EYE_SIZE) {
leftPupilY = LEFT_Y + EYE_SIZE;
//Mouse is in eye
} else {
leftPupilY = leftMouseY;
}
}
Finally you'll need to update the code that draws the left pupil to reflect the variable change, and actually call our new method.
//draw left pupil
setLeftEye();
g.setColor(Color.black);
g.fillOval(leftPupilX, leftPupilY, 40, 40);
These changes should make the left eye track your mouse the way you described. You'll need to do something similar for the right eye, since it has different coordinates. If you have any problems, let me know and I will try to help. :)
I am fairly new to Java and LWJGL. I am trying to make a 2d sprite change appearance so it faces in the direction that you are holding, how would I go about this?
So far I have this-
package keyboardinputdb;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
public class KeyboardInputDB extends JFrame{
//Variables
int x, y, scoreCount;
private Image dbImage;
private Graphics dbg;
Image littleAdventurer;
boolean faceLeft;
boolean faceRight;
boolean faceUp;
Font font = new Font("Arial", Font.BOLD, 18);
//Action Listener
public class AL extends KeyAdapter {
public void keyPressed(KeyEvent e){
int keyCode = e.getKeyCode();
if(keyCode == e.VK_LEFT){
x-=3;
if(x <= 0){
x = 0;
}
}
if(keyCode == e.VK_RIGHT){
x+=3;
if(x >= 235){
x = 235;
}
}
if(keyCode == e.VK_UP){
y-=3;
if(y <= 20){
y = 20;
}
}
if(keyCode == e.VK_DOWN){
y+=3;
if(y >= 235){
y = 235;
}
}
}
public void keyReleased(KeyEvent e){
}
}
public KeyboardInputDB(){
//Load Images
ImageIcon i = new ImageIcon("C:/Users/Clive/Documents/NetBeansProjects/KeyboardInput with DB/src/keyboardinputdb/littleAdventurer.gif");
littleAdventurer = i.getImage();
//Game Properties
addKeyListener(new KeyboardInputDB.AL());
setTitle("Java Game");
setSize(600, 500);
setResizable(false);
setVisible(true);
setBackground(Color.black);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
x = 150;
y = 150;
scoreCount = 0;
}
public void paint(Graphics g){
dbImage = createImage(getWidth(), getHeight());
dbg = dbImage.getGraphics();
paintComponent(dbg);
g.drawImage(dbImage, 0, 0, this);
}
public void paintComponent(Graphics g){
g.setFont(font);
g.setColor(Color.white);
g.drawString("Score: " + scoreCount, 450, 70);
if(faceLeft = true){
g.drawImage(littleAdventurer, x, y, this);
}
else{
g.setColor(Color.white);
g.fillOval(x, y, 15, 15);
}
repaint();
}
public static void main(String[] args) {
KeyboardInputDB javagame = new KeyboardInputDB();
}
}
Any help with this would be appreciated.
First of all, your main problem is that you're using jFrame instead of LWJGL. I would recommend that you change to LWJGL first. You're also using three boolean variables for which direction your sprite is facing. What happens when both faceLeft and faceRight are true? You should use enums instead.
I assume you're new to Java, so I'll give you a little tutorial in enums...
1st, add this to the top of your class where you declare your varaibles:
public static enum Direction{
UP, DOWN, LEFT, RIGHT
}
public static Direction direction = Direction.DOWN;
You can now use this code to check if an enum is a certain value:
if(direction == Direction.LEFT){
//Do something.
}
You can also set an enum simply by calling:
direction = Direction.RIGHT;
And even easier way to check an enum's vause is by using a switch statement:
switch(direction){
case UP:
//Do something when up.
break;
case DOWN:
//Do something when down.
break;
case LEFT:
//Do something when left.
break;
case RIGHT:
//Do something when right.
break;
}
This best way that I can describe an enum to beginners is similar to a boolean (where it has a limited amount of options) but you can make as many options as you want.
Your current system also isn't using LWJGL, so I recommend changing to that if that's what you would like to use. Making a game is much easier with LWJGL than jFrame once you learn how to use OpenGL.
This page will prove useful: http://lwjgl.org/wiki/index.php?title=Main_Page#Getting_started
Just made quads first, then you can easily learn how to add a sprite in and rotate it using glRotatef()
Would anyone be able to tell me why this program says I am missing a main method? I have one at the bottom of this code.
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class Collision extends JFrame
{
final int WIDTH = 900, HEIGHT = 650;
double p1Speed = .5, p2Speed = .5;
//these are the ints that represent directions
final int UP = 0, RIGHT = 1, DOWN = 2, LEFT = 3;
//these will keep track of the players directions(default = up)
int p1Direction = UP;
int p2Direction = UP;
Rectangle left = new Rectangle(0,0,WIDTH/9,HEIGHT);
Rectangle right = new Rectangle((WIDTH/9)*8,0,WIDTH/9,HEIGHT);
Rectangle top = new Rectangle(0,0,WIDTH,HEIGHT/9);
Rectangle bottom = new Rectangle(0,(HEIGHT/9)*8, WIDTH,HEIGHT/9);
Rectangle center = new Rectangle((int)((WIDTH/9)* 2.5),(int)((HEIGHT/9)*2.5),(int)
((WIDTH/9)*5),(HEIGHT/9)*4);
Rectangle obstacle = new Rectangle(WIDTH/2,(int)((HEIGHT/9)*7),WIDTH/10,HEIGHT/9);
Rectangle obstacle2 = new Rectangle(WIDTH/3,(int)((HEIGHT/9)*5),WIDTH/10,HEIGHT/4);
Rectangle obstacle3 = new Rectangle(2*(WIDTH/3),(int)
((HEIGHT/9)*5),WIDTH/10,HEIGHT/4);
Rectangle obstacle4 = new Rectangle(WIDTH/3,HEIGHT/9,WIDTH/30,HEIGHT/9);
Rectangle obstacle5 = new Rectangle(WIDTH/2,(int)((HEIGHT/9)*1.5),WIDTH/30,HEIGHT/4);
Rectangle finish = new Rectangle(WIDTH/9,(HEIGHT/2)-HEIGHT/9,(int)
((WIDTH/9)*1.5),HEIGHT/70);
Rectangle p1 = new Rectangle(WIDTH/9,HEIGHT/2, WIDTH/30,WIDTH/30);
Rectangle p2 = new Rectangle(((WIDTH/9)+((int)((WIDTH/9)*1.5)/2)),(HEIGHT/2)+
(HEIGHT/10),WIDTH/30,WIDTH/30);
public Collision()
{
//the following code creates the JFrame
super("Radical Racing");
setSize(WIDTH,HEIGHT);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
//start the inner class (which works on it's own because it is a thread)
Move1 m1 = new Move1();
Move2 m2 = new Move2();
m1.start();
m2.start();
}
public void paint(Graphics g)
{
super.paint(g);
//draw the bckround for the racetrack
g.setColor(Color.DARK_GRAY);
g.fillRect(0,0,WIDTH,HEIGHT);
//When we drawthe border will be green
g.setColor(Color.GREEN);
//the following rectangle is the start line for the outer player
Rectangle lineO = new
Rectangle(WIDTH/9,HEIGHT/2,(int)((WIDTH/9)*1.5)/2,HEIGHT/140);
//the following rctangle is the start line for the inner player
Rectangle lineI = new
Rectangle(((WIDTH/9)+((int)((WIDTH/9)*1.5)/2)),(HEIGHT/2)+(HEIGHT/10),
(int)((WIDTH/9)*1.5)/2,HEIGHT/140);
//now using the rectangles, draw it
g.fillRect(left.x,left.y,left.width,left.height);
g.fillRect(right.x,right.y,right.width,right.height);
g.fillRect(top.x,top.y,top.width,top.height);
g.fillRect(bottom.x,bottom.y,bottom.width,bottom.height);
g.fillRect(center.x,center.y,center.width,center.height);
g.fillRect(obstacle.x,obstacle.y,obstacle.width,obstacle.height);
g.fillRect(obstacle2.x,obstacle2.y,obstacle2.width,obstacle2.height);
g.fillRect(obstacle3.x,obstacle3.y,obstacle3.width,obstacle3.height);
g.fillRect(obstacle4.x,obstacle4.y,obstacle4.width,obstacle4.height);
g.fillRect(obstacle5.x,obstacle5.y,obstacle5.width,obstacle5.height);
//set the starting line color
g.setColor(Color.WHITE);
//the draw the starting line
g.fillRect(lineO.x,lineO.y,lineO.width,lineO.height);
g.fillRect(lineI.x,lineI.y,lineI.width,lineI.height);
//set the color of the finish line to yellow
g.setColor(Color.YELLOW);
g.fillRect(finish.x,finish.y,finish.width,finish.height);
//set the color to blue for p1
g.setColor(Color.BLUE);
//now draw the actual player
g.fill3DRect(p1.x,p1.y,p1.width,p1.height,true);
//set the color to red for p2
g.setColor(Color.red);
//now draw the actual player
g.fill3DRect(p2.x,p2.y,p2.width,p2.height,true);
}
private class Move1 extends Thread implements KeyListener
{
public void run()
{
//add the code to make the KeyListener "wake up"
addKeyListener(this);
//now, put the code should all be in an infinite loop, so the process repeats.
while(true)
{
try
{
//first refresh the screen:
repaint();
//check to see if the car hits the outside of the walls.
//If so make it slow it's speed by setting it's speed to .4.
if(p1.intersects(left) || p1.intersects(right) ||
p1.intersects(top) || p1.intersects(bottom) ||
p1.intersects(obstacle) || p1.intersects(obstacle2) ||
p1.intersects(p2) || p1.intersects(obstacle3) ||
p1.intersects(obstacle4) || p1.intersects(obstacle5))
{
p1Speed = -4;
}
if(p1.intersects(center))
{
p1Speed = -2.5;
}
//increase speed a bit
if(p1Speed<=5)
p1Speed+=.2;
//these will move the player based on direction
if(p1Direction == UP)
{
p1.y-=(int)p1Speed;
}
if(p1Direction ==DOWN)
{
p1.y+=(int)p1Speed;
}
if(p1Direction == LEFT)
{
p1.x-=(int)p1Speed;
}
if(p1Direction == RIGHT)
{
p1.x+=(int)p1Speed;
}
//This delays the refresh rate
Thread.sleep(75);
}
catch(Exception e)
{//if there is an exception (an error), exit the loop
break;
}
}
}
//You must also implement this method from Key Listener
public void keyPressed(KeyEvent event)
{
}
//You must also implement this method from key listener
public void keyReleased(KeyEvent event)
{
}
//You must also implement this method from key listener
public void keyTyped(KeyEvent event)
{
if(event.getKeyChar()=='a')
{
p1Direction = LEFT;
}
if(event.getKeyChar()=='s')
{
p1Direction = DOWN;
}
if(event.getKeyChar()=='d')
{
p1Direction = RIGHT;
}
if(event.getKeyChar()=='w')
{
p1Direction = UP;
}
}
}
private class Move2 extends Thread implements KeyListener
{
public void run()
{
//add the code to make the key listener wake up
addKeyListener(this);
//now this should all be in an infinite loop so that the process repeats
while(true)
{
try
{
//first refresh the screen
repaint();
//check to see if the car hits the outside walls.
//if so make it slow its speed by setting it's speed to -4.
if(p2.intersects(left) || p2.intersects(right) ||
p2.intersects(top) || p2.intersects(bottom) ||
p2.intersects(obstacle) || p2.intersects(obstacle2) ||
p1.intersects(p2))
{
p2Speed = -4;
}
if(p2.intersects(center))
{
p2Speed = -2.5;
}
//increase speed a bit
if(p2Speed<=5)
p2Speed = .2;
//these will move the player based off direction
if(p2Direction == UP)
{
p2.y-=(int)p2Speed;
}
if(p2Direction ==DOWN)
{
p2.y+=(int)p2Speed;
}
if(p2Direction == LEFT)
{
p2.x-=(int)p2Speed;
}
if(p2Direction == LEFT)
{
p2.x+=(int)p2Speed;
}
//this delays the refresh rate:
Thread.sleep(75);
}
catch(Exception e)
{
//if there is an exception, exit the loop.
break;
}
}
}
//you must also implement this method from key listener
public void keyPressed(KeyEvent event)
{
}
public void keyReleased(KeyEvent event)
{
}
public void keyTyped(KeyEvent event)
{
if(event.getKeyChar()=='j')
{
p2Direction = LEFT;
}
if(event.getKeyChar()=='k')
{
p2Direction = DOWN;
}
if(event.getKeyChar()=='l')
{
p2Direction = RIGHT;
}
if(event.getKeyChar()=='i')
{
p2Direction = UP;
}
}
//This starts the program by calling the constructor:
public static void main(String [] args)
{
new Collision();
}
}
KeyListeners only work if the component listened to has the focus, and often KeyListeners fail because this is not so. So one thing to do is to test this, and if the component has lost the focus than do things to correct this.
But having said this, I have to ask what book you're using, since in general, you want to avoid using KeyListeners with Swing applications in favor of Key Bindings. Also, it is usually not recommended to draw directly in a JFrame, so you may wish to use a different book.