NullPointerException Java Maze - java

basically i have been following a Java tutorial to make a basic maze game where i generate a random maze which is saved to a file then i print it out using Jpanel however i keep getting this error when i compile.
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at maze.Map.getMap(Map.java:43)
at maze.Board.paint(Board.java:40)
However i am not sure why, i believe it is something to do with my Y integer but if i set it to 0 it causes my program to print out wrong(just prints the same column instead of changing rows).
I need the Y value in Map.java:43 to increase like my x value does however it provides me with the Exception error.
Code:
Map Class
package maze;
import java.awt.Image;
import java.io.File;
import java.util.*;
import javax.swing.ImageIcon;
public class Map {
private Scanner m;
private Image wall, ground;
//number of columns
private String Map[] = new String[20];
public Map() {
//sets ground to a texture
ImageIcon img = new ImageIcon("C:\\MazeGraphics\\ground.png");
ground = img.getImage();
//sets wall texture
img = new ImageIcon("C:\\MazeGraphics\\wall.png");
wall = img.getImage();
openFile();
readFile();
closeFile();
}
public Image getGround() {
// gives grass texture for screen
return ground;
}
public Image getWall() {
// gives wall texture for screen
return wall;
}
public String getMap(int x, int y) {
//compares string to find graphic to use
String index= Map[y].substring(x, x+1);
return index;
}
public void openFile() {
try {
m = new Scanner(new File("C:\\MazeGraphics\\Maze.txt"));
} catch (Exception e) {
System.out.println("Error Loading Map");
}
}
public void readFile() {
for(int i = 0; i < 20; i++)
{
while(m.hasNext()){
Map[i] = m.next();
}
}
}
public void closeFile() {
m.close();
}
}
Board Class:
package maze;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Board extends JPanel implements ActionListener {
private Timer timer;
private Map m;
private Player p;
public Board()
{
MazeGeneration maz=new MazeGeneration();
//runs Map class
m = new Map();
p = new Player();
//listens for key presses
addKeyListener(new Al());
//knows to add key listener to the frame
setFocusable(true);
timer = new Timer(25, this);
timer.start();
}
public void actionPerformed(ActionEvent e) {
repaint();
}
public void paint(Graphics g) {
super.paint(g);
//paints the board row by row
for (int y = 0; y < 20; y++)
{
for (int x = 0; x < 20; x++)
{
//places graphic depending on the letter.
if (m.getMap(x, y).equals("g"))
{
g.drawImage(m.getGround(), y * 32, x * 32, null);
}
if (m.getMap(x, y).equals("w"))
{
g.drawImage(m.getWall(), y * 32,x * 32, null);
}
}
}
g.drawImage(p.getPlayer(), p.gettileX() * 32, p.gettileY() * 32, null);
}
public class Al extends KeyAdapter {
//moving the player
public void keyPressed(KeyEvent e, char maz[][], int r, int c) {
int keycode = e.getKeyCode();
if (keycode == KeyEvent.VK_W) {
//if not a wall can move
if (!m.getMap(p.gettileX(), p.gettileY() - 1).equals("w")) {
p.move(0, -1);
}
}
if (keycode == KeyEvent.VK_S) {
if (!m.getMap(p.gettileX(), p.gettileY() + 1).equals("w")) {
p.move(0, 1);
}
}
if (keycode == KeyEvent.VK_A) {
if (!m.getMap(p.gettileX() - 1, p.gettileY()).equals("w")) {
p.move(-1, 0);
}
}
if (keycode == KeyEvent.VK_D) {
if (!m.getMap(p.gettileX() + 1, p.gettileY() ).equals("w")) {
p.move(1, 0);
}
}
}
}
}

The issue is in this code: In your readFile() method, your issue arises during reading your file:
for(int i = 0; i < 20; i++)
{
while(m.hasNext()){
Map[i] = m.next();
}
}
You are assigning the value only to the 0'th index. To explain, for the first for loop, the index i is at zero. The inner loop "iterates" through the Scanner m until there is no element next. Therefore, Map[0] contains the last element on the file.
Your solution is as follows:
int i = 0;
while (m.hasNext()) {
Map[i++] = m.next();
}
I hope this helps.

Related

Accessing An Array throughout a method

