Smooth Animations with ActionEvents in Java - java

I am attempting to learn more about Java GUI programming, specifically animations for games. I am referencing a program found on http://math.hws.edu/javanotes/c6/s4.html called "SubKiller.java". The source is as followed:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* This panel implements a simple arcade game in which the user tries to blow
* up a "submarine" (a black oval) by dropping "depth charges" (a red disk) from
* a "boat" (a blue roundrect). The user moves the boat with the left- and
* right-arrow keys and drops the depth charge with the down-arrow key.
* The sub moves left and right erratically along the bottom of the panel.
* This class contains a main() routine to allow it to be run as a program.
*/
public class SubKiller extends JPanel {
public static void main(String[] args) {
JFrame window = new JFrame("Sub Killer Game");
SubKiller content = new SubKiller();
window.setContentPane(content);
window.setSize(600, 480);
window.setLocation(100,100);
window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
window.setResizable(false); // User can't change the window's size.
window.setVisible(true);
}
//------------------------------------------------------------------------
private Timer timer; // Timer that drives the animation.
private int width, height; // The size of the panel -- the values are set
// the first time the paintComponent() method
// is called. This class is not designed to
// handle changes in size; once the width and
// height have been set, they are not changed.
// Note that width and height cannot be set
// in the constructor because the width and
// height of the panel have not been set at
// the time that the constructor is called.
private Boat boat; // The boat, bomb, and sub objects are defined
private Bomb bomb; // by nested classes Boat, Bomb, and Submarine,
private Submarine sub; // which are defined later in this class.
// Note that the objects are created in the
// paintComponent() method, after the width
// and height of the panel are known.
/**
* The constructor sets the background color of the panel, creates the
* timer, and adds a KeyListener, FocusListener, and MouseListener to the
* panel. These listeners, as well as the ActionListener for the timer
* are defined by anonymous inner classes. The timer will run only
* when the panel has the input focus.
*/
public SubKiller() {
setBackground( new Color(0,200,0) );
ActionListener action = new ActionListener() {
// Defines the action taken each time the timer fires.
public void actionPerformed(ActionEvent evt) {
if (boat != null) {
boat.updateForNewFrame();
bomb.updateForNewFrame();
sub.updateForNewFrame();
}
repaint();
}
};
timer = new Timer( 30, action ); // Fires every 30 milliseconds.
addMouseListener( new MouseAdapter() {
// The mouse listener simply requests focus when the user
// clicks the panel.
public void mousePressed(MouseEvent evt) {
requestFocus();
}
} );
addFocusListener( new FocusListener() {
// The focus listener starts the timer when the panel gains
// the input focus and stops the timer when the panel loses
// the focus. It also calls repaint() when these events occur.
public void focusGained(FocusEvent evt) {
timer.start();
repaint();
}
public void focusLost(FocusEvent evt) {
timer.stop();
repaint();
}
} );
addKeyListener( new KeyAdapter() {
// The key listener responds to keyPressed events on the panel. Only
// the left-, right-, and down-arrow keys have any effect. The left- and
// right-arrow keys move the boat while down-arrow releases the bomb.
public void keyPressed(KeyEvent evt) {
int code = evt.getKeyCode(); // Which key was pressed?
if (code == KeyEvent.VK_LEFT) {
// Move the boat left. (If this moves the boat out of the frame, its
// position will be adjusted in the boat.updateForNewFrame() method.)
boat.centerX -= 15;
}
else if (code == KeyEvent.VK_RIGHT) {
// Move the boat right. (If this moves boat out of the frame, its
// position will be adjusted in the boat.updateForNewFrame() method.)
boat.centerX += 15;
}
else if (code == KeyEvent.VK_DOWN) {
// Start the bomb falling, if it is not already falling.
if ( bomb.isFalling == false )
bomb.isFalling = true;
}
}
} );
} // end constructor
/**
* The paintComponent() method draws the current state of the game. It
* draws a gray or cyan border around the panel to indicate whether or not
* the panel has the input focus. It draws the boat, sub, and bomb by
* calling their respective draw() methods.
*/
public void paintComponent(Graphics g) {
super.paintComponent(g); // Fill panel with background color, green.
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (boat == null) {
// The first time that paintComponent is called, it assigns
// values to the instance variables.
width = getWidth();
height = getHeight();
boat = new Boat();
sub = new Submarine();
bomb = new Bomb();
}
if (hasFocus())
g.setColor(Color.CYAN);
else {
g.setColor(Color.BLACK);
g.drawString("CLICK TO ACTIVATE", 20, 30);
g.setColor(Color.GRAY);
}
g.drawRect(0,0,width-1,height-1); // Draw a 3-pixel border.
g.drawRect(1,1,width-3,height-3);
g.drawRect(2,2,width-5,height-5);
boat.draw(g);
sub.draw(g);
bomb.draw(g);
} // end paintComponent()
/**
* This nested class defines the boat. Note that its constructor cannot
* be called until the width of the panel is known!
*/
private class Boat {
int centerX, centerY; // Current position of the center of the boat.
Boat() { // Constructor centers the boat horizontally, 80 pixels from top.
centerX = width/2;
centerY = 80;
}
void updateForNewFrame() { // Makes sure boat has not moved off screen.
if (centerX < 0)
centerX = 0;
else if (centerX > width)
centerX = width;
}
void draw(Graphics g) { // Draws the boat at its current location.
g.setColor(Color.BLUE);
g.fillRoundRect(centerX - 40, centerY - 20, 80, 40, 20, 20);
}
} // end nested class Boat
/**
* This nested class defines the bomb.
*/
private class Bomb {
int centerX, centerY; // Current position of the center of the bomb.
boolean isFalling; // If true, the bomb is falling; if false, it
// is attached to the boat.
Bomb() { // Constructor creates a bomb that is initially attached to boat.
isFalling = false;
}
void updateForNewFrame() { // If bomb is falling, take appropriate action.
if (isFalling) {
if (centerY > height) {
// Bomb has missed the submarine. It is returned to its
// initial state, with isFalling equal to false.
isFalling = false;
}
else if (Math.abs(centerX - sub.centerX) <= 36 &&
Math.abs(centerY - sub.centerY) <= 21) {
// Bomb has hit the submarine. The submarine
// enters the "isExploding" state.
sub.isExploding = true;
sub.explosionFrameNumber = 1;
isFalling = false; // Bomb reappears on the boat.
}
else {
// If the bomb has not fallen off the panel or hit the
// sub, then it is moved down 10 pixels.
centerY += 10;
}
}
}
void draw(Graphics g) { // Draw the bomb.
if ( ! isFalling ) { // If not falling, set centerX and centerY
// to show the bomb on the bottom of the boat.
centerX = boat.centerX;
centerY = boat.centerY + 23;
}
g.setColor(Color.RED);
g.fillOval(centerX - 8, centerY - 8, 16, 16);
}
} // end nested class Bomb
/**
* This nested class defines the sub. Note that its constructor cannot
* be called until the width of the panel is known!
*/
private class Submarine {
int centerX, centerY; // Current position of the center of the sub.
boolean isMovingLeft; // Tells whether the sub is moving left or right
boolean isExploding; // Set to true when the sub is hit by the bomb.
int explosionFrameNumber; // If the sub is exploding, this is the number
// of frames since the explosion started.
Submarine() { // Create the sub at a random location 40 pixels from bottom.
centerX = (int)(width*Math.random());
centerY = height - 40;
isExploding = false;
isMovingLeft = (Math.random() < 0.5);
}
void updateForNewFrame() { // Move sub or increase explosionFrameNumber.
if (isExploding) {
// If the sub is exploding, add 1 to explosionFrameNumber.
// When the number reaches 15, the explosion ends and the
// sub reappears in a random position.
explosionFrameNumber++;
if (explosionFrameNumber == 15) {
centerX = (int)(width*Math.random());
centerY = height - 40;
isExploding = false;
isMovingLeft = (Math.random() < 0.5);
}
}
else { // Move the sub.
if (Math.random() < 0.04) {
// In one frame out of every 25, on average, the sub
// reverses its direction of motion.
isMovingLeft = ! isMovingLeft;
}
if (isMovingLeft) {
// Move the sub 5 pixels to the left. If it moves off
// the left edge of the panel, move it back to the left
// edge and start it moving to the right.
centerX -= 5;
if (centerX <= 0) {
centerX = 0;
isMovingLeft = false;
}
}
else {
// Move the sub 5 pixels to the right. If it moves off
// the right edge of the panel, move it back to the right
// edge and start it moving to the left.
centerX += 5;
if (centerX > width) {
centerX = width;
isMovingLeft = true;
}
}
}
}
void draw(Graphics g) { // Draw sub and, if it is exploding, the explosion.
g.setColor(Color.BLACK);
g.fillOval(centerX - 30, centerY - 15, 60, 30);
if (isExploding) {
// Draw an "explosion" that grows in size as the number of
// frames since the start of the explosion increases.
g.setColor(Color.YELLOW);
g.fillOval(centerX - 4*explosionFrameNumber,
centerY - 2*explosionFrameNumber,
8*explosionFrameNumber,
4*explosionFrameNumber);
g.setColor(Color.RED);
g.fillOval(centerX - 2*explosionFrameNumber,
centerY - explosionFrameNumber/2,
4*explosionFrameNumber,
explosionFrameNumber);
}
}
} // end nested class Submarine
} // end class SubKiller
Looking through the source code, I can't find out why the boat the user controls doesn't move smoothly like the submarine. I see they both operate under the same timer... I'm assuming this is because the program is looking for an action event each time iteration or something? Thank you in advance!!

