main methods and key listener - java

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.

Related

Space Invaders Game - Only one bullet is firing when space bar is pressed. How to get multiple bullets to fire?

I am making a space invaders game but I can only get one bullet to fire, how can I get multiple bullets to fire when the space bar is pressed?
I am currently only using rectangles for the spaceship and for the bullets.
This is the main class. This contains the the size of the frame for the space invader game.
public static void main(String[] args) {
JFrame jf = new JFrame();
jf.setTitle("Shooter");
jf.setSize(700, 500);
jf.setResizable(false);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Shooter ss = new Shooter();
jf.add(ss);
jf.setVisible(true);
Thread t = new Thread(ss);
t.start();
}
This is the shooter class. Here I draw the bullet and spaceship and set the left and right controls for the movement of the spaceship.
public class Shooter extends JPanel implements KeyListener, Runnable {
int rectXPos = (700 / 2) - 50 / 2;
int rectYPos = 425;
boolean rightPressed, leftPressed, spaceBarPressed, fireBullet, shot;
Rectangle bullet;
int bulletXPos, bulletYPos;
public Shooter() {
addKeyListener(this);
this.setFocusTraversalKeysEnabled(false);
this.setFocusable(true);
}
public void paintComponent(Graphics g) {
g.setColor(Color.BLUE);
g.drawRect(0, 0, 700, 500);
g.fillRect(0, 0, 700, 500);
g.setColor(Color.YELLOW);
g.drawRect(rectXPos, rectYPos, 50, 30);
g.fillRect(rectXPos, rectYPos, 50, 30);
if (shot) {
g.setColor(Color.RED);
g.fillRect(bullet.x, bullet.y, bullet.width, bullet.height);
}
repaint();
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
rightPressed = true;
if (rectXPos >= 630) {
rectXPos = 630;
} else {
moveRight();
}
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
leftPressed = true;
if (rectXPos <= 5) {
rectXPos = 5;
} else {
moveLeft();
}
}
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
if (bullet == null) {
fireBullet = true;
if (fireBullet) {
bulletXPos = rectXPos;
bulletYPos = rectYPos;
bullet = new Rectangle(bulletXPos + 25, bulletYPos, 3, 5);
shot = true;
}
}
}
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
rightPressed = false;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
leftPressed = false;
}
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
fireBullet = false;
if (bullet.y <= -5) {
bullet = new Rectangle(0, 0, 0, 0);
shot = false;
fireBullet = true;
}
}
}
public void shootBullet() {
if (shot) {
bullet.y--;
System.out.println("shot fired");
}
}
public void moveRight() {
rightPressed = true;
rectXPos += 15;
}
public void moveLeft() {
leftPressed = true;
rectXPos -= 15;
}
#Override
public void run() {
try {
while (true) {
moveRight();
moveLeft();
shootBullet();
Thread.sleep(5);
}
} catch (Exception e) {
System.err.println(e.getMessage());
}
}
}
Based on the code, your KeyPressed/KeyReleased logic is correct for firing multiple bullets -- you are setting a boolean fireBullet to true on keyPressed events and then to false on keyReleased.
However, it appears you can only have exactly one Rectangle bullet at any given time because you have only declared one. The bullet instance will always be overwritten during the keyPressed event (the relevant line bullet = new Rectangle(0, 0, 0, 0);).
In order to have more than one bullet on-screen at a time, you need to keep track of the bullets via a List, array, or other structure allowing multiple instances of Rectangles representing bullet.
The refactor would look something like this:
Change the Rectangle bullet to List<Rectangle> bullets (or an array, or a Set, etc)
shootBullet should check to see if fireBullet is true. If it is, you should add a new bullet to the list
shootBullet should also move every bullet in the list (currently it moves the single instance of bullet)
One other thing to note -- depending on how frequently the frame updates, you may also want to keep track of how many bullets can be fired per second (the suggested changes would allow one bullet to be created per frame update, which may be too many). You would then need to track the time (or number of frame updates) since the last bullet was fired prior to spawning another. That would also need to happen in shootBullet.

How to change ghost speed in this code

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) {
}
}

Why doesn't my code go in the keyPressed() method? (Even if i press keys)