I am writing a video game in Java (a horrible idea, yes I know). But I have run into a massive roadblock. I have written code that accesses a text document to output a 'dungeon' through the use of 1s and 0s. This is read into an multidimensional Array [imageArray] which then places my "wall' images. This works like a charm. What I am now trying to do is create a second array that can be accessed outside of the try/catch brackets.
My problem is I have tried several different ways of accessing a secondary array, and I just need help.
Much appreciated.
This is the Code.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.io.*;
import java.util.Scanner;
public class main extends JPanel implements KeyListener, ActionListener
{
Timer t = new Timer(8, this);
int xCoord, yCoord;
int x=1;
int y=1;
int d,v;
private Image image1, image2, image3, image4;
boolean pressed;
Random ran = new Random();
int cubeDimension = 40;
int set = cubeDimension + 2;
public main(){
xCoord = 0;
yCoord = 0;
t.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.black);
g.fillRect(0,0, 1000,1000);
g.setColor(Color.white);
for(int i = 0; i < 795; i += set){
for(int e = 0; e < 595; e += set){
g.fillRect(i, e, cubeDimension, cubeDimension);
}
}
//random code (ran.nextInt(9)+1)
//ImageIcon m1 = new ImageIcon("monster1.jpg");
//image2=m1.getImage();
ImageIcon w = new ImageIcon("wall.jpg");
image3 = w.getImage();
ImageIcon j = new ImageIcon("Hero.jpg");
image1 = j.getImage();
try{
Scanner file = new Scanner(new File("room.dat"));
int cnt = file.nextInt();
int cnt2 =file.nextInt();
int[][] imageArray = new int[cnt][cnt2];
for(int i=0;i<cnt;i++)
{
yCoord=i;
for(int c=0;c<cnt2;c++)
{
xCoord=c;
int n = file.nextInt();
imageArray[i][c] = n;
mapArray[xCoord][yCoord]=n;
if (n==1)
{
g.drawImage(image3,c*set,i*set,null);
}
if (n==2)
{
g.drawImage(image1,c*set*x+5,i*set*y,null);
}
}
}
}
catch(FileNotFoundException e){
System.out.println("Error");
}
}
//border code
public void keyReleased(KeyEvent e)
{
int code = e.getKeyCode();
if(code==KeyEvent.VK_NUMPAD8)
if(y>=0)
up();
if(code==KeyEvent.VK_NUMPAD7)
if(y>=0&&x>=0)
upleft();
if(code==KeyEvent.VK_NUMPAD2)
if(y<=14)
down();
if(code==KeyEvent.VK_NUMPAD1)
if(y<=14&&x>0)
downleft();
if(code==KeyEvent.VK_NUMPAD6)
if(x<=19)
right();
if(code==KeyEvent.VK_NUMPAD3)
if(x<=19&&y<=14)
downright();
if(code==KeyEvent.VK_NUMPAD4)
if(x>=0)
left();
if(code==KeyEvent.VK_NUMPAD9)
if(x<=19&&y>0)
upright();
}
public void actionPerformed(ActionEvent e){
repaint();
}
public void up(){ y= y-1 ;}
public void upleft(){y= y-1;x= x-1;}
public void down(){ y= y+1;}
public void downleft(){ y= y+1; x= x-1;}
public void left(){ x = x-1;}
public void upright(){x = x+1;y= y-1;}
public void right(){ x = x+1;}
public void downright(){y= y+1;x = x+1;}
public void keyTyped(KeyEvent e){}
public void keyPressed(KeyEvent e){}
}
My problem is accessing a secondary array outside of the try/catch brackets.
Move imageArray before try block.
int[][] imageArray = null;
try{
Scanner file = new Scanner(new File("room.dat"));
int cnt = file.nextInt();
int cnt2 =file.nextInt();
imageArray = new int[cnt][cnt2];
...
}catch(FileNotFoundException e){
System.out.println("Error");
}