Related

How to fix Java listening to more than 1 key at a time?

Me and my partner are attempting to create the game Pong for our computer science final project. We created a reference code where 2 cubes can be controlled upwards and downwards and it works fine. The problem occurs when attempting to control both cubes at the same time (only 1 cube will move at a time). We want to make both cubes move at the same time.
WE want to say that:
yPos - is the y position of the black cube
xPos - is the x position of the black cube
xPos2 - is the x position of the blue cube
YPos2 - is the y position of the blue cube
Keys:
A - Go up for black cube
Z - Go down for black cube
K - Go up for blue cube
M - go down for blue cube
We have tried using a more complicated version which used j-label animation. How ever we want to make our pong game through the graphics function. But we do not understand:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class PongHelpNeed extends JFrame implements KeyListener
{
// booleans to tell which key is pressed
boolean upKey;
boolean downKey;
boolean upKey2;
boolean downKey2;
// the position variables
int yPos;
int xPos;
int xPos2;
int yPos2;
public PongHelpNeed ()
{
//create window
super ("Controller");
setSize (660, 700);
// set keys to false and original positions
upKey = false;
downKey = false;
upKey2 = false;
downKey2 = false;
xPos = 100;
yPos = 350;
xPos2 = 500;
yPos2 = 350;
// add the frame as a listener to your keys
addKeyListener (this);
// Show the frame
setVisible(true);
}
//needs to be here because the class implements KeyListener
public void keyTyped (KeyEvent e)
{
System.out.println (e.getKeyCode () + " Typed");
}
//needs to be here because the class implements KeyListener
public void keyPressed (KeyEvent e) {
//check if keys a,z or k,m are pressed
if (e.getKeyCode () == KeyEvent.VK_A)
{
upKey = true;
}
else if (e.getKeyCode () == KeyEvent.VK_Z)
{
downKey = true;
}
else if (e.getKeyCode () == KeyEvent.VK_K)
{
upKey2 = true;
}
else if (e.getKeyCode () == KeyEvent.VK_M)
{
downKey2 = true;
}
//repaint the window everytime you press a key
repaint ();
}
//needs to be here because the class implements KeyListener
public void keyReleased (KeyEvent e)
{
System.out.println (e.getKeyCode () + " Released");
}
//paints the pictures
public void paint (Graphics g)
{
//set background
g.setColor(Color.WHITE);
g.fillRect(0, 0, 660, 700);
//cube 1
g.setColor(Color.BLACK);
g.fillRect(xPos,yPos,50, 50);
//draw cube 2
g.setColor(Color.BLUE);
g.fillRect(xPos2,yPos2, 50, 50);
//if keys are pressed move the cubes accordingly up or down
if (upKey == true)
{
yPos = yPos - 15;
upKey = false;
}
else if (downKey == true)
{
yPos = yPos + 15;
downKey = false;
}
else if (downKey2 == true){
yPos2 = yPos2 + 15;
downKey2 = false;
}
else if (upKey2 == true) {
yPos2 = yPos2 - 15;
upKey2 = false;
}
}
public static void main (String[] args)
{
new PongHelpNeed ();
}
}
Our expected results are we are trying to move both cube at the same time. So when we press the A key and the K key the black square should move and the blue cube should move.
Calling repaint() does not trigger a call to the paint immediately, so it's possible that the keyPressed is triggered twice (or more) before paint.
In your paint method you are checking the keys in if-else, which means that if one of the flags is true, the rest are not checked. You also have a race condition where the keyPressed is fighting with paint over the flags. Also, if you press a key quickly multiple times, you'll lose all the extra key presses between the first handled event and the next repaint.
Instead of doing the move within paint, you should do it within the keyPressed handler. Don't set a flag to e.g. upKey = true;, but instead do the action directly: yPos = yPos - 15;. The paint method will then just refresh the view to reflect the current (updated) state.