I'm trying to create a brickbreakers game. Obviously i'm still struggling with the beginning of it. I need my "block" to move but if i press some key my code won't even go in the keyPressed()-method. Does anybody know why?
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class VGKernel extends JPanel implements KeyListener {
public Rectangle screen, ball, block; // The screen area and ball location/size.
public Rectangle bounds; // The boundaries of the drawing area.
public JFrame frame; // A JFrame to put the graphics into.
public VGTimerTask vgTask; // The TimerTask that runs the game.
public boolean down, right; // Direction of ball's travel.
public VGKernel(){
super();
screen = new Rectangle(0, 0, 600, 400);
ball = new Rectangle(0, 0, 20, 20);
block = new Rectangle(0, 350, 40, 10);
bounds = new Rectangle(0, 0, 600, 400); // Give some starter values.
frame = new JFrame("VGKernel");
vgTask = new VGTimerTask();
addKeyListener(this);
}
class VGTimerTask extends TimerTask{
public void run(){
moveBall();
frame.repaint();
}
}
// Now the instance methods:
public void paintComponent(Graphics g){
// Get the drawing area bounds for game logic.
bounds = g.getClipBounds();
// Clear the drawing area, then draw the ball.
g.clearRect(screen.x, screen.y, screen.width, screen.height);
g.fillRect(ball.x, ball.y, ball.width, ball.height);
g.fillRect(block.x, block.y, block.width, block.height);
}
public void moveBall(){
// Ball should really be its own class with this as a method.
if (right) ball.x+=1; // If right is true, move ball right,
else ball.x-=1; // otherwise move left.
if (down) ball.y+=1; // Same for up/down.
else ball.y-=1;
if (ball.x > (bounds.width - ball.width)) // Detect edges and bounce.
{ right = false; ball.x = bounds.width - ball.width; }
if (ball.y > (bounds.height - ball.height))
{ down = false; ball.y = bounds.height - ball.height;}
if (ball.x <= 0) { right = true; ball.x = 0; }
if (ball.y <= 0) { down = true; ball.y = 0; }
}
public void keyPressed(KeyEvent evt) {
if(evt.getKeyCode() == KeyEvent.VK_G && block.x > 0) {
block.x -= 10;
}
if(evt.getKeyCode() == KeyEvent.VK_H && block.x < 560) {
block.x += 10;
}
}
public void keyTyped(KeyEvent evt){ }
public void keyReleased(KeyEvent evt){ }
public static void main(String arg[]){
java.util.Timer vgTimer = new java.util.Timer(); // Create a Timer.
VGKernel panel = new VGKernel(); // Create and instance of our kernel.
// Set the intial ball movement direction.
panel.down = true;
panel.right = true;
// Set up our JFRame
panel.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel.frame.setSize(panel.screen.width, panel.screen.height);
panel.frame.setContentPane(panel);
panel.frame.setVisible(true);
// Set up a timer to do the vgTask regularly.
vgTimer.schedule(panel.vgTask, 0, 10);
}
}
Put
setFocusable(true);
inside your constructor.

Java - KeyListener Events not firing

I have begun to write a simple platform game in java. As a test, I wrote this simple
program that moves a rectangle around the applet when you press the arrow keys. The key events have not been firing at all. Here's the code:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Game extends Applet implements Runnable, KeyListener
{
//setup data
Thread t;
Image buffimg;
Graphics draw;
Dimension dim;
//game variables
int charx = 400;//rectangles X and Y positions
int chary = 50;
boolean leftArrow = false;
public void init()
{
setSize(800, 500);
t = new Thread(this);
t.start();
addKeyListener( this );
}
public void run()
{
while(true)
{
repaint();
moveChar();//move the rectangle
try {
t.sleep(1000/30);
} catch (InterruptedException e) { ; }
}
}
public void keyPressed( KeyEvent e )
{
int k = e.getKeyCode();
if(k == 37)
{
leftArrow = true;
charx--;
}
}
public void keyReleased( KeyEvent e )
{
if(e.getKeyCode() == 37)
{
leftArrow = false;
}
}
public void keyTyped( KeyEvent e )
{
}
public void moveChar()
{
//move rectangle on left arrow key press
if(leftArrow == true)
{
charx--;
}
}
public void paint(Graphics g)
{
g.drawRect(charx, chary, 100, 100);
}
public void update (Graphics g)
{
//double buffering
// initialize buffer
if (buffimg == null)
{
buffimg = createImage (this.getSize().width, this.getSize().height);
draw = buffimg.getGraphics ();
}
// clear screen in background
draw.setColor (getBackground ());
draw.fillRect (0, 0, this.getSize().width, this.getSize().height);
// draw elements in background
draw.setColor (getForeground());
paint (draw);
// draw image on the screen
g.drawImage (buffimg, 0, 0, this);
}
}
Why aren't they firing and how should I fix this?
this.requestFocusInWindow(); // end of init(), or better, in start()
I tried your code. It works as it should.
The problem is you need to press the mouse on the drawing area to focus it first before it can receive events.
To do it automatically, use this command: requestFocusInWindow()

My JFrame Flickers

