1

スタックとJavaの新しい男。

まず、これが私のコード、AsteroidsGame.java です。

   import java.applet.*;
   import java.awt.*;
   import java.awt.event.*;
   import javax.swing.*;
   import java.net.*;
   import java.util.*;


public class AsteroidsGame extends JApplet 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;

    int numAsteroids;

    double astRadius;

    double minAstVel;

    double maxAstVel;

    int astNumHits;

    int astNumSplit;

    int level;

    private AudioClip audioClip;




public void init() {

    resize(500, 500);

    shots = new Shot[41];

    numAsteroids = 0;

    level = 0;

    astRadius = 60;

    minAstVel = .5;

    maxAstVel = 5;

    astNumHits = 3;

    astNumSplit = 2;

    endTime = 0;

    startTime = 0;

    framePeriod = 25;

    addKeyListener(this);

    setFocusable(true);

    requestFocusInWindow();

    dim = getSize();

    img = createImage(dim.width, dim.height);

    g = img.getGraphics();

    thread = new Thread(this);

    thread.start();

    URL urlAudioClip = getClass().getResource("audio/minorcircuit.wav");

    audioClip = Applet.newAudioClip(urlAudioClip);

    audioClip.loop();

}



public void start() {

    audioClip.loop();

}

public void stop() {

    audioClip.stop();

}





public void setUpNextLevel() {

    level++;

    ship = new Ship(250, 250, 0, .35, .98, .1, 12);

    numShots = 0;

    paused = false;

    shooting = false;

    asteroids = new Asteroid[level * (int)Math.pow(astNumSplit, astNumHits - 1) + 1];

    numAsteroids = level;

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

        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);

    g.drawString("Level " + level, 20, 20);

    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

            for(int i = 0; i < numShots; i++) {

                shots[i].move(dim.width, dim.height);

                if(shots[i].getLifeLeft() <= 0) {

                    deleteShot(i);

                    i--;

                }

            }

            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 asteroid in at end of 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

        if(asteroids[i].shipCollision(ship)) {

            level--;

//restart this level

            numAsteroids = 1;

            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;

                i--;

            }

        }

    }

}



public void keyPressed(KeyEvent e) {

    if(e.getKeyCode() == KeyEvent.VK_ENTER) {

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

        return;

    }

    else if(e.getKeyCode() == KeyEvent.VK_SPACE) {

        ship.setAccelerating(true);

    }

    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;

    }

    else if(e.getKeyCode() == KeyEvent.VK_M) {

        audioClip.stop();

    }

    else if(e.getKeyCode() == KeyEvent.VK_S) {

        audioClip.loop();

    }

}



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

}



}

これは小惑星の「クローン」です。私よりも少し長くプレイしている方の中には、アーケードでプレイしたことがある人もいるでしょう。とにかく、私は Java コースの最終プロジェクトのためにこれを書きましたが、完全に機能することはありませんでした。うまく起動し、向きを変えて撃つことはできますが、前進することはできません。ただ、今は引っ越しの心配はありません。アプレットが起動すると、音楽が再生され、「小惑星」が画面上を移動します。小惑星を発射するか、いずれかの方向に 3 回発射すると、スレッド例外が発生します。

Exception in thread "Thread-3" java.lang.NullPointerException
at AsteroidsGame.updateAsteroids(AseroidsGame.java:161)
at AsteroidsGame.run(AsteroidsGame.java:115)
at java.lang.Thread.run(Thread.java:722)

オンラインで見回しても、ほとんど役に立ちませんでした。私が学んだことのほとんどは独学であり、頭を包み込むのは簡単ではありません. この例外を解決するためにここで何をすべきか正確にはわかりません。スタック上の別のスレッドでは、以前は配列がサイズで宣言されていなかったため、ArrayList を使用することが言及されていました。それをいじった。それが機能することはありませんでした。

アイデア/提案/批評が必要です。完成したと言えるように、これを機能させたいのです。

その他のクラス、Asteroid.java

import java.awt.*;



