Java applet methods [closed] - java

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;

Related

Why wont my image move when the y value of it is increasing?

I'm currently having an issue where the image won't move when the y-value of the image is increasing. I wanted the image to move vertically so I made a method that controls the speed of the image, The parameter is the ActionEvent and the y-value for the player. The y-value increases as I printed out the value, but the image won't move. I've even added the timer which didn't make the image move at all. No error in the output whatsoever.
public void speedPerformed(ActionEvent e, Rectangle movingPlayer){
int speed = 15;
// help deals with gravity
ticks++;
// if the remainder of zero is given from tick
//then the object will feel heavier
if (ticks % 2 == 0 && yMotion < 15) {
yMotion += 3;
}
movingPlayer.y += yMotion;
}
#Override
public void actionPerformed(ActionEvent e) {
action.speedPerformed(e,movingPlayer);
gameInterface.getRenderer().repaint();
}
public void repaint(Graphics g) {
g.drawImage(Renderer.renderer.getImage(),movingPlayer.x,movingPlayer.y,100,100, null);
}
public RepaintConfiguration(GameInterface gameInterface) {
this.gameInterface = gameInterface;
lasers = new Lasers();
action = new Actions();
movingPlayer = new Rectangle(0, 550, 100, 100);
timer = new Timer(20,this);
timer.start();
}
let me know if you want to take a look at any of my codes that I haven't included here.
You code is wrong: you are updating the local variable y.
You should update directly the movingPlayer:
public void speedPerformed(ActionEvent e){
int speed = 15;
// help deals with gravity
ticks++;
// the y value of the moving player
// if the remainder of zero is given from tick
//then the object will feel heavier
if (ticks % 2 == 0 && yMotion < 15) {
yMotion += 3;
}
movingPlayer.y += yMotion;
}

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.

Making a moving circle disappear after being clicked on, Processing

I have written a program in which a UFO (in essence, a gray ellipse) appears from the center of the screen and flies to the edge. There is a laser that appears when the mouse is pressed, and disappears when the mouse is released. I want to make it so that the UFO disappears when the mouse clicks on it/the laser touches it.
I've made it as far as to make the UFO class and create variables that determine its movements and speed, and I was able to get the laser to appear directly on the cursor. I thought of making an 'if' statement to check if the cursor is within the radius (or diameter) of the UFO, and placing it inside of the for loop I created for the UFOs. However, I am not sure how to achieve the proper syntax to make it happen.
Note: You may need to wait a few seconds for the first circle to appear after you play the sketch.
UFO[] ufos = new UFO[3];
void setup() {
size(700, 700);
for (int j = 0; j < ufos.length; j++) {
ufos[j] = new UFO();
}
}
//UFO class
//Class setup ends on line 61
class UFO {
float a;
float b;
float c;
float sa;
float sb;
float d;
UFO() {
//declare float a/b/c value
a = random(-width/2, width/2);
b = random(-height/2, width/2);
c = random(width);
}
//UFO movement
void update() {
//float c will serve as a speed determinant of UFOs
c = c - 1;
if (c < 5) {
c = width;
}
}
//UFO setup
void show() {
//moving x/y coordinates of UFO
float sa = map(a / c, 0, 1, 0, width);
float sb = map(b / c, 0, 1, 0, height);
float d = map(c, 0, width, 50, 0);
//UFO drawing shapes
//ellipse is always sa (or sb) / c to allow UFO to appear
//as if it is moving through space
fill(200);
ellipse((sa / c), (sb / c), d + 5, d+5);
//Hides UFO way off the screen
//and replaces it with a black-filled ellipse until
//it forms into a full circle
//When radius d becomes 50, the UFO flies from the
//center of the screen to off of the screen
if (d < 50) {
fill(0);
ellipse(-5, -10, 90, 90);
sa = 10000;
sb = 10000;
}
}
}
void draw() {
//Background
background(0);
//Translated the screen so that the UFOs appear to fly from
//the center of the screen
translate(width/2, height/2);
//UFO draw loop, make UFO visible on screen
for (int j = 0; j < ufos.length; j++) {
ufos[j].update();
ufos[j].show();
//mouse-click laser
if (mousePressed == true) {
fill(200,0,0);
ellipse(mouseX - 352,mouseY - 347,50,50);
}
}
}
Like I said on the Happy Coding forum:
Basically, if your UFO is a series of circles, then you just need to use the dist() function to check whether the distance from the mouse to the center of the circle is less than the radius of the circle. If it is, then the mouse is inside the circle. Here's a small example:
float circleX = 50;
float circleY = 50;
float circleDiameter = 20;
boolean showCircle = true;
void draw(){
background(0);
if(showCircle){
ellipse(circleX, circleY, circleDiameter, circleDiameter);
}
}
void mousePressed(){
if(dist(mouseX, mouseY, circleX, circleY) < circleDiameter/2){
showCircle = false;
}
}
If your UFO is multiple circles, then you need to apply this logic to each circle. Please try something and post a small example like this one (not your whole sketch) if you get stuck. Good luck.

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.

Smooth Animations with ActionEvents in 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!!

Categories