我在一个小“项目”上测试了自己。它基本上是一个生存游戏。使用W,A,S,D移动,使用箭头键向不同方向拍摄。你的目标是尽可能长久地生存。敌人跟着你,他们会在命中时冻结。它们在3秒后再次开始移动。
代码如下(执行“window”类)
窗口级
package TestGame;
import java.awt.Graphics;
public class Window extends GameIntern{
public void init(){
setSize(windowX,windowY);
Thread th = new Thread(this);
th.start();
offscreen = createImage(windowX,windowY);
d = offscreen.getGraphics();
addKeyListener(this);
}
public void paint(Graphics g){
d.clearRect(0,0,windowX,windowY);//clear window
d.drawString(numberEnemies.toString(), 10, 10);//"Score" number of enemies displayed
d.drawRect(x, y, playerWidth, playerHeight);//draw player
for(Enemy e : enemies){//draw all enemies
d.drawRect(e.getx(), e.gety(), playerWidth, playerHeight);
}
for(Bullet b : bullets){//draw all bullets
d.drawOval(b.getx(), b.gety(), bulletSize, bulletSize);
}
g.drawImage(offscreen,0,0,this);
}
public void update(Graphics g){
paint(g);
}
}
GameIntern级
package TestGame;
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
public class GameIntern extends Applet implements Runnable , KeyListener {
public int windowX = 854;//size of the window in x direction
public int windowY = 460;//size of the window in y direction
public static int x;//x-coordinate of player
public static int y;//y-coordinate of player
public int playerpositionX = x;
public int playerpositionY = y;
public int playerHeight = 20;//player height
public int playerWidth = 20;//player width
public int playerSpeed = 3;//pixel per frame
public int bulletSize = 5;//diameter of bullets
public int spawnTime = 4;//time for new enemies to spawn in seconds
public int enemySleepTime = 180;//Time an enemy does nothing in Frames per second (180 in 60fps = 3sec)
public boolean alive = true;
public Image offscreen;
public Graphics d;
public boolean up,down,left,right;
private int delay;
private Random random= new Random();
public Integer numberEnemies = new Integer(enemies.size());
protected static List<Enemy> enemies = Collections.synchronizedList(new ArrayList<Enemy>()); //List of all enemies
protected static List<Bullet> bullets = Collections.synchronizedList(new ArrayList<Bullet>());//List of all bullets
protected static List<PowerUps> powerups = Collections.synchronizedList(new ArrayList<PowerUps>());//List of all powerups
public void run() {
this.x = 400;//startingposition x
this.y = 240;//startingposition y
double ns = 1000000000.0 / 60.0; //60 "frames"
double delta = 0;
long lastTime = System.nanoTime();
while (alive) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
repaint();
tick(); //Line 53
collisionEnemy();
// collisionPowerUp();
delta--;
}
}
}
/**
* Method to calculate all objects and their positions per frame
*/
private void tick() {
if(left == true){
if(x>=0 + playerSpeed){
x-=playerSpeed;
}else{ x=0;}//Farthest left x-coordinate
repaint();
}
if(right == true){
if(x<=windowX - playerWidth - playerSpeed){
x+=playerSpeed;
}else{ x=windowX - playerWidth;}//Farthest right x-coordinate
repaint();
}
if(up == true){
if(y>=0 + playerSpeed){
y-=playerSpeed;
}else{ y=0;}//Highest y-coordinate
repaint();
}
if(down == true){
if(y<=windowY - playerHeight - playerSpeed){
y+=playerSpeed;
}else{y=windowY - playerHeight;}//Lowest y-coordinate
repaint();
}
for (Enemy e : enemies) { //Tick every enemy
e.tick();
}
for (Bullet b : bullets){ //Tick every bullet (LINE 92 !)
b.tick();
}
if(delay % (60 * spawnTime) == 0){ //Spawn enemy
enemies.add(new Enemy(random.nextInt(windowX), random.nextInt(windowY)));
numberEnemies++;
}
delay++;
//Remove bullets, in contact with enemy
LinkedList<Bullet> bulletsToRemove = new LinkedList<>();
for(Enemy e : enemies){ //collision : enemy & bullet
for(Bullet b : bullets){
if(b.getx()+bulletSize >= e.getx() && b.getx() <= e.getx()+20){
if(b.gety()+bulletSize >= e.gety() && b.gety() <= e.gety()+20){
e.setHit();
bulletsToRemove.add(b);
}
}
}
}
for(Bullet b : bulletsToRemove){ //Remove bullets from ArrayList
bullets.remove(b);
}
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == 65){//W
left=true;
}
if(e.getKeyCode() == 87){//A
up=true;
}
if(e.getKeyCode() == 68){//S
right=true;
}
if(e.getKeyCode() == 83){//D
down=true;
}
}
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == 65){//Arrowkey left
left=false;
}
if(e.getKeyCode() == 87){//Arrowkey up
up=false;
}
if(e.getKeyCode() == 68){//Arrowkey right
right=false;
}
if(e.getKeyCode() == 83){//Arrowkey dowm
down=false;
}
if(e.getKeyCode() == 37){//Arrowkey left
bullets.add(new Bullet(x,y,false,false,true,false)); //Direction the bullet has to go
}
if(e.getKeyCode() == 38){//Arrowkey up
bullets.add(new Bullet(x,y,true,false,false,false));//Direction the bullet has to go
}
if(e.getKeyCode() == 39){//Arrowkey right
bullets.add(new Bullet(x,y,false,false,false,true));//Direction the bullet has to go
}
if(e.getKeyCode() == 40){//Arrowkey down
bullets.add(new Bullet(x,y,false,true,false,false));//Direction the bullet has to go
}
}
public void keyTyped(KeyEvent e){}
/**
* Method to see if the player collided with an enemy
*/
public void collisionEnemy(){
for(Enemy e : enemies){
for(int i = 0;i <= playerWidth; i++){
if(GameIntern.x+i >= e.getx() && GameIntern.x+i <= e.getx()+playerWidth){
if(GameIntern.y+i >= e.gety() && GameIntern.y+i <= e.gety()+playerHeight){
alive = false;
}
}
}
}
}
// public void addEnemy(){
// enemies.add(new Enemy(random.nextInt(windowX), random.nextInt(windowY)));
//
// //Spawn enemies inside the filed, not outside the boarder
// if (playerpositionX < playerWidth * 2 || playerpositionX * 2 > windowX - 2*playerWidth || playerpositionY * 2 > windowY - 2*playerHeight || playerpositionY < playerHeight * 2){
// enemies.add(new Enemy(random.nextInt(windowX - 3*playerWidth), random.nextInt(windowY - 3*playerHeight)+3*playerHeight));
// }else {
// int temp1 = random.nextInt(windowX-3*playerWidth);
// if (temp < playerpositionX){
//
// }
// enemies.add(new Enemy(random.nextInt(windowX), random.nextInt(windowY)));
// }
//
// }
}
子弹级
package TestGame;
public class Bullet extends GameIntern{
public int x,y;
public boolean up,down,left,right;
public boolean remove;
public Bullet(int x, int y,boolean up,boolean down, boolean left, boolean right){
this.x = x + 8;
this.y = y + 8;
this.up = up;
this.down = down;
this.left = left;
this.right = right;
}
public int getx(){
return this.x;
}
public int gety(){
return this.y;
}
public void setRemove(){
remove=true;
}
public void tick() {
if (up == true) y-=2;
if (down == true) y+=2;
if (left == true) x-=2;
if (right == true) x+=2;
if(x < 0){
remove = true;
}
if(x > 840){
remove = true;
}
if(y < 0){
remove = true;
}
if(y > 470){
remove = true;
}
}
}
敌人级
package TestGame;
public class Enemy extends GameIntern {
public int x,y;
public boolean hit = false;
public int counter = 0;
public Enemy(int x, int y) {
this.x = x;
this.y = y;
}
public int getx(){
return this.x;
}
public int gety(){
return this.y;
}
public void setHit(){
hit = true;
counter = enemySleepTime;
}
public void tick() {
if(counter == 0){
if(hit == true){
hit=false;
}
if (x < GameIntern.x) x++;
if (x > GameIntern.x) x--;
if (y < GameIntern.y) y++;
if (y > GameIntern.y) y--;
}else {counter--;}
}
}
玩了一会儿后我得到了
我不明白这个例外。有人可以向我解释我做错了什么吗?
我该如何解决这个问题?