将Java Applet转换为Application

时间:2014-04-17 03:16:23

标签: java applet

所以我遵循了一本免费手册,指导如何在Java中编写Asteroids,它运行得很好。我想将它添加到一个程序中,以便我可以调用它,运行它一段时间,然后让它返回一个int。我正在制作的程序是一个应用程序,我一直在寻找尝试和失败的一段时间,弄清楚如何让它作为一个应用程序运行。我在这里读到的东西说我应该这样做:

public class Main extends JFrame {
 public static void main(String[] args) {         
     AsteroidsGame game = new AsteroidsGame();
     JFrame frame = new JFrame();
     frame.setLayout(new GridLayout (1,1));
     frame.add(game);
     frame.setSize(500,500);         
     game.init();
     game.start();       
     frame.setVisible(true);
   }

}

但后来我收到错误

线程“main”中的异常java.lang.NullPointerException

at AsteroidsGame.init(AsteroidsGame.java:49)

在Main.main(Main.java:15)

指向第49行的下方,以及第15行的game.init()。

        g = img.getGraphics();

这是AsteroidsGame的代码,我太累了,不能再想了。我只需要让它作为一个应用程序运行,此时任何其他代码更改都无关紧要。我知道这是很多代码,但我希望这是一个我错过的简单的东西。任何帮助是极大的赞赏。谢谢!

    import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;