public class Asteroid {



double x, y, xVelocity, yVelocity, radius;

int hitsLeft, numSplit;



public Asteroid(double x,double y,double radius,double minVelocity, double maxVelocity,int hitsLeft,int numSplit) {

    this.x = x;

    this.y = y;

    this.radius = radius;

    this.hitsLeft = hitsLeft;

    this.numSplit = numSplit;

    double vel = minVelocity + Math.random() * (maxVelocity - minVelocity);

    double dir = 2 * Math.PI * Math.random();

    xVelocity = vel * Math.cos(dir);

    yVelocity = vel * Math.sin(dir);

}



public void move(int scrnWidth, int scrnHeight) {

    x += xVelocity;

    y += yVelocity;

    if(x < 0 - radius) {

        x += scrnWidth + 2 * radius;

    }

    else if(x > scrnWidth + radius) {

        x -= scrnWidth + 2 * radius;

    }

    if(y < 0 - radius) {

        y += scrnHeight + 2 * radius;

    }

    else if(y > scrnHeight + radius) {

        y -= scrnHeight + 2 * radius;

    }

}



public void draw(Graphics g) {

    g.setColor(Color.gray);

    g.fillOval((int)(x - radius + .5), (int)(y - radius + .5), (int)(2 * radius), (int)(2 * radius));

}



public Asteroid createSplitAsteroid(double minVelocity,double maxVelocity) {

    return new Asteroid(x, y, radius / Math.sqrt(numSplit), minVelocity, maxVelocity, hitsLeft - 1, numSplit);

}



public boolean shipCollision(Ship ship) {

    if(Math.pow(radius + ship.getRadius(), 2) > Math.pow(ship.getX() - x, 2) + Math.pow(ship.getY() - y, 2) && ship.isActive()) {

        return true;

    }

    return false;

}



public boolean shotCollision(Shot shot) {

    if(Math.pow(radius, 2) > Math.pow(shot.getX() - x, 2) + Math.pow(shot.getY() - y, 2)) {

        return true;

    }

    return false;

}



public int getHitsLeft() {

    return hitsLeft;

}



public int getNumSplit() {

    return numSplit;

}

}

Ship.java

import java.awt.*;