How can I edit JPanel Graphics in one class?

So I'm trying to program snake on a JFrame and doing all graphical stuff (moving the 'snake', random food generation, etc.) on a JPanel. I'm in the beginning stages so all I'm trying to do right now is move a black square around on my frame using arrow keys. My while loop in the Panel class won't get interrupted by a key press in the Snake class, so is there a way to edit JPanel graphics from the same class with all my other code?
Here's all the code. My Panel class at the bottom follows the template I found here.
public class Snake {
// panel width and height
static int pW;
static int pH;
static int x = 10;
static int y = 10;
static int k;
static JFrame frame = new JFrame("SNAKE");
// getters for panel class
public int getPW() { return pW; }
public int getPH() { return pH; }
public int getX() { return x; }
public int getY() { return y; }
public static void main(String[] args) {
// get screen dimensions
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int sH = (int) screenSize.getHeight();
int sW = (int) screenSize.getWidth();
pW = (int) sW/2;
pH = (int) sH/2;
// initialize frame
frame.setSize (pW/1,pH/1);
frame.setLocation(pW/2,pH/2);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.addKeyListener( new KeyAdapter() {
public void keyPressed(KeyEvent e) {
k = e.getKeyCode();
switch(k) {
case 38: /* y -= square size */ break; // up
case 40: /* y += square size */ break; // down
case 37: /* x -= square size */ break; // left
case 39: /* x += square size */ break; // right
case 27: System.exit(0);
}
}
});
Panel panel = new Panel();
frame.add(panel);
frame.setVisible(true);
}
}
class Panel extends JPanel {
Snake snake = new Snake();
//square size and separation between squares
int sep = 0;
int size = 50;
// initial location of square on the panel/frame
int x = sep + size;
int y = sep + size;
// holding values to check if x or y have changed
int xH = x;
int yH = x;
public void paint(Graphics g) {
int pW = snake.getPW();
int pH = snake.getPH();
int i; int o;
Color on = Color.BLACK;
Color off = Color.GRAY;
// gray background
g.setColor(Color.GRAY);
g.fillRect(0,0,pW,pH);
// black square initialization
g.setColor(Color.BLACK);
g.fillRect(x, y, size, size);
/* this loop is supposed to check if the black
* rectangle has moved by repeatedly grabbing x & y
* values from the Snake class. When a key is pressed
* and the values change, a gray rectangle is placed at the old location
* and a black one is placed at the new location.
*
* When I run the program, I get stuck in this while loop.
* If I had the while loop in the same class I check for keys,
* I don't think I would have this problem
*/
while(true) {
x = snake.getX();
y = snake.getY();
if(x != xH || y != yH) {
g.setColor(off);
g.fillRect(xH, yH, size, size);
g.setColor(on);
g.fillRect(snake.getX(), snake.getY(), size, size);
xH = x;
yH = y;
}}
}
}
You should never have a while(true) loop in a painting method. This will just cause an infinite loop and your GUI will not be able to respond to events.
Instead you need to add methods to your snake class to move the snake. So when one of the arrow keys is pressed you update the starting position of the snake. Then the method will invoke repaint() and the snake will repaint itself when the paintComponent() method is invoked by Swing.
So your painting code should override paintComponent() not paint() and you should invoke super.paintComponent(g) as the first statement in the method.
Don't call your custom class "Panel", there is an AWT class with that name. Make your class name more descriptive.