I'm trying to make a simple java game -- driving a car through a track. I am conditioned by my teacher to use rectangles and stuff like that . My problem is when I use the method repaint() that my frame flickers. I have tried to put the repaint method just when the car changes direction, but it doesn't do any good. Any suggestions?
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class MAP extends JFrame
{
//the URL and Img designed for the images
URL cLeft,cRight,cUp;
Image img1,img2,img3;
//these will keep track of each player’s speed:
double p1Speed =.5, p2Speed =.5;
//constant for the screen size and used for the drawing the terrain
final int WIDTH = 900, HEIGHT = 650;
//these are ints that represent directions:
final int UP = 0, RIGHT = 1, DOWN = 2, LEFT = 3;
//these will keep track of the player’s directions (default = up)
int p1Direction = 0;
//this is the rectangle for player 1’s (outer) car:
Rectangle p1 = new Rectangle(WIDTH/9,HEIGHT/2, WIDTH/30,WIDTH/30);
//draw the terrain
Rectangle left = new Rectangle(0,0,WIDTH/9,HEIGHT);
Rectangle right = new Rectangle((WIDTH/9)*9,0,WIDTH/9,HEIGHT);
Rectangle top = new Rectangle(0,0,WIDTH, HEIGHT/9);
Rectangle bottom = new Rectangle(0,(HEIGHT/9)*9,WIDTH,HEIGHT/9);
Rectangle center = new Rectangle((int)((WIDTH/9)*2.5),(int)((HEIGHT/9)*2.5), (int)((WIDTH/9)*5),(HEIGHT/9)*4);
//these obstacles will obstruct the path and make navigating harder
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 lineO=new Rectangle(WIDTH/9,HEIGHT/2,(int)((WIDTH/9)*1.5)/2,HEIGHT/140);
Rectangle lineI = new Rectangle(((WIDTH/9)+((int)((WIDTH/9)*1.5)/2)),(HEIGHT/2)+(HEIGHT/10),(int)((WIDTH/9)*1.5)/2, HEIGHT/140);
//the constructor:
public MAP() {
//the following code creates the JFrame
super("Radical Racing");
setSize(WIDTH,HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(false);
try {
cUp = this.getClass().getResource("carUp.jpg");
cLeft = this.getClass().getResource("carLeft.jpg");
cRight = this.getClass().getResource("carRight.jpg");
} catch(Exception e) {
}
//attach the URLs to the images
img1 = Toolkit.getDefaultToolkit().getImage(cUp);
img2 = Toolkit.getDefaultToolkit().getImage(cLeft);
img3 = Toolkit.getDefaultToolkit().getImage(cRight);
repaint();
Move1 m1 = new Move1();
m1.start();
}
//this will draw the cars and the race track
public void paint(Graphics g) {
super.paint(g);
//draw the background for the racetrack
g.setColor(Color.DARK_GRAY);
g.fillRect(0,0,WIDTH,HEIGHT);
//when we draw, the border will be green
g.setColor(Color.GREEN);
//fill rectangle
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,obstacle3.width,obstacle4.height);
g.fillRect(obstacle5.x,obstacle5.y,obstacle5.width,obstacle5.height);
//set the starting line color to white
g.setColor(Color.WHITE);
//now 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);
//now draw the finish line
g.fillRect(finish.x,finish.y,finish.width,finish.height);
//set the color to blue for p1
g.setColor(Color.WHITE);
//now draw the actual player
g.fill3DRect(p1.x,p1.y,p1.width,p1.height,true);
//draw the images for the player
if(p1Direction==UP)
g.drawImage(img1,p1.x,p1.y,this);
if(p1Direction==LEFT)
g.drawImage(img2,p1.x,p1.y,this);
if(p1Direction==RIGHT)
g.drawImage(img3,p1.x,p1.y,this);
}
private class Move1 extends Thread implements KeyListener {
public void run() {
//now, this should all be in an infinite loop, so the process
//repeats
addKeyListener(this);
while(true) {
//now, put the code in a try block. This will let the
//program exit
//if there is an error.
try {
//first, refresh the screen:
repaint();
//increase speed a bit
// if(p1Speed<=5)
// p1Speed+=.2;
//p1.y-=(int) p1Speed;
if(p1.intersects(left) || p1.intersects(right) || p1.intersects(top) || p1.intersects(bottom) || p1.intersects(obstacle) || p1.intersects(obstacle2)|| p1.intersects(obstacle3) || p1.intersects(obstacle4) || p1.intersects(obstacle5)) {
p1Speed = -5;
}
//if the car hits the center, do the same as above
//but make the speed -2.5.
if(p1.intersects(center)) {
p1Speed = -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;
//repaint();
}
if(p1Direction==DOWN) {
p1.y+=(int)p1Speed;
//repaint();
}
if(p1Direction==LEFT) {
p1.x-=(int)p1Speed;
//repaint();
}
if(p1Direction==RIGHT) {
p1.x+=(int)p1Speed;
//repaint();
}
//this delays the refresh rate:
Thread.sleep(200);
} catch(Exception e) {
//if there is an exception (an error), exit the loop.
break;
}
}
}
#Override
public void keyPressed(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent event) {
if(event.getKeyChar()=='a') {
p1Direction = LEFT;
repaint();
}
if(event.getKeyChar()=='s') {
p1Direction = DOWN;
repaint();
}
if(event.getKeyChar()=='d') {
p1Direction = RIGHT;
repaint();
}
if(event.getKeyChar()=='w') {
p1Direction = UP;
repaint();
}
}
}
//this starts the program by calling the constructor:
public static void main (String[ ] args) {
new MAP();
}
}
Don't draw directly in the JFrame in its paint method. Instead draw in a JPanel or JComponent and override its paintComponent method since Swing does double buffering by default, and this will allow you to take advantage of this.
You need to buffer your drawing instead of drawing right on the frame. See this related question and also the API for BufferStrategy.
You can avoid the flickering on your graphical interface by using the Double Buffering Technique. Here is an article that gives one example of double buffering.
This part of the Java Tutorial also gives further advice and examples.

Categories