Menu in a simple java game [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I created a GUI named Menu class for my Start, Help and Exit button. my problem is my game won't start, it hangs everytime I press the Start button. Can someone check my error and explain it to me because its my case study at school.
package spaceSip;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
public class Menu extends JFrame implements ActionListener
{
private JLabel titleL;
private JButton startB, helpB, exitB;
static JFrame frame1 = new JFrame();
public Menu()
{
frame1.setSize(500,250);
Container mainP = frame1.getContentPane();
mainP.setLayout(null);
titleL = new JLabel("WELCOME");
startB = new JButton("Start");
helpB = new JButton("Help");
exitB = new JButton("Exit");
mainP.add(titleL);
titleL.setFont(new Font("Chiller",Font.BOLD,50));
titleL.setBounds(100, 30, 200, 50);
mainP.add(startB);
startB.setMnemonic(KeyEvent.VK_S);
startB.setBounds(200, 80, 100, 20);
mainP.add(helpB);
helpB.setMnemonic(KeyEvent.VK_H);
helpB.setBounds(200, 100, 100, 20);
mainP.add(exitB);
exitB.setMnemonic(KeyEvent.VK_E);
exitB.setBounds(200, 120, 100, 20);
startB.addActionListener(this);
helpB.addActionListener(this);
exitB.addActionListener(this);
frame1.setVisible(true);
frame1.setResizable(false);
}
public void actionPerformed(ActionEvent e)
{
String key = e.getActionCommand();
if(key == "Start")
{
frame1.dispose();
new SpaceShipMain();
}
else if(key == "Help")
{
}
else
System.exit(0);
}
public static void main(String[]args)
{
new Menu();
}
}
package spaceSip;
import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class SpaceShipMain implements MouseListener
{
private JFrame background;
private SpaceShipPanel back;
public static boolean paused;
public static boolean crashed;
public static boolean started;
public static boolean playedOnce;
public boolean goingUp;
private double upCount;
public static int distance;
public static int maxDistance;
public final int XPOS;
public final int NUMRECS;
public final int RECHEIGHT;
public final int RECWIDTH;
private int moveIncrement;
private int numSmoke;
private ArrayList<SpaceShipImage> toprecs;
private ArrayList<SpaceShipImage> bottomrecs;
private ArrayList<SpaceShipImage> middlerecs;
private ArrayList<SpaceShipImage> smoke;
private SpaceShipImage helicopter;
public SpaceShipMain()
{
NUMRECS = 100;
RECHEIGHT = 70;
RECWIDTH = 30;
XPOS = 200;
playedOnce = false;
maxDistance = 0;
load(new File("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/Best.txt"));
initiate();
}
public void load(File file)
{
try
{
Scanner reader = new Scanner(file);
while(reader.hasNext())
{
int value = reader.nextInt();
if(value > maxDistance)
maxDistance = value;
}
}
catch(IOException i )
{
System.out.println("Error. "+i);
}
}
public void save()
{
FileWriter out;
try
{
out = new FileWriter("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/Best.txt");
out.write("" + maxDistance);
out.close();
}
catch(IOException i)
{
System.out.println("Error: "+i.getMessage());
}
}
public void initiate()
{
if(!playedOnce)
{
background = new JFrame("Space Ship Game");
background.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //closes the program when the window is closed
background.setResizable(false); //don't allow the user to resize the window
background.setSize(new Dimension(800,500));
background.setVisible(true);
back = new SpaceShipPanel("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/starfield.jpg");
background.add(back);
back.addMouseListener(this);
}
playedOnce = true;
goingUp = false;
paused = false;
crashed = false;
started = false;
distance = 0;
upCount = 0;
moveIncrement = 2;
numSmoke = 15;
toprecs = new ArrayList<SpaceShipImage>();
middlerecs = new ArrayList<SpaceShipImage>();
bottomrecs = new ArrayList<SpaceShipImage>();
smoke = new ArrayList<SpaceShipImage>();
helicopter = new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rocketship.GIF",XPOS,200);
for(int x = 0; x < NUMRECS; x++)
toprecs.add(new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rec2.JPG",RECWIDTH*x,5));
for(int x = 0; x < NUMRECS; x++)
bottomrecs.add(new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rec2.JPG",RECWIDTH*x,410));
middlerecs.add(new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid2.jpg",1392,randomMidHeight()));
middlerecs.add(new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid2.jpg",1972,randomMidHeight()));
drawRectangles();
}
public void drawRectangles()
{
long last = System.currentTimeMillis();
long lastCopter = System.currentTimeMillis();
long lastSmoke = System.currentTimeMillis();
long lastSound = System.currentTimeMillis();
int firstUpdates = 0;
double lastDistance = (double)System.currentTimeMillis();
while(true)
{
if(!paused && !crashed && started && (double)System.currentTimeMillis() - (double)(2900/40) > lastDistance)
{
lastDistance = System.currentTimeMillis();
distance++;
}
if(!paused && !crashed && started && System.currentTimeMillis() - 10 > lastCopter)
{
lastCopter = System.currentTimeMillis();
updateCopter();
updateMiddle();
}
if(!paused && !crashed && started && System.currentTimeMillis() - 100 > last)
{
last = System.currentTimeMillis();
updateRecs();
}
if(!paused && !crashed && started && System.currentTimeMillis() - 75 > lastSmoke)
{
lastSmoke = System.currentTimeMillis();
if (firstUpdates < numSmoke)
{
firstUpdates++;
smoke.add(new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/smoke.GIF",187,helicopter.getY()));
for(int x = 0; x < firstUpdates; x++)
smoke.set(x,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/smoke.GIF",smoke.get(x).getX() - 12, smoke.get(x).getY()));
}
else
{
for(int x = 0; x < numSmoke - 1; x++)
smoke.get(x).setY(smoke.get(x+1).getY());
smoke.set(numSmoke - 1,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/smoke.GIF",187,helicopter.getY()));
}
}
back.updateImages(middlerecs,helicopter,smoke);
}
}
public void updateRecs()
{
for(int x = 0; x < (NUMRECS - 1); x++) //move all but the last rectangle 1 spot to the left
{
toprecs.set(x,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rec2.JPG",RECWIDTH*x,toprecs.get(x+1).getY()));
bottomrecs.set(x,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rec2.JPG",RECWIDTH*x,bottomrecs.get(x+1).getY()));
}
}
public void randomDrop()
{
toprecs.get(26).setY(toprecs.get(26).getY() + (463 - bottomrecs.get(26).getY()));
bottomrecs.get(26).setY(463);
}
public int randomMidHeight()
{
int max = 10000;
int min = 0;
for(int x = 0; x < NUMRECS; x++)
{
if(toprecs.get(x).getY() > min)
min = (int)toprecs.get(x).getY();
if(bottomrecs.get(x).getY() < max)
max = (int)bottomrecs.get(x).getY();
}
min += RECHEIGHT;
max -= (RECHEIGHT + min);
return min + (int)(Math.random() * max);
}
//moves the randomly generated middle rectangles
public void updateMiddle()
{
if(middlerecs.get(0).getX() > -1 * RECWIDTH)
{
middlerecs.set(0,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid.gif",middlerecs.get(0).getX() - (RECWIDTH/5), middlerecs.get(0).getY()));
middlerecs.set(1,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid.gif",middlerecs.get(1).getX() - (RECWIDTH/5), middlerecs.get(1).getY()));
}
else
{
middlerecs.set(0,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid.gif",middlerecs.get(1).getX() - (RECWIDTH/5), middlerecs.get(1).getY()));
middlerecs.set(1,new SpaceShipImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/asteroid.gif",middlerecs.get(0).getX() + 580,randomMidHeight()));
}
}
public boolean shoot()
{
for(int x = 3; x <= 7; x++)
if(helicopter.getY() >= bottomrecs.get(x).getY())
return true;
for(int y = 3; y <= 7; y++)
if(helicopter.getY() <= toprecs.get(y).getY())
return true;
for(int z = 0; z <= 1; z++)
if(isInMidRange(z))
return true;
return false;
}
public boolean isInMidRange(int num)
{
Rectangle middlecheck = new Rectangle((int)middlerecs.get(num).getX(),(int)middlerecs.get(num).getY(),RECWIDTH,RECHEIGHT);
Rectangle coptercheck = new Rectangle((int)helicopter.getX(),(int)helicopter.getY(),70,48); //asteroid X and y bump
return middlecheck.intersects(coptercheck);
}
public void crash()
{
crashed = true;
if(distance > maxDistance)
{
maxDistance = distance;
save();
}
int reply = JOptionPane.showConfirmDialog(null, " RESTART ?", "GAME OVER", JOptionPane.YES_NO_OPTION);
if(reply == JOptionPane.YES_OPTION)
initiate();
else
System.exit(0);
initiate();
}
//moves the spaceship
public void updateCopter()
{
upCount += .10;
if(goingUp)
{
if(upCount < 3.5)
helicopter.setPosition(XPOS,(double)(helicopter.getY() - (.3 + upCount)));
else
helicopter.setPosition(XPOS,(double)(helicopter.getY() - (1.2 + upCount)));
helicopter.setImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rocketship.GIF");
}
else
{
if(upCount < 1)
helicopter.setPosition(XPOS,(double)(helicopter.getY() + upCount));
else
helicopter.setPosition(XPOS,(double)(helicopter.getY() + (1.2 + upCount)));
helicopter.setImage("C:\\Users/Travelmate/workspace/GAME/src/spaceSip/rocketship.GIF");
}
if(shoot())
crash();
}
//Called when the mouse exits the game window
public void mouseExited(MouseEvent e)
{
paused = true;
}
//Called when the mouse enters the game window
public void mouseEntered(MouseEvent e)
{
}
//Called when the mouse is released
public void mouseReleased(MouseEvent e)
{
goingUp = false;
upCount = -1;
if(paused)
paused = false;
}
//Called when the mouse is pressed
public void mousePressed(MouseEvent e)
{
if (!started)
started = true;
goingUp = true;
upCount = 0;
}
//Called when the mouse is released
public void mouseClicked(MouseEvent e)
{
}
}
package spaceSip;
import java.awt.Image;
import javax.swing.ImageIcon;
public class SpaceShipImage
{
private Image image; //The picture
private double x; //X position
private double y; //Y position
//Construct a new Moving Image with image, x position, and y position given
public SpaceShipImage(Image img, double xPos, double yPos)
{
image = img;
x = xPos;
y = yPos;
}
//Construct a new Moving Image with image (from file path), x position, and y position given
public SpaceShipImage(String path, double xPos, double yPos)
{
this(new ImageIcon(path).getImage(), xPos, yPos);
//easiest way to make an image from a file path in Swing
}
//They are set methods. I don't feel like commenting them.
public void setPosition(double xPos, double yPos)
{
x = xPos;
y = yPos;
}
public void setImage(String path)
{
image = new ImageIcon(path).getImage();
}
public void setY(double newY)
{
y = newY;
}
public void setX(double newX)
{
x = newX;
}
//Get methods which I'm also not commenting
public double getX()
{
return x;
}
public double getY()
{
return y;
}
public Image getImage()
{
return image;
}
}
package spaceSip;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
class SpaceShipPanel extends JPanel
{
private Image background;
private ArrayList<SpaceShipImage> middle;
private SpaceShipImage copter;
private ArrayList<SpaceShipImage> smoke;
//Constructs a new ImagePanel with the background image specified by the file path given
public SpaceShipPanel(String img)
{
this(new ImageIcon(img).getImage());
//The easiest way to make images from file paths in Swing
}
//Constructs a new ImagePanel with the background image given
public SpaceShipPanel(Image img)
{
background = img;
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
//Get the size of the image
//Thoroughly make the size of the panel equal to the size of the image
//(Various layout managers will try to mess with the size of things to fit everything)
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
middle = new ArrayList<SpaceShipImage>();
smoke = new ArrayList<SpaceShipImage>();
}
//This is called whenever the computer decides to repaint the window
//It's a method in JPanel that I've overwritten to paint the background and foreground images
public void paintComponent(Graphics g)
{
//Paint the background with its upper left corner at the upper left corner of the panel
g.drawImage(background, 0, 0, null);
//Paint each image in the foreground where it should go
for(SpaceShipImage img : middle)
g.drawImage(img.getImage(), (int)(img.getX()), (int)(img.getY()), null);
for(SpaceShipImage img : smoke)
g.drawImage(img.getImage(), (int)(img.getX()), (int)(img.getY()), null);
if(copter != null)
g.drawImage(copter.getImage(), (int)(copter.getX()), (int)(copter.getY()), null);
drawStrings(g);
}
public void drawStrings(Graphics g)
{
g.setColor(Color.WHITE);
g.setFont(new Font("Arial",Font.BOLD,20));
g.drawString("Distance: " + SpaceShipMain.distance,30,440);
g.setFont(new Font("Arial",Font.BOLD,20));
if (SpaceShipMain.distance > SpaceShipMain.maxDistance)
g.drawString("Best: " + SpaceShipMain.distance,650,440);
else
g.drawString("Best: " + SpaceShipMain.maxDistance,650,440);
if(SpaceShipMain.paused)
{
g.setFont(new Font("Chiller",Font.BOLD,72));
g.drawString("Paused",325,290);
g.setFont(new Font("Chiller",Font.BOLD,30));
g.drawString("Click to unpause.",320,340);
}
}
//Replaces the list of foreground images with the one given, and repaints the panel
public void updateImages(ArrayList<SpaceShipImage> newMiddle,SpaceShipImage newCopter,ArrayList<SpaceShipImage> newSmoke)
{
copter = newCopter;
middle = newMiddle;
smoke = newSmoke;
repaint(); //This repaints stuff... you don't need to know how it works
}
}
You compare Strings with equals(value equality) not with ==(reference equality). For more information read this previous question How do I compare strings in Java?
As #AndrewThompson always advice don't use NullLayout
Java GUIs might have to work on a number of platforms, on different
screen resolutions & using different PLAFs. As such they are not
conducive to exact placement of components. To organize the
components for a robust GUI, instead use layout managers, or
combinations of
them1, along
with layout padding & borders for white
space2.
As you say that your gui is blocked, that may be cause some of your execution code takes too more time and it's executed in the same thread as gui stuff (The Event Dispatch Thread). As you have a while(true) that's block the gui so use a SwingTimer for execute repeatidly task or if that code that takes long time execute it in a background thread using a Swing Worker. Here you have a complete example. When you perform custom painting you should override paintComponent and in first line you have to call super.paintComponent(..) to follow correct chaining. Read more in Painting in AWT-Swing.
Another error i see is that you are adding components after calling setVisible(true) without calling revalidate() repaint(). So i recommend to first add components to container then call setVisible(true) at final step.

how to create snake body using arraylist in snake game

Hi, I'm developing a snake game. To create the snake I'm using ArrayList. While moving the snake I'm getting the following error: "java.lang.IndexOutOfBoundsException: Index: 3, Size: 3". Below is my program. In Snake.update() method I have problem.
Game.java:
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class Game extends JFrame {
public Game(){
add(new GamePanel());
setTitle("Game Test3");
setVisible(true);
setAlwaysOnTop(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
public static void main(String[] args) {
new Game();
}
}
GamePanel.java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class GamePanel extends JPanel implements Runnable, KeyListener {
public static int width = 300;
public static int height = 400;
private Thread thread;
private Image image;
private Graphics2D g;
private Food food;
private Snake snake;
public GamePanel() {
setPreferredSize(new Dimension(width, height));
setFocusable(true);
}
public void addNotify() {
super.addNotify();
if (thread == null) {
thread = new Thread(this);
thread.start();
}
addKeyListener(this);
}
public void run() {
image = createImage(width, height);
g = (Graphics2D) image.getGraphics();
RenderingHints reneringHints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHints(reneringHints);
food = new Food();
snake = new Snake();
while (true) {
gameRender();
gameUpdate();
gameDraw();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void gameDraw() {
Graphics2D g2 = (Graphics2D) getGraphics();
g2.drawImage(image, 0, 0, this);
g2.dispose();
}
private void gameRender() {
g.setColor(Color.black);
g.fillRect(0, 0, width, height);
// food drawing
food.draw(g);
// snake drawing
snake.draw(g);
}
private void gameUpdate() {
food.update();
snake.update();
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
snake.setLeft(true);
}
if (key == KeyEvent.VK_RIGHT) {
snake.setRight(true);
}
if (key == KeyEvent.VK_UP) {
snake.setUp(true);
}
if (key == KeyEvent.VK_DOWN) {
snake.setDown(true);
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
snake.setLeft(false);
}
if (key == KeyEvent.VK_RIGHT) {
snake.setRight(false);
}
if (key == KeyEvent.VK_UP) {
snake.setUp(false);
}
if (key == KeyEvent.VK_DOWN) {
snake.setDown(false);
}
}
public void keyTyped(KeyEvent e) {
}
}
//snake body
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.ArrayList;
public class Snake {
private int x;
private int y;
private int r;
int body;
Rectangle rectangle;
ArrayList<Rectangle> rc = new ArrayList<Rectangle>();
private boolean left;
private boolean right;
private boolean up;
private boolean down;
public Snake() {
x = 150;
y = 150;
r = 4;
body = 3;
for (int i = 0; i < body; i++) {
rc.add(new Rectangle(x - i * r * 3, y, r * 3, r * 3));
}
}
public void draw(Graphics2D g) {
for (int i = 0; i < body; i++) {
if (i == 0) {
g.setColor(Color.red);
} else {
g.setColor(Color.green);
}
g.fillOval(rc.get(i).x, rc.get(i).y, rc.get(i).width,
rc.get(i).height);
}
}
public void update() {
for (int i = body; i > 0; i--) {
rc.set(i, rc.get(i - 1));
}
if (left) {
rc.get(0).x -= 1;
System.out.println("vbnv");
}
if (right) {
rc.get(0).x += 1;
}
if (up) {
rc.get(0).y -= 1;
}
if (down) {
rc.get(0).y += 1;
}
}
public void setLeft(boolean b) {
left = b;
}
public void setRight(boolean b) {
right = b;
}
public void setUp(boolean b) {
up = b;
}
public void setDown(boolean b) {
down = b;
}
}
Without reading the code I can tell that somewhere you are trying to get non-existent element. Read the message of exception, it tells you that your ArrayList consist of three elements (which means that the last element has index of 2) while you try to get the element with index of 3.
Update: yes, the problem is here:
for (int i = body; i > 0; i--) {
rc.set(i, rc.get(i - 1));
}
body equals to 3, and rc after the constructor invocation has the size of 3. set method replaces already existing element with the specified index (see the documentation), but element with index of 3 doesn't exist. That's the cause of an exception.
Your problem is in this loop:
for (int i = body; i > 0; i--) {
rc.set(i, rc.get(i - 1));
}
During the first iteration around this loop, you will be calling:
rc.set(3, <someValue>);
3 is not a valid index in a list of length 3. The largest valid index is 2.
for (int i = body; i > 0; i--)
In this for, i is assigned with the value of body(which is 3) and it looks like your ArrayList rc has only 3 elements in it. Therefore, when you try to access the index 3 using rc.set(3, something), its giving the IndexOutOfBoundsException.
Always remember, whether it is Arrays or ArrayList, the max possible index accessible in them is always array.length - 1 and ArrayList.size() - 1.

Java timer&paintcomponent issues

Hi I am trying to make a red box appear at the bottom of a JPanel .I wish for this box to move to one corner of the screen and stop and then start moving the other way,however i have been unable make the box stop the following is the code i have been working with
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;
public class JavaApplication13 extends JPanel {
public static void main(String[] args) {
JFrame rough = new JFrame("Panamr");
rough.setVisible(true);
rough.setLocation(1, 1);
rough.setSize(500, 500);
rough.setContentPane(mamals);
}
public static int iomega(int x, int y) {
if (y == 1) {
diget = -5;
time.stop();
}
if (y == 0) {
diget = 5;
}
return diget;
}
static JavaApplication13 mamals = new JavaApplication13();
JavaApplication13() {
setBackground(Color.red);
}
static int oy = 400;
static int ox = 200;
static int diget;
static Timer time = new Timer(100, new ActionListener() {
public int xy = 1;
#Override
public void actionPerformed(ActionEvent e) {
iomega(ox, xy);
if (ox == 500) {
xy = 1;
}
if (ox == 0) {
xy = 0;
}
ox = ox - iomega(ox, oy);
/*if(ox!=500){
ox=ox-diget;
if(ox==0){
diget=-5;}
else {
diget=5;
}
}*/
}
});
boolean test = true;
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.black);
g.fillRect(ox, oy, 60, 60);
time.start();
repaint();
}
}
your co-ordiantes for the frames/panels size is off, you should calculate this dynamically maybe, or have a final value. Next your xy=0 and xy=1 should be swapped like this:
if (ox == 400) {//this was a larger number then the panel/frame so it went offscreen
xy = 0;//swapped
}
if (ox == 0) {
xy = 1;//swapped
}

Collision detection using plain arrays and rectangles--java

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.

Categories