Does the repaint() method in Java require a timer or action?

I've been working on a small "game," which I think is called Pachinko. I have uploaded an image of what the game screen looks like. I will be dropping balls, and having them look like they are rolling off pegs, ending up being caught in the bottom "gates."
My problem is that I cannot get the repaint() method to work. Does the repaint() method require a timer, or action to work? Please look at at these two classes. I have created a Ball class object inside the GameWindow class (near the bottom), and would like to update the ball's x/y values using the Ball's setPos() method, then repaint, so the ball appears to move.
What am I doing wrong? Do I need an update() method to use the repaint() method?
Game Window Image:
public class GameWindow extends JPanel{
private int numBalls = 0;
// GameWindow Constructor (Sets Ball amount from user)
public GameWindow(int balls){
JFrame myFrame = new JFrame("Game Window");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Globally set ball amount
setBallAmount(balls);
myFrame.add(this);
myFrame.setSize(325, 790);
myFrame.setLocationRelativeTo(this);
myFrame.setResizable(false);
myFrame.setVisible(true);
} // End GameWindow Constructor
// Function setPegAmount;
// Passes the amount of balls the user to class variable.
public void setBallAmount(int balls)
{
numBalls = balls * 2;
}
public void paintComponent(Graphics g){
super.paintComponent(g); // housekeeping, etc.
this.setBackground(Color.WHITE); // Background
int counter = 0; // count what number peg we are painting
int row = 1; // calculate what row we are creating
int rowSpacer = 55;
boolean evenRow = false;
int columnSpacer = 60;
// DRAW PEGS TO SCREEN (4 rows of 8, 4 rows of 7)
for (int x = 0; x < 60; x++)
{
// For odd rows
if (row % 2 == 1)
{
g.setColor(Color.BLACK);
g.fillOval(rowSpacer - 40, columnSpacer, 10, 10);
rowSpacer += 40;
counter++;
}
// For Even rows
else
{
g.setColor(Color.BLACK);
g.fillOval(rowSpacer - 20, columnSpacer, 10, 10);
rowSpacer += 40;
counter++;
}
// Check to see if we are finished with odd row
if (counter % 8 == 0 && evenRow == false)
{
row++;
rowSpacer = 55;
columnSpacer += 60;
evenRow = true;
counter = 0;
}
else if(counter % 7 == 0 && evenRow == true)
{
row++;
rowSpacer = 55;
columnSpacer += 60;
evenRow = false;
counter = 0;
}
} // END DRAWING PEGS TO SCREEN
// DRAW RECTANGULAR WALLS TO SCREEN
g.setColor(Color.BLACK); // Wall Color
g.fillRect(0, 0, 5, 760); // LEFT Wall
g.fillRect(315, 0, 5, 760); // RIGHT Wall
g.fillRect(0, 0, 315, 5); // TOP Wall
g.fillRect(0, 755, 320, 5); // BOTTOM Wall
// DRAW BOTTOM GATES
int gateSeperator = 35;
for (int x = 0; x < 7; x++)
{
g.setColor(Color.BLACK);
g.fillRect(gateSeperator, 500, 10, 255);
gateSeperator += 40;
}
// Create instance of ball object
Ball myBall = new Ball();
// Test draw ball
myBall.drawBall(g); // The ball is drawn to screen
myBall.setPos(50, 50); // Change the x and y coordinates of the Ball
repaint(); // Also tried "this.repaint();" but neither does anything
} // Ends paintComponent
} // End GameWindow Class
Ball.java:
public class Ball{
private int x = 5;
private int y = 30;
public void setPos(int xPos, int yPos)
{
x = xPos;
y = yPos;
}
public void drawBall(Graphics g)
{
g.setColor(Color.GREEN);
g.fillOval(x, y, 30, 30);
}
}
I don't think that's the way to do it. Swing's not my specialty but calling repaint in paintComponent, according to my experience, is incorrect.
For example, tell the component to repaint itself.
/**
* Tells the view to repaint itself.
*/
public void update() {
repaint();
}
As soon as possible, repaint ends up calling paintComponent via paint.
/**
* Paints the component.
* #param g The graphics object for the view.
*/
#Override
protected void paintComponent(Graphics g) {
// Draw some stuff...
}
So calling repaint inside of paintComponentis likely not what you're wanting to do. What you should be doing is using repaint to invode paintComponent.
I don't think you can rely on putting the repaint or update at the end of paintComponent because, I believe, multiple calls to repaint get lumped into a single update. So, yes, to properly animate object you should look into using a Swing Timer. For example,
Timer timer = Timer(delay, action);
timer.start();
The above timer will invoke the given action on the delay given in milliseconds. Please see this for more details.