public class Ship {



final double[] origXPts = {14,-10,-6,-10}, origYPts = {0,-8,0,8}, origFlameXPts = {-6,-23,-6}, origFlameYPts = {-3,0,3};

final int radius = 6;



double x, y, angle, xVelocity, yVelocity, acceleration, velocityDecay, rotationalSpeed;

//used for movement

boolean turningLeft, turningRight, accelerating, active;

int [] xPts, yPts, flameXPts, flameYPts;

//current location of ship

int shotDelay, shotDelayLeft;

//rate of fire



public Ship(double x, double y, double angle, double acceleration, double velocityDecay, double rotationalSpeed, int shotDelay) {

    this.x = x;

    this.y = y;

    this.angle = angle;

    this.acceleration = acceleration;

    this.velocityDecay = velocityDecay;

    this.rotationalSpeed = rotationalSpeed;

    xVelocity = 0;

    yVelocity = 0;

    turningLeft = false;

    turningRight = false;

    accelerating = false;

    active = false;

    xPts = new int[4];

    yPts = new int[4];

    flameXPts = new int[3];

    flameYPts = new int[3];

    this.shotDelay = shotDelay;

    shotDelayLeft = 0;

}



public void draw(Graphics g) {

    if(accelerating && active) {

        for(int i = 0; i < 3; i++) {

            flameXPts[i] = (int)(origFlameXPts[i] * Math.cos(angle) - origFlameYPts[i] * Math.sin(angle) + x + .5);

            flameYPts[i] = (int)(origFlameXPts[i] * Math.sin(angle) + origFlameYPts[i] * Math.cos(angle) + y + .5);

        }

        g.setColor(Color.red);

//color of flame

        g.fillPolygon(flameXPts, flameYPts, 3);



    }

    for(int i = 0; i < 4; i++) {

        xPts[i] = (int)(origXPts[i] * Math.cos(angle) - origYPts[i] * Math.sin(angle) + x + .5);

        yPts[i] = (int)(origXPts[i] * Math.sin(angle) + origYPts[i] * Math.cos(angle) + y + .5);

    }



    if(active) {

        g.setColor(Color.white);

    }

    else {

        g.setColor(Color.darkGray);

    }

    g.fillPolygon(xPts, yPts, 4);

}



public void move(int scrnWidth, int scrnHeight) {

    if(shotDelayLeft > 0) {

        shotDelayLeft--;

    }

    if(turningLeft) {

        angle -= rotationalSpeed;

    }

    if(turningRight) {

        angle += rotationalSpeed;

    }

    if(angle > (2 * Math.PI)) {

        angle -= (2 * Math.PI);

    }

    else if(angle < 0) {

        angle += (2 * Math.PI);

    }

    if(accelerating) {

        xVelocity += acceleration * Math.cos(angle);

        yVelocity += acceleration * Math.sin(angle);

    }

    x += xVelocity;

    y += yVelocity;

    xVelocity *= velocityDecay;

    yVelocity *= velocityDecay;

    if(x<0) {

        x += scrnWidth;

    }

    else if(x > scrnWidth) {

        x -= scrnWidth;

    }

    if(y < 0) {

        y += scrnHeight;

    }

    else if(y > scrnHeight) {

        y -= scrnHeight;

    }

}



public void setAccelerating(boolean accelerating) {

    this.accelerating = accelerating;

//start or stop accelerating the ship

}



public void setTurningLeft(boolean turningLeft) {

    this.turningLeft = turningLeft;

//start or stop turning the ship

}



public void setTurningRight(boolean turningRight) {

    this.turningRight = turningRight;

}



public double getX() {

    return x;

//returns the ship’s x location

}



public double getY() {

    return y;

//returns the ship's y location

}



public double getRadius() {

    return radius;

//returns radius of circle that approximates the ship

}



public void setActive(boolean active) {

    this.active = active;

//used when the game is paused or unpaused

}



public boolean isActive() {

    return active;

}



public boolean canShoot() {

    if(shotDelayLeft > 0) {

        return false;

    }

    else {

        return true;

    }

}



public Shot shoot() {

    shotDelayLeft=shotDelay;

//set delay till next shot can be fired

//a life of 40 makes the shot travel about the width of the

//screen before disappearing

    return new Shot(x, y, angle, xVelocity, yVelocity, 40);

}

}

ショット.java

import java.awt.*;



public class Shot {



final double shotSpeed = 12;

double x, y, xVelocity, yVelocity;

int lifeLeft;



public Shot(double x, double y, double angle, double shipXVel, double shipYVel, int lifeLeft) {

    this.x = x;

    this.y = y;

    xVelocity = shotSpeed * Math.cos(angle) + shipXVel;

    yVelocity = shotSpeed * Math.sin(angle) + shipYVel;

    this.lifeLeft = lifeLeft;

}



public void move(int scrnWidth, int scrnHeight) {

    lifeLeft--;

    x += xVelocity;

    y += yVelocity;

    if(x < 0) {

        x += scrnWidth;

    }

    else if(x > scrnWidth) {

        x -= scrnWidth;

    }

    if(y < 0) {

        y += scrnHeight;

    }

    else if(y > scrnHeight) {

        y -= scrnHeight;

    }

}



public void draw(Graphics g) {

    g.setColor(Color.yellow);

    g.fillOval((int)(x - .5), (int)(y - .5), 3, 3);

}



public double getX() {

    return x;

}



public double getY() {

    return y;

}



public int getLifeLeft() {

    return lifeLeft;

}

}

見てくれてありがとう。

----------------------2012 年 12 月 9 日編集----------------------- -

NetBeans IDE 7.2.1 でデバッグを試みました。船の方向転換を不適切に描写し、まったく異なるエラーを出します:

Exception in thread "Thread-3" java.lang.NullPointerException
at AsteroidsGame.run(AsteroidsGame.java:122)
at java.lang.Thread.run(Thread.java:722)

run メソッド内の Shot[] shots 配列に注意を向けています。これは、Asteroid[] と Shot[] の配列が同じように設定されているためです。

4

0 に答える 0