I wasn't sure if this should go in games development or here but it's java so I put it here. This is homework so please don't write my code for me. My assignment is to create a game. It has to have moving parts, keyboard controls, buttons, the works. I am recreating asteroids except the ship is going to be in a vein and it will be shooting viruses. I have most of it working the way I want it to. The viruses float around, the background shows up and sits there like it should, I have a bunch of classes. The problem I am having is that I can't get my ship to paint and if I can get it to paint (by just putting the image in the panel instead of the class which doesn't help) then it won't move. I am using a key listener for moving the ship and I want to use the spacebar to fire but that comes after if I can get it to paint. I don't know of any way to give you my images for testing. If you need them I could try and email them or something unless you know of a better way. If not just use random images. I used png's because of the transparency. Also I removed getters and setters to conserve space. Here is the code:
Game Class:
package virus_game;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*; // New library classes, Swing extends AWT
/**
* @author 24x24
*/
public class Game extends JFrame implements ActionListener, KeyListener {
// size of the window
private static final int WINDOW_WIDTH = 800;
private static final int WINDOW_HEIGHT = 600;
ArrayList balls;
private Ship ship;
private GamePanel gamePanel;
ArrayList<Integer> keys = new ArrayList<Integer>();
private int fireLimit = 0;
KeyEvent e;
/**
* Pause command used to control the speed of the virus animation.
* Currently pauses for 20 ms. Use smaller values for faster animation and
* vice versa.
*/
public static void pause() {
try {
Thread.sleep(20); // pause for 20 ms
} catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
/** Creates a new instance of Game */
public Game() {
super("Virus: Annihilation"); // set frame name
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//this.setSize(windowWidth, windowHeight);
this.setResizable(false);
this.setLocation(100, 100);
this.setVisible(true);
// this.addKeyListener(this);
this.createBufferStrategy(2);
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setLayout(new BorderLayout());
gamePanel = new GamePanel();
add(gamePanel);
center(this);
setVisible(true);
// This doesn't work yet
// JButton pauseGame = new JButton();
// pauseGame.setText("Pause");
// pauseGame.addActionListener(this);
// add(pauseTheGame, BorderLayout.SOUTH);
gamePanel.addViruses(); // calls user input
ship = new Ship();
// This is where the keys should be used
// int code = e.getKeyCode();
// if (code == 40) {
// ship.moveUp();
// }
// }
// if (code == 38) {
// ship.moveDown();
// }
// }
// if (code == 37) {
// ship.moveLeft();
// }
// if (code == 39) {
// ship.moveRight();
// }
// // Fires bullet (Hopefully)
// if (keys.contains(new Integer(32))) {
// if (fireLimit == 0) {
// ship.fire();
// fireLimit = 5;
// } else {
// fireLimit--;
// }
// This is theoretical and probably won't work
// // check if the ship goes through any walls, if so respawn it on the other side
// if (ship.getshipxCoord() > WINDOW_WIDTH + 20) {
// ship.set(20, ship.getshipxCoord());
// } else if (ship.getshipyCoord() < -20) {
// ship.set(WINDOW_WIDTH - 20, ship.getshipyCoord());
// }
// if (ship.getshipyCoord() > WINDOW_HEIGHT + 20) {
// ship.set(ship.getshipxCoord(), 20);
// } else if (ship.getshipyCoord() < 0) {
// ship.set(ship.getShipxCoord(), WINDOW_HEIGHT);
// }
// infinite animation loop, program halts when window is closed.
while (true) {
pause();
gamePanel.move();
gamePanel.repaint();
} // end while
} // end Game
/** Helper routine to center a frame on the screen (will cause problems if
frame is bigger than the screen!)
*/
public static void center(JFrame frame) {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
Point center = ge.getCenterPoint();
int w = frame.getWidth();
int h = frame.getHeight();
int x = center.x - w / 2, y = center.y - h / 2;
frame.setBounds(x, y, w, h);
frame.validate();
}
public static void main(String[] args) {
Game t = new Game();
}
/**
* This method creates a button at the bottom of the screen that adds more
* balls to the arrayList when pressed
* @param e
*/
@Override
public void actionPerformed(ActionEvent e) {
gamePanel.moreViruses();
}
@Override
public void keyPressed(KeyEvent e) {
if (!keys.contains(new Integer(e.getKeyCode()))) {
keys.add(new Integer(e.getKeyCode()));
}
}
@Override
public void keyReleased(KeyEvent e) {
keys.remove(new Integer(e.getKeyCode()));
}
@Override
public void keyTyped(KeyEvent e) {
// not used
}
} // end method Main
GamePanel Class:
package virus_game;
import java.awt.*;
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
/**
* @author 24x24
*/
/**
* A panel containing viruses. This panel may be placed in a JFrame.
*/
public class GamePanel extends JPanel {
ArrayList viruses = new ArrayList();
Viruses virus;
Viruses r;
Image background = new ImageIcon("images/blood.jpg").getImage();
// Image ship = new ImageIcon("images/ship.png").getImage();
Ship ship;
/** Creates a new instance of GamePanel */
public GamePanel() {
super();
viruses = new ArrayList();
}
/**
* Adds a new virus to viruses. Also prints the size of the array to the console
* as a check
*/
public void moreViruses() {
Viruses virus = new Viruses();
viruses.add(virus);
System.out.println(viruses.size()); // A check to make sure viruses were added
}
/**
* This method asks the user how many viruses to start with and adds that
* number of viruses to the array list
* @return viruses
*/
public ArrayList addViruses() {
String stringVirus = JOptionPane.showInputDialog("How many viruses would you like?");
int numViruses = Integer.parseInt(stringVirus); // Turns string into int
for (int i = 0; i < numViruses; i++) {
Viruses virus = new Viruses();
viruses.add(virus);
System.out.println(viruses.size()); // A check to make sure viruses were added
}
return viruses;
} // End of addViruses
/**
Paints the viruses at their current positions within the panel.
*/
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g.drawImage(background, 0, 0, this);
// g.drawImage(ship, WIDTH, HEIGHT, this); // only way ship appears in panel but wrong
// ship.paintComponent(g); // gives error:
// Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
// at virus_game.GamePanel.paintComponent(GamePanel.java:131)
// at javax.swing.JComponent.paint(JComponent.java:1029)
// just keeps going
for (int i = 0; i < viruses.size(); i++) {
((Viruses) viruses.get(i)).paintComponent(g);
}
} // end method paintComponent
/**
Computes the next position for the viruses and updates their positions.
*/
public void move() {
// Move Viruses
// If virus is approaching a wall, reverse direction
for (Object b : viruses) {
((Viruses) b).move(getWidth(), getHeight());
}
// I used the same move method that I used for virus and called it here
// It didn't work so I removed it. It was just for testing purposes
//ship.move(WIDTH, HEIGHT); // makes panel white and gives NullPointer errors
} // end method move
} // End of GamePanel
Virus Class:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package virus_game;
import java.awt.*;
import javax.swing.*;
import java.util.*;
/**
*
* @author 24x24
*/
public class Viruses {
int virusxCoord;
int virusyCoord;
int virusHeight;
int virusWidth;
int virusRise;
int virusRun;
GamePanel gamePanel;
double size;
ArrayList viruses;
// Bigger picture for bigVirus, etc
Image bigVirus = new ImageIcon("images/bigVirus.png").getImage();
Image medVirus = new ImageIcon("images/medVirus.png").getImage();
Image smallVirus = new ImageIcon("images/smallVirus.png").getImage();
Image virusSize = null;
/** Creates a new instance of GamePanel */
public Viruses() {
int randVirus = (int) ((Math.random()*3)+1);
System.out.println("Random " + randVirus);
// Initialize Viruses with random values
virusxCoord = (int) (Math.random() * (50));
virusyCoord = (int) (Math.random() * (50));
virusRise = (int) (Math.random() * (5));
virusRun = (int) (Math.random() * (5));
switch (randVirus){
case 1: {
virusHeight = bigVirus.getHeight(gamePanel);//(int) (10 + (int) (Math.random() * ((20 - 10) + 1)));
virusWidth = bigVirus.getWidth(gamePanel);}//(int) (10 + (int) (Math.random() * ((20 - 10) + 1)));
virusSize = bigVirus;
break;
case 2:
{
virusHeight = medVirus.getHeight(gamePanel);//(int) (10 + (int) (Math.random() * ((20 - 10) + 1)));
virusWidth = medVirus.getWidth(gamePanel);//(int) (10 + (int) (Math.random() * ((20 - 10) + 1)));
virusSize = medVirus;
}break;
case 3:
{
virusHeight = smallVirus.getHeight(gamePanel);//(int) (10 + (int) (Math.random() * ((20 - 10) + 1)));
virusWidth = smallVirus.getWidth(gamePanel);//(int) (10 + (int) (Math.random() * ((20 - 10) + 1)));
virusSize = smallVirus;
}
}
size = virusHeight + virusWidth; // Used for comparison
}
/**
Paints the viruses at their current positions within the panel.
*/
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// Paint Viruses
g.drawImage(virusSize, virusxCoord, virusyCoord, gamePanel);
}
/**
* This method moves the viruses
* @param pWidth
* @param pHeight
*/
public void move(int pWidth, int pHeight) {
// Move Viruses
// If ball is approaching a wall, reverse direction
if (virusxCoord < (0 - virusRun) || virusxCoord > (pWidth - virusWidth)) {
virusRun = -virusRun;
}
if (virusyCoord < (0 - virusRise) || virusyCoord > (pHeight - virusHeight)) {
virusRise = -virusRise;
}
// "Move" ball according to values in rise and run
virusxCoord += virusRun;
virusyCoord += virusRise;
}
// Getters and setters
} // end of Viruses class
Ship class:
package virus_game;
import java.awt.*;
import javax.swing.*;
import java.util.*;
/**
*
* @author 24x24
*/
public class Ship {
int shipxCoord;
int shipyCoord;
int shipHeight;
int shipWidth;
int shipRise;
int shipRun;
GamePanel ballPanel;
double size;
Image ship = new ImageIcon("images/ship.png").getImage();
/** Creates a new instance of GamePanel */
public Ship() {
// Initialize Ship with random values
shipxCoord = (int) 50;
shipyCoord = (int) 50;
shipRise = (int) (Math.random() * (5));
shipRun = (int) (Math.random() * (5));
size = shipHeight + shipWidth; // Used for comparison
}
/**
Paints the balls at their current positions within the panel.
*/
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// Paint Ball
//g.setColor(shipColor);
//g.setColor(Color.white);
//g.fillOval(ballxCoord, ballyCoord, ballWidth, ballHeight);
g.drawImage(ship, shipxCoord, shipyCoord, ballPanel);
}
public void moveLeft() {
shipxCoord -=5;
}
public void moveRight() {
shipxCoord +=5;
}
public void moveUp() {
shipRise +=5;
shipRun +=5;
}
public void moveDown() {
shipRise -=5;
shipRun -=5;
}
// getters and setters
} // end of Ship class
Thanks for any help you can give.