JFrame Simple Application

I am working on creating a game for fun that basically is a simplistic representation for evolution.
Essentially, when I click on my moving ball it changes color. The goal is to continuously change until it matches the background color meaning the ball is successfully hidden. Eventually I will add more balls but I am trying to figure out how to change its color upon a mouse click. I have created the moving ball animation so far.
How can I change the ball color when I click on the ball?
Code:
public class EvolutionColor
{
public static void main( String args[] )
{
JFrame frame = new JFrame( "Bouncing Ball" );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
BallPanel bp = new BallPanel();
frame.add( bp );
frame.setSize( 1800, 1100 ); // set frame size
frame.setVisible( true ); // display frame
bp.setBackground(Color.YELLOW);
} // end main
}
class BallPanel extends JPanel implements ActionListener
{
private int delay = 10;
protected Timer timer;
private int x = 0; // x position
private int y = 0; // y position
private int radius = 15; // ball radius
private int dx = 2; // increment amount (x coord)
private int dy = 2; // increment amount (y coord)
public BallPanel()
{
timer = new Timer(delay, this);
timer.start(); // start the timer
}
public void actionPerformed(ActionEvent e)
// will run when the timer fires
{
repaint();
}
public void mouseClicked(MouseEvent arg0)
{
System.out.println("here was a click ! ");
}
// draw rectangles and arcs
public void paintComponent( Graphics g )
{
super.paintComponent( g ); // call superclass's paintComponent
g.setColor(Color.red);
// check for boundaries
if (x < radius) dx = Math.abs(dx);
if (x > getWidth() - radius) dx = -Math.abs(dx);
if (y < radius) dy = Math.abs(dy);
if (y > getHeight() - radius) dy = -Math.abs(dy);
// adjust ball position
x += dx;
y += dy;
g.fillOval(x - radius, y - radius, radius*2, radius*2);
}
}
Take a look at How to Write a Mouse Listener.
Don't make decisions about the state of the view in the paintComponent, painting can occur for any number of reasons, many you don't control. Instead, make theses decisions within the actionPerformed method of your Timer
You may also wish to consider changing your design slightly. Rather then having the balls as JPanels, you create a virtual concept of a ball, which contains all the properties and logic it needs and use the JPanel to paint them. You could then store them in some kind of List, each time you register a mouse click you could iterate the List and check to see if any of the balls were clicked
Have look at Java Bouncing Ball for an example
Instead of hard-coding the color (g.setColor(Color.red);), why not create an attribute:
g.setColor(currentColor);
Then when you click in the circle area, change currentColor.

