I am currently making a Space Shooter in Java. I am able to make bullets shoot and enemies come from the top, but I am not sure how to check if they intersect. I understand that the Rectangle class has a intersects method, but I am not sure how I would place the rectangles around the bullets and the enemies, since I don't know beforehand how many may be on the screen. How can I do this? Here is my code:
Game.java
package main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable, KeyListener {
//declare values
private static final long serialVersionUID = 1L;
public static final int WIDTH = 800;
public static final int HEIGHT = 600;
public static final String TITLE = "Space Shooter";
private boolean running = false;
private Thread thread;
private Player player;
private BufferedImage playerImage;
private BufferedImage bulletImage;
private BufferedImage enemyImage;
int playerx;
int playery;
int round = 1;
public Game() {
//
player = new Player((WIDTH/2)-32, HEIGHT-200);
//allocates all file resources
try {
playerImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/player.png"));
bulletImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/bullet.png"));
enemyImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/enemy.png"));
} catch (IOException e) {
e.printStackTrace();
}
addKeyListener(this);
setFocusable(true);
requestFocusInWindow();
}
//starts thread
private synchronized void start() {
if (running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
//stops thread
private synchronized void stop() {
if (!running)
return;
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.exit(1);
}
#Override
//game loop
public void run() {
long lastTime = System.nanoTime();
final double amountOfTicks = 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int updates = 0;
int frames = 0;
long timer = System.currentTimeMillis();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if (delta > 1) {
tick();
updates++;
delta--;
}
Shoot.updateBullets();
Enemy.updateEnemies();
render();
frames++;
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " TICKS, " + frames + " FPS");
updates = 0;
frames = 0;
}
}
stop();
}
//updates sprite locations
public void tick() {
playerx = player.getX();
playery = player.getY();
}
//renders sprites
public void render() {
//setting up triple-buffering
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
//////////////////////////////////
g.setColor(Color.BLACK); g.fillRect(0,0,getWidth(), getHeight());
g.drawImage(playerImage, playerx, playery, this);
if (Shoot.allBullets.size() != 0) {
for (int i = 0; i < Shoot.allBullets.size(); i++) {
int bulletx = (int) Shoot.allBullets.get(i).x;
int bullety = (int) Shoot.allBullets.get(i).y;
g.drawImage(bulletImage, bulletx + 21, bullety, this);
}
}
if (Enemy.allEnemies.size() != 0) {
for (int i = 0; i < Enemy.allEnemies.size(); i++) {
int enemyx = (int) Enemy.allEnemies.get(i).x;
int enemyy = (int) Enemy.allEnemies.get(i).y;
g.drawImage(enemyImage, enemyx, enemyy, this);
}
} else {
Enemy.createEnemies(round);
round++;
}
//////////////////////////////////
g.dispose();
bs.show();
}
#Override
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
Shoot.addBullet(player.getX(), player.getY());
}
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_UP) {
player.setY(playery -= 20);
} else if (key == KeyEvent.VK_DOWN) {
player.setY(playery += 20);
} else if (key == KeyEvent.VK_RIGHT) {
player.setX(playerx += 40);
} else if (key == KeyEvent.VK_LEFT) {
player.setX(playerx -= 40);
}
}
public void keyTyped(KeyEvent e) {}
public static void main(String[] args) {
Game game = new Game();
JFrame frame = new JFrame(TITLE);
frame.setSize(WIDTH, HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(game);
frame.getContentPane().setBackground(Color.BLACK);
frame.setVisible(true);
game.start();
}
}
Shoot.java
package main;
import java.util.ArrayList;
public class Shoot {
static ArrayList<Point> allBullets = new ArrayList<Point>();
public static void addBullet(int x, int y) {
allBullets.add(new Point(x, y));
}
public static ArrayList<Point> getAllBulletPosistions() {
return allBullets;
}
public static void updateBullets() {
if (allBullets.size() != 0) {
for (int i = 0; i < allBullets.size(); i++) {
allBullets.get(i).y -= 1;
}
}
}
}
Enemy.java
package main;
import java.util.ArrayList;
public class Enemy {
static ArrayList<Point> allEnemies = new ArrayList<Point>();
public static ArrayList<Point> createEnemies(int round) {
for (int i = 0; i < round; i++) {
Point newEnemyLocation = new Point((int) (Math.random()*Game.WIDTH - 64), 0);
if (newEnemyLocation.x < 64) {
newEnemyLocation.x += 70;
}
allEnemies.add(newEnemyLocation);
}
return allEnemies;
}
int validate(int xpos) {
if (xpos > Game.WIDTH - 64) {
xpos -= 64;
}
if (xpos < 64) {
xpos += 64;
}
return xpos;
}
public static ArrayList<Point> updateEnemies() {
if (allEnemies.size() != 0) {
for (int i = 0; i < allEnemies.size(); i++) {
Point enemyLocation = allEnemies.get(i);
if (enemyLocation.y <= Game.HEIGHT) {
allEnemies.get(i).y += 0.1;
} else {
allEnemies.remove(i);
}
}
}
return allEnemies;
}
}
for(int i = 0; i < Shoot.allBullets.size(); i++){
for(int j = 0; j < Enemy.allEnemys.size(); j++){
if(new Rectangle(Shoot.allBullets.get(i).x,Shoot.allBullets.get(i).y, width, height).intersects(new Rectangle(Enemy.allEnemys.get(j).x, Enemy.allEnemys.get(j).y, width, height)){
//on intersect
}
}
}
This would work but you shouldn't create new rectangles like this instead you should create a bullet class and a Enemy class that both contains the position and Rectangle anyways good luck!
Related
I am writing a space invaders clone for a school project, I am in the process of writing the aliens and their algorithm for movement with the use of an array.
My issue is a bunch of errors occur when I run the code but I can`t find why?
any help would be appreciated and bare in mind I am very inexperienced with game development and java
bellow is my GamePanel class, and then my Alien class
package Main;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;
import entity.Alien;
import entity.Controller;
import entity.Player;
import entity.playerBullet;
public class GamePanel extends JPanel implements Runnable{
public final int screenHeight = 600;
public final int screenWidth = 800;
public final int playerSize = 48;
int fps = 60;
KeyHandler keyH = new KeyHandler();
Thread gameThread;
public Player player = new Player(this,keyH);
public CollisionChecker cChecker = new CollisionChecker(this);
private Controller c = new Controller(null);
Alien alien;
//player default position
int playerX = 100;
int playerY = 100;
int playerSpeed = 4;
public GamePanel() {
this.setPreferredSize(new Dimension (screenWidth, screenHeight));
this.setBackground(Color.black);
this.setDoubleBuffered(true);
this.addKeyListener(keyH);
this.setFocusable(true);
}
public void startGameThread() {
gameThread = new Thread (this);
gameThread.start();
alien.initAlien();
}
public void run() {
double drawInterval = 1000000000/fps; // 0.01666 seconds = 60 times per seconds
double nextDrawTime = System.nanoTime() + drawInterval;
while(gameThread != null) {
System.out.println("this game is runing");
// update information such as character positions
// draw the screen with the updated information
update();
repaint();
try {
double remainingTime = nextDrawTime - System.nanoTime();
remainingTime = remainingTime/1000000;
if(remainingTime<0) {
remainingTime = 0;
}
Thread.sleep ((long) remainingTime);
nextDrawTime += drawInterval;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void update() {
player.update();
c.tick();
alien.moveAliens();
}
public void paintComponent(Graphics g) {
// to draw something
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
player.draw(g2);
c.render(g );
g2.dispose();
alien.render(g );
}
}
Alien class
package entity;
import java.awt.Color;
import java.awt.Graphics;
public class Alien {
boolean isVisible;
boolean moveLeft;
boolean moveRight;
Alien[] a = new Alien[10];
private int x;
private int y;
int ax = 10;
int ay = 10;
public Alien(int x, int y) {
}
public void initAlien() {
for(int i=0;i<a.length; i++) {
a[i] = new Alien(ax,ay);
ax += 40;
if(i==4) {
ax=10;
ay+=40;
}
}
}
public void moveAliens() {
for(int i=0;i<a.length; i++) {
if (a[i].moveLeft ==true) {
a[i].x -=2;
}
if (a[i].moveRight ==true) {
a[i].x+=2;
}
for(int i1 = 0; i<a.length; ) {
if(a[i].x>600) {
for(int j =0;j<a.length; j++) {
a[j].moveLeft = true;
a[j].moveRight = false;
a[j].y += 5;
}
}
if(a[i].x<0) {
for(int j = 0; j< a.length; j++) {
a[j].moveLeft = false;
a[j].moveRight = true;
a[j].y += 5;
}
}
}
}
}
To be frank i have not the slightest clue how to fix this whats so ever. It works until you get to the part that only 1 brick shows and its kinda frustrating... If anyone could help me i would appreciate it. I did look up how to fix this but i didn't even find anyone that had this problem. Google searching isn't really that good. Oh and i used Eclipse for this program.
Board Class
package Final;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JPanel;
public class Board extends JPanel implements Commons {
private Timer timer;
private String message = "Your Fired";
private Ball ball;
private Paddle paddle;
private Brick bricks[];
private boolean ingame = true;
public Board() {
initBoard();
}
private void initBoard() {
addKeyListener(new TAdapter());
setFocusable(true);
bricks = new Brick[N_OF_BRICKS];
setDoubleBuffered(true);
timer = new Timer();
timer.scheduleAtFixedRate(new ScheduleTask(), DELAY, PERIOD);
}
#Override
public void addNotify() {
super.addNotify();
gameInit();
}
private void gameInit() {
ball = new Ball();
paddle = new Paddle();
int k = 0;
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 6; j++) {
bricks[k] = new Brick(j * 40 + 30, i * 10 + 50);
k++;
}
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
if (ingame) {
drawObjects(g2d);
} else {
gameFinished(g2d);
}
Toolkit.getDefaultToolkit().sync();
}
private void drawObjects(Graphics2D g2d) {
g2d.drawImage(ball.getImage(), ball.getX(), ball.getY(),
ball.getWidth(), ball.getHeight(), this);
g2d.drawImage(paddle.getImage(), paddle.getX(), paddle.getY(),
paddle.getWidth(), paddle.getHeight(), this);
for (int i = 0; i < N_OF_BRICKS; i++) {
if (!bricks[i].isDestroyed()) {
g2d.drawImage(bricks[i].getImage(), bricks[i].getX(),
bricks[i].getY(), bricks[i].getWidth(),
bricks[i].getHeight(), this);
}
}
}
private void gameFinished(Graphics2D g2d) {
Font font = new Font("Verdana", Font.BOLD, 18);
FontMetrics metr = this.getFontMetrics(font);
g2d.setColor(Color.BLACK);
g2d.setFont(font);
g2d.drawString(message,
(Commons.WIDTH - metr.stringWidth(message)) / 2,
Commons.WIDTH / 2);
}
private class TAdapter extends KeyAdapter {
#Override
public void keyReleased(KeyEvent e) {
paddle.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
paddle.keyPressed(e);
}
}
private class ScheduleTask extends TimerTask {
#Override
public void run() {
ball.move();
paddle.move();
checkCollision();
repaint();
}
}
private void stopGame() {
ingame = false;
timer.cancel();
}
private void checkCollision() {
if (ball.getRect().getMaxY() > Commons.BOTTOM_EDGE) {
stopGame();
}
for (int i = 0, j = 0; i < N_OF_BRICKS; i++) {
if (bricks[i].isDestroyed()) {
j++;
}
if (j == N_OF_BRICKS) {
message = "Pay Day";
stopGame();
}
}
if ((ball.getRect()).intersects(paddle.getRect())) {
int paddleLPos = (int) paddle.getRect().getMinX();
int ballLPos = (int) ball.getRect().getMinX();
int first = paddleLPos + 8;
int second = paddleLPos + 16;
int third = paddleLPos + 24;
int fourth = paddleLPos + 32;
if (ballLPos < first) {
ball.setXDir(-1);
ball.setYDir(-1);
}
if (ballLPos >= first && ballLPos < second) {
ball.setXDir(-1);
ball.setYDir(-1 * ball.getYDir());
}
if (ballLPos >= second && ballLPos < third) {
ball.setXDir(0);
ball.setYDir(-1);
}
if (ballLPos >= third && ballLPos < fourth) {
ball.setXDir(1);
ball.setYDir(-1 * ball.getYDir());
}
if (ballLPos > fourth) {
ball.setXDir(1);
ball.setYDir(-1);
}
}
for (int i = 0; i < N_OF_BRICKS; i++) {
if ((ball.getRect()).intersects(bricks[i].getRect())) {
int ballLeft = (int) ball.getRect().getMinX();
int ballHeight = (int) ball.getRect().getHeight();
int ballWidth = (int) ball.getRect().getWidth();
int ballTop = (int) ball.getRect().getMinY();
Point pointRight = new Point(ballLeft + ballWidth + 1, ballTop);
Point pointLeft = new Point(ballLeft - 1, ballTop);
Point pointTop = new Point(ballLeft, ballTop - 1);
Point pointBottom = new Point(ballLeft, ballTop + ballHeight + 1);
if (!bricks[i].isDestroyed()) {
if (bricks[i].getRect().contains(pointRight)) {
ball.setXDir(-1);
} else if (bricks[i].getRect().contains(pointLeft)) {
ball.setXDir(1);
}
if (bricks[i].getRect().contains(pointTop)) {
ball.setYDir(1);
} else if (bricks[i].getRect().contains(pointBottom)) {
ball.setYDir(-1);
}
bricks[i].setDestroyed(true);
}
}
}
}
}
Brick Class
package Final;
import javax.swing.ImageIcon;
public class Brick extends Sprite {
private boolean destroyed;
public Brick(int x, int y) {
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
}
public boolean isDestroyed() {
return destroyed;
}
public void setDestroyed(boolean val) {
destroyed = val;
}
}
Commons Class
package Final;
public interface Commons {
public static final int WIDTH = 300;
public static final int HEIGTH = 400;
public static final int BOTTOM_EDGE = 390;
public static final int N_OF_BRICKS = 30;
public static final int INIT_PADDLE_X = 200;
public static final int INIT_PADDLE_Y = 360;
public static final int INIT_BALL_X = 230;
public static final int INIT_BALL_Y = 355;
public static final int DELAY = 1000;
public static final int PERIOD = 10;
}
Sprite Class
package Final;
import java.awt.Image;
import java.awt.Rectangle;
public class Sprite {
protected int x;
protected int y;
protected int i_width;
protected int i_heigth;
protected Image image;
public void setX(int x) {
this.x = x;
}
public int getX() {
return x;
}
public void setY(int y) {
this.y = y;
}
public int getY() {
return y;
}
public int getWidth() {
return i_width;
}
public int getHeight() {
return i_heigth;
}
Image getImage() {
return image;
}
Rectangle getRect() {
return new Rectangle(x, y,
image.getWidth(null), image.getHeight(null));
}
}
Breakout Class
package Final;
import java.awt.EventQueue;
import javax.swing.JFrame;
public class Breakout extends JFrame {
public Breakout() {
initUI();
}
private void initUI() {
add(new Board());
setTitle("Lord Carl's Demolition Job");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(Commons.WIDTH, Commons.HEIGTH);
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Breakout game = new Breakout();
game.setVisible(true);
}
});
}
}
The problem is in checkCollision(). Inside the loop, j will never equal N_OF_BRICKS because of the loop condition. You could change to:
private void checkCollision() {
if (ball.getRect().getMaxY() > Commons.BOTTOM_EDGE) {
stopGame();
}
int j = 0;
for (int i = 0; i < N_OF_BRICKS; i++) {
if (bricks[i].isDestroyed()) {
j++;
}
}
if (j == N_OF_BRICKS) {
message = "Pay Day";
stopGame();
}
}
Also, in the Brick class you neglect to store the x,y coords:
public class Brick extends Sprite {
....
public Brick(int x, int y) {
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
// Save these
this.x = x;
this.y = y
}
....
}
Or, add a constructor to the Sprite class and call that from the Brick constructor:
public class Sprite {
....
public Sprite(int x, int y) {
this.x = x;
this.y = y;
}
....
}
public class Brick extends Sprite {
....
public Brick(int x, int y) {
// Call the sprite constructor
super(x, y);
ImageIcon ii = new ImageIcon("images/bricks.png");
image = ii.getImage();
i_width = image.getWidth(null);
i_heigth = image.getHeight(null);
destroyed = false;
}
....
}
I try running this program and I get a static void error. I am new to this and I have no idea how to fix this problem so any input would be helpful, thank you!
package johnbarthelmes.Java;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Board extends JPanel implements ActionListener {
private final int B_WIDTH = 300;
private final int B_HEIGHT = 300;
private final int DOT_SIZE = 10;
private final int ALL_DOTS = 900;
private final int RAND_POS = 29;
private final int DELAY = 140;
private final int x[] = new int[ALL_DOTS];
private final int y[] = new int[ALL_DOTS];
private int dots;
private int apple_x;
private int apple_y;
private boolean leftDirection = false;
private boolean rightDirection = true;
private boolean upDirection = false;
private boolean downDirection = false;
private boolean inGame = true;
private Timer timer;
private Image ball;
private Image apple;
private Image head;
public Board() {
addKeyListener(new TAdapter());
setBackground(Color.black);
setFocusable(true);
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
loadImages();
initGame();
}
private void loadImages() {
ImageIcon iid = new ImageIcon("dot.png");
ball = iid.getImage();
ImageIcon iia = new ImageIcon("apple.png");
apple = iia.getImage();
ImageIcon iih = new ImageIcon("head.png");
head = iih.getImage();
}
private void initGame() {
dots = 3;
for (int z = 0; z < dots; z++) {
x[z] = 50 - z * 10;
y[z] = 50;
}
locateApple();
timer = new Timer(DELAY, this);
timer.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
private void doDrawing(Graphics g) {
if (inGame) {
g.drawImage(apple, apple_x, apple_y, this);
for (int z = 0; z < dots; z++) {
if (z == 0) {
g.drawImage(head, x[z], y[z], this);
} else {
g.drawImage(ball, x[z], y[z], this);
}
}
Toolkit.getDefaultToolkit().sync();
} else {
gameOver(g);
}
}
private void gameOver(Graphics g) {
String msg = "Game Over";
Font small = new Font("Helvetica", Font.BOLD, 14);
FontMetrics metr = getFontMetrics(small);
g.setColor(Color.white);
g.setFont(small);
g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) / 2, B_HEIGHT / 2);
}
private void checkApple() {
if ((x[0] == apple_x) && (y[0] == apple_y)) {
dots++;
locateApple();
}
}
private void move() {
for (int z = dots; z > 0; z--) {
x[z] = x[(z - 1)];
y[z] = y[(z - 1)];
}
if (leftDirection) {
x[0] -= DOT_SIZE;
}
if (rightDirection) {
x[0] += DOT_SIZE;
}
if (upDirection) {
y[0] -= DOT_SIZE;
}
if (downDirection) {
y[0] += DOT_SIZE;
}
}
private void checkCollision() {
for (int z = dots; z > 0; z--) {
if ((z > 4) && (x[0] == x[z]) && (y[0] == y[z])) {
inGame = false;
}
}
if (y[0] >= B_HEIGHT) {
inGame = false;
}
if (y[0] < 0) {
inGame = false;
}
if (x[0] >= B_WIDTH) {
inGame = false;
}
if (x[0] < 0) {
inGame = false;
}
if(!inGame) {
timer.stop();
}
}
private void locateApple() {
int r = (int) (Math.random() * RAND_POS);
apple_x = ((r * DOT_SIZE));
r = (int) (Math.random() * RAND_POS);
apple_y = ((r * DOT_SIZE));
}
#Override
public void actionPerformed(ActionEvent e) {
if (inGame) {
checkApple();
checkCollision();
move();
}
repaint();
}
private class TAdapter extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) {
leftDirection = true;
upDirection = false;
downDirection = false;
}
if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) {
rightDirection = true;
upDirection = false;
downDirection = false;
}
if ((key == KeyEvent.VK_UP) && (!downDirection)) {
upDirection = true;
rightDirection = false;
leftDirection = false;
}
if ((key == KeyEvent.VK_DOWN) && (!upDirection)) {
downDirection = true;
rightDirection = false;
leftDirection = false;
}
}
}
}
If it helps at all this is the code for the snake game that I got from a Dr Java tutorial in which I followed all the steps correctly as far as I know. There was no errors compiling but when I ran the program I got that error message.
In order to run an application, your class needs a main method with a certain signature, so Java knows what to do. Probably you want to start up the program by showing your JFrame:
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Board b = new Board();
b.setVisible(true);
}
});
}
You need to add a main method. It's the entry point to every Java application. It looks like it should have this implementation, based on your code sample.
public static void main(String[] args) {
Board board = new Board();
// need to do something else with board here maybe?
}
I'm creating a game like zType
and I have a problem in validating the input. As you can see in the picture below it select two words. How can I fix this problem, please help.
This is My Game class
import java.awt.Canvas;
import java.awt.event.KeyListener;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.LinkedList;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable, KeyListener
{
public static final int WIDTH = 640;
public static final int HEIGHT = 680;
public final String TITLE = "Game";
private boolean running = false;
private Thread thread;
private BufferedImage spriteSheet = null;
private BufferedImage background = null;
public int level = 1;
public int fps = 0;
public int score = 0;
private int enemy_count = 15;
private int enemy_killed = 0;
private int enemy_notkilled = 0;
private boolean target = false;
public String t = "";
private Controller c;
private Textures tex;
private LinkedList<Enemy> e = new LinkedList<Enemy>();
private Enemy enemy;
public void init()
{
requestFocus();
try
{
spriteSheet = ImageIO.read(getClass().getResource("/sprite_sheet.png"));
background = ImageIO.read(getClass().getResource("/background.png"));
}
catch(IOException e)
{
e.printStackTrace();
}
tex = new Textures(this);
c = new Controller(tex, this);
addKeyListener(this);
c.createEnemy(enemy_count);
e = c.getEnemy();
}
private synchronized void start()
{
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
private synchronized void stop()
{
if(!running)
return;
running = false;
try
{
thread.join();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
System.exit(1);
}
public void run()
{
init();
long lastTime = System.nanoTime();
final double amountOfTicks= 60.0;
double ns = 1000000000 / amountOfTicks;
double delta = 0;
int frames = 0;
long timer = System.currentTimeMillis();
while(running)
{
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
if(delta >= 1)
{
update();
delta--;
}
render();
frames++;
if(System.currentTimeMillis() - timer > 1000)
{
timer += 1000;
fps = frames;
frames = 0;
}
}
stop();
}
private void update()
{
c.update();
if(enemy_killed + enemy_notkilled >= enemy_count)
{
e.clear();
t = "";
level++;
enemy_killed = 0;
enemy_notkilled = 0;
c.createEnemy(enemy_count);
}
}
private void render()
{
BufferStrategy bs = this.getBufferStrategy();
if(bs == null)
{
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawImage(background, 0, 0, null);
c.render(g);
g.dispose();
bs.show();
}
public void keyPressed(KeyEvent ek)
{
int key = ek.getKeyCode();
char character = Character.toLowerCase(ek.getKeyChar());
boolean result = isValid(key);
if(result && !target)
{
for(int i = 0; i < e.size(); i++)
if(e.get(i).getFirstLetter() == character && e.get(i).getOnScreen())
{
enemy = e.get(i);
t = enemy.getText();
if(enemy.getCurrentIndex() == 0)
enemy.addCurrentIndex();
target = true;
System.out.println("---"+enemy.text);
break;
}
}
else if(result && t.charAt(enemy.getCurrentIndex()) == character)
enemy.addCurrentIndex();
}
public void keyReleased(KeyEvent ek){ }
public void keyTyped(KeyEvent ek){ }
public static void main(String[] args)
{
Game game = new Game();
game.setPreferredSize(new Dimension(WIDTH, HEIGHT));
game.setMaximumSize(new Dimension(WIDTH, HEIGHT));
game.setMinimumSize(new Dimension(WIDTH, HEIGHT));
JFrame frame = new JFrame(game.TITLE);
frame.add(game);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
game.start();
}
public boolean isValid(int key)
{
return key >= 65 && key <= 90 ? true : false;
}
public BufferedImage getSpriteSheet()
{
return spriteSheet;
}
public int getEnemy_count()
{
return enemy_count;
}
public void setEnemy_count(int enemy_count)
{
this.enemy_count = enemy_count;
}
public int getEnemy_killed()
{
return enemy_killed;
}
public void setEnemy_killed(int enemy_killed)
{
this.enemy_killed = enemy_killed;
}
public int getEnemy_notkilled()
{
return enemy_notkilled;
}
public void setEnemy_notkilled(int enemy_notkilled)
{
this.enemy_notkilled = enemy_notkilled;
}
public void addScore(int k)
{
score += k;
}
public void falseTarget()
{
target = false;
}
public String getT()
{
return t;
}
public void setT(String k)
{
t = k;
}
}
This is my Enemy Class
import java.awt.*;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
public class Enemy
{
private double x ,y;
public String text;
private char firstLetter;
private AttributedString as;
private Controller c;
private Textures tex;
private Game game;
private int currentIndex = 0;
private int textLength = 0;
private double speed = 0.0;
private int stringWidth = 0;
private boolean onScreen = false;
public Enemy(double x, double y, double speed, Textures tex, Controller c, Game game, String text, int stringWidth)
{
this.x = x;
this.y = y;
this.tex = tex;
this.text = text;
this.game = game;
this.c = c;
this.speed = speed;
firstLetter = this.text.charAt(0);
textLength = this.text.length();
this.stringWidth = stringWidth;
}
public void update()
{
y += speed;
if(y >= 0)
onScreen = true;
if(currentIndex >= textLength)
{
game.addScore(5);
game.setT("");
c.removeEnemy(this);
game.setEnemy_killed(game.getEnemy_killed() + 1);
game.falseTarget();
}
if(y >= Game.HEIGHT - 50)
{
//game.decreaseHealth();
game.setT("");
c.removeEnemy(this);
game.setEnemy_notkilled(game.getEnemy_notkilled() + 1);
game.falseTarget();
game.t ="";
}
}
public void render(Graphics g)
{
g.drawImage(tex.enemy, (int)x, (int)y, null);
as = new AttributedString(text);
if(currentIndex >= 1)
as.addAttribute(TextAttribute.FOREGROUND, Color.WHITE, 0, currentIndex);
as.addAttribute(TextAttribute.FONT, new Font("Consolas", Font.BOLD, 12), 0, text.length());
g.drawString(as.getIterator(), (int)x + getAdd(stringWidth), (int)y + 13);
}
public double getX()
{
return x;
}
public double getY()
{
return y;
}
public String getText()
{
return text;
}
public char getFirstLetter()
{
return firstLetter;
}
public void addCurrentIndex()
{
currentIndex++;
}
public int getCurrentIndex()
{
return currentIndex;
}
public int getTextLength()
{
return textLength;
}
public int getAdd(int width)
{
return (96 / 2) - (width / 2);
}
public boolean getOnScreen()
{
return onScreen;
}
}
The problem is that you're calling falseTarget() whenever an enemy moves out of the screen. In your example, you assigned target = true when you pressed the 'o' (for the enemy named "owe"), but then a different enemy (maybe "jet", maybe an enemy that is no longer visible) finished "dropping" out of the screen (y >= Game.HEIGHT - 50), so you called falseTarget() - and thus, when you pressed 'i' you started a new enemy ("ice").
What you want to do is call falseTarget() in this case only if the enemy that dropped out of the screen is the one that's currently being targeted:
if(y >= Game.HEIGHT - 50)
{
//game.decreaseHealth();
//game.setT(""); // <-- Commented this line out
c.removeEnemy(this);
game.setEnemy_notkilled(game.getEnemy_notkilled() + 1);
if(game.getT().equals(text)) // <-- Added this if before calling falseTarget()
{ // and clearing the game's current enemy text
game.falseTarget();
game.t ="";
}
}
I am almost done with my first little java game for my final project. It is a sidescroller where you have to shoot/avoid asteroids. My last problem is figuring out how to make my array of asteroids collide with the player's lasers. Here's what I have so far, there's an "AWT-EventQueue-0" java.lang.NullPointerException" on line 137, that I can't deal with. Any help is appreciated.
Edit: I added in my other classes, I realize it would be hard to judge the functionality of my code if I didn't show you where it came from.
package ShooterGame;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
public class Board extends JPanel implements ActionListener
{
Enemy[] baddies = new Enemy[10000];
Player p;
Image img;
int y;
Timer time;
boolean lost = false;
static Font font = new Font("SanSerif", Font.BOLD, 24);
public AudioClip theme, bang, laser;
static ArrayList<Enemy> enemies;
public static int score = 0;
public static int lives = 5;
public Board()
{
p = new Player();
addKeyListener(new ActionListener());
setFocusable(true);
ImageIcon i = new ImageIcon("images/background.png");
img = i.getImage();
time = new Timer(5, this);
time.start();
for(int j = 0; j < baddies.length; j++)
{
Random ran = new Random();
y = ran.nextInt(365)+1;
baddies[j]= new Enemy((100*j + 700), y, "images/asteroid.gif");
}
theme = Applet.newAudioClip(getClass().getResource("theme.mid"));
theme.play();
bang = Applet.newAudioClip(getClass().getResource("bang.wav"));
}
public void actionPerformed(ActionEvent e)
{
checkCollisions();
ArrayList<?> bullets = Player.getBullets();
for(int i = 0; i < bullets.size(); i++)
{
Bullet b = (Bullet)bullets.get(i);
if(b.isVisible() == true)
{
b.move();
}
else
{
bullets.remove(i);
}
}
p.move();
for(int i = 0; i < baddies.length; i++)
{
if(p.x > 400)
{
baddies[i].move(p.getdx());
}
}
repaint();
}
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
if(lost)
{
g2d.drawString("You Lose!", 300, 300);
}
if((p.getX() - 590) % 2400 == 0 || (p.getX() - 590) % 2400 == 1)
{
p.nx = 0;
}
if((p.getX() - 1790) % 2400 == 0 ||(p.getX() - 1790) % 2400 == 1)
{
p.nx2 = 0;
}
g2d.drawImage(img, 685-p.nx2, 0, null);
if(p.getX() >= 590)
{
g2d.drawImage(img, 685-p.nx, 0, null);
}
g2d.drawImage(p.getImage(), p.edge, p.getY(), null);
ArrayList<?> bullets = Player.getBullets();
for(int i = 0; i < bullets.size(); i++)
{
Bullet b = (Bullet)bullets.get(i);
g2d.drawImage(b.getImg(), b.getX(), b.getY(), null);
}
for(int i = 0; i < baddies.length; i++)
{
if(baddies[i].isAlive == true)
{
g2d.drawImage(baddies[i].getImg(), baddies[i].getX(), baddies[i].getY(), null);
}
}
g2d.setColor(Color.white);
g2d.drawString("Score: " + score, 0, 320);
g2d.drawString("Lives: " + lives, 80, 320);
}
public void checkCollisions()
{
Rectangle[] rect = new Rectangle[baddies.length];
for(int i = 0; i < baddies.length; i++)
{
Enemy e = (Enemy)baddies[i];
rect[i] = e.getBounds();
}
ArrayList<?> bullets = Player.getBullets();
for (int i = 0; i < bullets.size(); i++)
{
Bullet b = (Bullet) bullets.get(i);
Rectangle b1 = b.getBounds();
if (rect[i].intersects(b1) && baddies[i].isAlive())
{
score++;
baddies[i].isAlive = false;
baddies[i].isVisible = false;
bang.play();
}
Rectangle h = p.getBounds();
if (h.intersects(rect[i]))
{
if(baddies[i].isAlive() == true)
{
lives--;
if(lives < 0)
{
lost = true;
theme.stop();
System.exit(1);
}
}
}
}
}
private class ActionListener extends KeyAdapter
{
public void keyReleased(KeyEvent e)
{
p.keyReleased(e);
}
public void keyPressed(KeyEvent e)
{
p.keyPressed(e);
}
}
}
Enemy
package ShooterGame;
import java.awt.*;
import javax.swing.ImageIcon;
public class Enemy
{
int x, y;
Image img;
boolean isAlive = true;
boolean isVisible = true;
public Enemy(int startX, int startY, String location)
{
x = startX;
y = startY;
ImageIcon l = new ImageIcon(location);
img = l.getImage();
}
public Rectangle getBounds()
{
return new Rectangle(x, y, 60, 60);
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public boolean isAlive()
{
return isAlive;
}
public boolean isVisible()
{
return isVisible;
}
public Image getImg()
{
return img;
}
public void move(int dx)
{
x = x - dx;
}
}
Bullet
package ShooterGame;
import java.applet.Applet;
import java.awt.*;
import javax.swing.ImageIcon;
import java.applet.AudioClip;
public class Bullet
{
int x, y;
Image img;
boolean visible;
public Bullet(int startX, int startY)
{
x = startX;
y = startY;
ImageIcon newBullet = new ImageIcon("images/bullet.gif");
img = newBullet.getImage();
visible = true;
}
public Rectangle getBounds()
{
return new Rectangle(x, y, 9, 5);
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public Image getImg()
{
return img;
}
public boolean isVisible()
{
return visible;
}
public void move()
{
x = x + 2;
if(x > 700)
{
visible = false;
}
}
public void setVisible(boolean isVisible)
{
visible = isVisible;
}
}
Player
package ShooterGame;
import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.ImageIcon;
public class Player
{
int x, dx, y, dy, nx2, nx, edge, ceiling;
Image player;
ImageIcon ib = new ImageIcon("images/player1back.gif");
ImageIcon i = new ImageIcon("images/playerstill.gif");
ImageIcon f = new ImageIcon("images/playerforward.gif");
ImageIcon up = new ImageIcon("images/playerup.gif");
ImageIcon down = new ImageIcon("images/playerdown.gif");
public AudioClip laser;
static ArrayList<Bullet> bullets;
public Player()
{laser = Applet.newAudioClip(getClass().getResource("laser.wav"));
player = ib.getImage();
x = 75;
nx = 0;
nx2 = 685;
y = 172;
edge = 150;
ceiling = 0;
bullets = new ArrayList<Bullet>();
}
public static ArrayList<Bullet> getBullets()
{
return bullets;
}
public void fire()
{
Bullet z = new Bullet((edge + 60), (y+17));
bullets.add(z);
}
public Rectangle getBounds()
{
return new Rectangle(edge, y, 43, 39);
}
public void move()
{
y = y + dy;
if(y < ceiling)
{
y = ceiling;
}
if(y > 290)
{
y = 290;
}
if(dx != -1)
{
if(edge + dx <= 151)
{
edge = edge + dx;
}
else
{
x = x + dx;
nx2 = nx2 + dx;
nx = nx + dx;
}
}
else
{
if(edge + dx > 0)
{
edge = edge + dx;
}
}
}
public int getX()
{
return x;
}
public int getdx()
{
return dx;
}
public int getY()
{
return y;
}
public Image getImage()
{
return player;
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT)
{
dx = 2;
player = f.getImage();
}
if(key == KeyEvent.VK_UP)
{
dy = -1;
player = up.getImage();
}
if(key == KeyEvent.VK_DOWN)
{
dy = 1;
player = down.getImage();
}
if(key == KeyEvent.VK_SPACE)
{
fire();
laser.play();
}
}
public void keyReleased(KeyEvent e)
{
int key = e.getKeyCode();
if(key == KeyEvent.VK_RIGHT)
{
dx = 1;
player = ib.getImage();
}
if(key == KeyEvent.VK_UP)
{
dy = 0;
player = ib.getImage();
}
if(key == KeyEvent.VK_DOWN)
{
dy = 0;
player = ib.getImage();
}
}
}
Frame
package ShooterGame;
import javax.swing.*;
public class Frame
{
public AudioClip theme;
public Frame()
{
JFrame frame = new JFrame();
frame.add(new Board());
frame.setTitle("SideShooter");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700,365);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public static void main(String[] args)
{
new Frame();
}
}
Ok, so the problem is the line mentioned in the other answer, but I believe it is that all the enemies may not be initialised before it checks collisions. Because you are making 10000 of them to start with, I think your action performed method may be checking collisions before they have all be created.
One thing to try could be to bring down the amount of enemies you have and see if it still keeps happening, try 100 or 1000, but this still won't fix the issue.
You really want to be change your game to run in it's own loop though, at the moment you are only checking collisions when the player performs an action. so if the player stops moving, no collision detection...
I would suggest that you find a book called 'Killer Game Programming in Java', there are free ebook version, and just read the first 2 chapters about making a game loop. The book is a bit old, but the basics of the loop are very good.
This question here also contains a very simple loop, and some suggestions in the comments about how to make it better.
The error is on the line
rect[i] = e.getBounds();
Are you not initializing the bounds of your Enemy class correctly? Alternatively, the Enemy you pulled out of the array could be null.