public class AsteroidsGame extends Applet implements Runnable, KeyListener {
Thread thread;
Dimension dim;
Image img;
Graphics g;
long endTime, startTime, framePeriod;
Ship ship;
boolean paused; // True if the game is paused. Enter is the pause key
Shot[] shots;
int numShots;
boolean shooting;
Asteroid[] asteroids; // the array of asteroids
int numAsteroids; // the number of asteroids currently in the array
double astRadius, minAstVel, maxAstVel; // values used to create
// asteroids
int astNumHits, astNumSplit;
int level; // the current level number
int money;
double fuel;
Random rand = new Random();

public void init() {
    resize(500, 500);
    shots = new Shot[41]; // 41 is a shot's life period plus one.
    // since at most one shot can be fired per frame,
    // there will never be more than 41 shots if each one only
    // lives for 40 frames.
    numAsteroids = 0;
    level = rand.nextInt(25)+1; // will be incremented to 1 when first level is set up
    astRadius = 10; // values used to create the asteroids
    minAstVel = 2;
    maxAstVel = 8;
    astNumHits = 3;
    astNumSplit = 2;
    money = 0;
    fuel = 100;

    endTime = 0;
    startTime = 0;
    framePeriod = 25;
    addKeyListener(this); // tell it to listen for KeyEvents
    dim = getSize();
    img = createImage(dim.width, dim.height);
    g = img.getGraphics();
    thread = new Thread(this);
    thread.start();
}

public void setUpNextLevel() { // start new level with one more asteroid
    level++;
    // create a new, inactive ship centered on the screen
    // I like .35 for acceleration, .98 for velocityDecay, and
    // .1 for rotationalSpeed. They give the controls a nice feel.
    ship = new Ship(250, 250, 0, .35, .98, .1, 12);
    numShots = 0; // no shots on the screen at beginning of level
    paused = false;
    shooting = false;
    // create an array large enough to hold the biggest number
    // of asteroids possible on this level (plus one because
    // the split asteroids are created first, then the original
    // one is deleted). The level number is equal to the
    // number of asteroids at it's start.
    asteroids = new Asteroid[level
            * (int) Math.pow(astNumSplit, astNumHits - 1) + 1];
    numAsteroids = level;
    // create asteroids in random spots on the screen
    for (int i = 0; i < numAsteroids; i++)
        asteroids[i] = new Asteroid(Math.random() * dim.width,
                Math.random() * dim.height, astRadius, minAstVel,
                maxAstVel, astNumHits, astNumSplit);
}

public void paint(Graphics gfx) {
    g.setColor(Color.black);
    g.fillRect(0, 0, 500, 500);
    for (int i = 0; i < numShots; i++)
        // draw all the shots on the screen
        shots[i].draw(g);
    for (int i = 0; i < numAsteroids; i++)
        asteroids[i].draw(g);
    ship.draw(g); // draw the ship
    g.setColor(Color.cyan); // Display level number in top left corner
    g.drawString("Level " + level, 20, 20);
    g.drawString("Money " + money, 80, 20);
    g.drawString("Fuel " + fuel, 20, 50);
    gfx.drawImage(img, 0, 0, this);
}

public void update(Graphics gfx) {
    paint(gfx);
}

public void run() {
    for (;;) {
        startTime = System.currentTimeMillis();
        // start next level when all asteroids are destroyed
        if (numAsteroids <= 0)
            setUpNextLevel();
        if (!paused) {
            ship.move(dim.width, dim.height); // move the ship
            // move shots and remove dead shots
            for (int i = 0; i < numShots; i++) {
                shots[i].move(dim.width, dim.height);
                // removes shot if it has gone for too long
                // without hitting anything
                if (shots[i].getLifeLeft() <= 0) {
                    // shifts all the next shots up one
                    // space in the array
                    deleteShot(i);
                    i--; // move the outer loop back one so
                    // the shot shifted up is not skipped
                }

            }
            if(ship.accelerating && fuel>0){
                fuel -= 1.5;
            }
            if(ship.accelerating && fuel == 0)
            {
                ship.accelerating = false;
            }
            // move asteroids and check for collisions
            updateAsteroids();
            if (shooting && ship.canShoot()) {
                // add a shot on to the array
                shots[numShots] = ship.shoot();
                numShots++;
            }
        }
        repaint();
        try {
            endTime = System.currentTimeMillis();
            if (framePeriod - (endTime - startTime) > 0)
                Thread.sleep(framePeriod - (endTime - startTime));
        } catch (InterruptedException e) {
        }
    }
}

private void deleteShot(int index) {
    // delete shot and move all shots after it up in the array
    numShots--;
    for (int i = index; i < numShots; i++)
        shots[i] = shots[i + 1];
    shots[numShots] = null;
}

private void deleteAsteroid(int index) {
    // delete asteroid and shift ones after it up in the array
    numAsteroids--;
    for (int i = index; i < numAsteroids; i++)
        asteroids[i] = asteroids[i + 1];

    asteroids[numAsteroids] = null;
}

private void addAsteroid(Asteroid ast) {
    // adds the asteroid passed in to the end of the array
    asteroids[numAsteroids] = ast;
    numAsteroids++;
}

private void updateAsteroids() {
    for (int i = 0; i < numAsteroids; i++) {
        // move each asteroid
        asteroids[i].move(dim.width, dim.height);
        // check for collisions with the ship, restart the
        // level if the ship gets hit
        if (asteroids[i].shipCollision(ship)) {
            money+= Math.random()*1000;
            deleteAsteroid(i);

            //level--; // restart this level
            //numAsteroids = 0;
            return;
        }
        // check for collisions with any of the shots
        for (int j = 0; j < numShots; j++) {
            if (asteroids[i].shotCollision(shots[j])) {
                // if the shot hit an asteroid, delete the shot
                deleteShot(j);
                // split the asteroid up if needed
                if (asteroids[i].getHitsLeft() > 1) {
                    for (int k = 0; k < asteroids[i].getNumSplit(); k++)
                        addAsteroid(asteroids[i].createSplitAsteroid(
                                minAstVel, maxAstVel));
                }
                // delete the original asteroid
                deleteAsteroid(i);
                j = numShots; // break out of inner loop - it has
                // already been hit, don't need to check
                // for collision with other shots
                i--; // don't skip asteroid shifted back into
                // the deleted asteroid's position
            }
        }
    }
}

public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_ENTER) {
        // These first two lines allow the asteroids to move
        // while the player chooses when to enter the game.
        // This happens when the player is starting a new life.
        if (!ship.isActive() && !paused)
            ship.setActive(true);
        else {
            paused = !paused; // enter is the pause button
            if (paused) // grays out the ship if paused
                ship.setActive(false);
            else

                ship.setActive(true);
        }
    } else if (paused || !ship.isActive()) // if the game is
        return; // paused or ship is inactive, do not respond
    // to the controls except for enter to unpause
    else if (e.getKeyCode() == KeyEvent.VK_UP)
    {if(fuel>0){
        ship.setAccelerating(true);

        //fuel -= 1.5;  
        }
    else{
        fuel = 0;
    }
}
    else if (e.getKeyCode() == KeyEvent.VK_LEFT)
    {

        ship.setTurningLeft(true);
    }

    else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
        ship.setTurningRight(true);
        //else if (e.getKeyCode() == KeyEvent.VK_CONTROL)
        //shooting = true; // Start shooting if ctrl is pushed
}

public void keyReleased(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_UP)
        ship.setAccelerating(false);
    else if (e.getKeyCode() == KeyEvent.VK_LEFT)
        ship.setTurningLeft(false);
    else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
        ship.setTurningRight(false);
    //else if (e.getKeyCode() == KeyEvent.VK_CONTROL)
        //shooting = false;
}

public void keyTyped(KeyEvent e) {
}
}

1 个答案:

答案 0 :(得分:0)

我相信createImage()将返回null,直到组件实际在屏幕上,我相信在线程启动之后。

而不是:

img = createImage(dim.width, dim.height);
g = img.getGraphics();
thread = new Thread(this);
thread.start();

尝试:

 new Thread(new Runnable() {
    public void run() {
        do {
            try {
                Thread.sleep(25);
            } catch(InterruptedException e) {
                System.out.println("wait interrupted");
                break;
            }
        } while(!isDisplayable());
        // Now it should be safe to make these calls.
        img= createImage(dim.width, dim.height);
        g = img.getGraphics();
        start();
    }
}).start();