Java applet methods [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
This is my program:
import java.applet.*; // imports basic applet package
import java.awt.*; // imports the abstract windows toolkit
import java.awt.event.*; // imports the events package from the abstract windows toolking
import java.util.Random; // imports package for randomizing numbers
public class Game extends Applet implements KeyListener
{
public int x = 240; // sets the x variable
public int y = 230; // sets the y variable
private Image dbImage; // Variable for doublebuffering
private Graphics dbg; // Variable for doublebuffering
Image startscreen; // declares startscreen as an image
Image instructions; // declares insturctions as an image
Image background; // declares background as an image
Random rand = new Random (); // declares the random variable
public void init ()
{
Game b = new Game ();
addKeyListener (this);
setSize (500, 500); // sets the size of the screen
//setBackground (Color.WHITE); // sets the backround color
startscreen = getImage (getDocumentBase (), "startscreen.png"); // gets the "startscreen.png" image
for (int p = 0 ; p < 1000 ; p++)
{
}
instructions = getImage (getDocumentBase (), "instructions.png"); // gets the "instructions.png" image
for (int o = 0 ; o < 1000 ; o++)
{
}
background = getImage (getDocumentBase (), "background.png"); // gets the "background.png" image
Game.bombs ();
}
public void backgrounds (Graphics g)
{
setSize (500, 500);
g.drawImage (startscreen, 0, 0, this); // draws the startscreen
g.drawImage (instructions, 0, 0, this); // draws the instructions
g.drawImage (background, 0, 0, this); // draws the background
}
public void paint (Graphics g)
{
g.drawImage (startscreen, 0, 0, this); // draws the startscreen
repaint ();
g.drawImage (instructions, 0, 0, this); // draws the instructions
repaint ();
g.drawImage (background, 0, 0, this);
g.setColor (Color.GRAY); // sets the body of the tank to GRAY
g.fillRect (x, y, 30, 50); // body of tank
g.setColor (Color.BLACK); // sets the rest of the tank to BLACK
g.fillRect (x - 10, y - 10, 10, 70); // left wheel of tank
g.fillRect (x + 30, y - 10, 10, 70); // right wheel of tank
g.fillRect (x + 5, y + 20, 20, 20); // top of tank
g.fillRect (x + 10, y - 20, 10, 50); // barrel of tank
}
public void keyTyped (KeyEvent e)
{
}
public void update (Graphics g)
{
// initialize buffer
if (dbImage == null)
{
dbImage = createImage (this.getSize ().width, this.getSize ().height); // sets the width, height, etc of doublebuffer
dbg = dbImage.getGraphics (); // gets the image
}
// clear screen in background
dbg.setColor (getBackground ()); // gets the background for the double buffer
dbg.fillRect (0, 0, this.getSize ().width, this.getSize ().height); // gets teh size of the width, height, etc of background
// draw elements in background
dbg.setColor (getForeground ()); // sets the forground for the doulbebuffer
paint (dbg); // draws the image for the double buffer
g.drawImage (dbImage, 0, 0, this); // draw image on the screen
}
public void keyPressed (KeyEvent e)
{
if (e.getKeyCode () == 37) // checks if left arrow is pressed
{
x -= 10; // moves the tank over 4 to the left
repaint ();
} // end if for left arrow
if (e.getKeyCode () == 39) // checks if up arrow is pressed
{
x += 10; // moves the tank over 4 to the right
repaint ();
} // end if for up arrow
if (e.getKeyCode () == 38) // checks if right arrow is pressed
{
y -= 10;
repaint ();
} // end if for right arrow
if (e.getKeyCode () == 40) // checks if down arrow is pressed
{
y += 10;
repaint ();
} // end if for down arrow
if (e.getKeyCode () == 32) // checks if space is pressed
{
repaint ();
} // end if for space
if (x > 460) // makes sure that the tank does not pass the right wall
{
x -= 10;
}
if (x < 10) // makes sure that the tank does not pass the left wall
{
x += 10;
}
if (y > 440) // makes sure that the tank does not pass the bottom wall
{
y -= 10;
}
if (y < 20) // makes sure that the tank does not pass the top wall
{
y += 10;
}
}
public void keyReleased (KeyEvent e)
{
}
public void bombs (Graphics g)
{
int pick = 0;
int pick2 = 0;
for (int j = 0 ; j < 1 ; j++) // for loop for counter
{
pick = rand.nextInt (500); // randomizes random integers from 0 to 500
//System.out.println (pick); // prints the integers
} // end for loop for randomize
for (int m = 0 ; m < 1 ; m++) // for loop for randomize integer
{
pick2 = rand.nextInt (500); // randomizes intger from 0 to 500
}
g.fillRect (pick, pick2, 100, 100); // draws the bombs
if (x < pick + 10 || x > pick + 10) // collision detection for x
{
}
if (y < pick2 + 10 || y > pick2 + 10) // collision detection for y
{
}
}
}
can you please tell me how to call in "bombs" in a different place?
i want to call bombs in inside KeyPressed
The right way to do it: have your paint() method call bombs() if a boolean flag member variable is set. Then in your key listener, set the flag and call repaint(). The paint() method can clear the flag after calling the method. That way you can call it from anywhere; when paint() is called by repaint(), it will be able to supply the Graphics argument and call the method correctly.
So in paint() you might have
public void paint(Graphics g) {
...
if (shouldShowBombs) {
bombs(g);
shouldShowBombs = false;
}
Then if you want to paint the bombs anywhere in your applet, you just write
shouldShowBombs = true;
repaint();
Of course, you have to declare shouldShowBombs
public class Game {
private boolean shouldShowBombs = false;

Categories