Below are some of the classes I have written for a small space invaders game. It's not finished but it's at the bare bones stage. I am still learning how to properly use the Slick2D library. I know where there are some problems but that is due to my lack of full knowledge of how Slick2D works, so I had to think of a workaround for the time being.
I have only created this code so you can all check it out and tell me where I am going wrong and what I am doing right. I'd also like some feedback on the code in general, such as if it is clean, if it is organized, if the naming conventions for methods and variables helpful, and other things like that. I don't know if I am a good programmer or not so hopefully this may shine some light on the situation.
Entity class
package com.emeraldzonegames.jinvaders.entities;
import java.awt.Rectangle;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Image;
import org.newdawn.slick.Graphics;
public abstract class Entity
{
public Image entityImage;
public int x, y, width, height,speed;
public Rectangle entityRect;
/**
* Method that loads an image for each entity
* @param imageName
*/
public void loadImage(String imageName)
{
try
{
entityImage = new Image("Assets/Graphics/"+imageName+".png");
}
catch(Exception e)
{
e.printStackTrace();
}
}
//Getters and setters
public void setPosition(int x, int y)
{
this.x = x;
this.y = y;
}
public void setDimenseions(int width, int height)
{
this.width = width;
this.height = height;
}
public void setSpeed(int speed)
{
this.speed = speed;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public int getWidth()
{
return width;
}
public int getHeight()
{
return height;
}
public int getSpeed()
{
return speed;
}
public Image getImage()
{
return entityImage;
}
/**
* Creates a rectangle for the entity
*/
public void createRectangle()
{
entityRect = new Rectangle(getX(),getY(), getWidth(), getHeight());
}
/**
* Method to carry out logic if input is required
* @param gc
* @param deltaTime
*/
public void entityLogic(GameContainer gc,int deltaTime){}
/**
* Method to render objects to the screen
* @param g
*/
public void renderEntity(Graphics g){}
}
Player class.
package com.emeraldzonegames.jinvaders.entities;
import java.util.ArrayList;
import org.newdawn.slick.Input;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.GameContainer;
/**
*
* ClassName: Player.java
* -------------------------------------
* Description: The purpose of this class is to
* Define all of the operations that are carried
* out by the Player Object
*
*/
public class Player extends Entity
{
public ArrayList<Bullet> bulletList;
private boolean firing;
private final String ENTITY_ID = "ship";
public Player()
{
bulletList = new ArrayList<Bullet>();
this.setImage(ENTITY_ID);
this.setPosition(350,450);
this.setDimenseions(100, 100);
this.setSpeed(5);
this.createRectangle();
}
@Override
public void entityLogic(GameContainer gc, int deltaTime)
{
Input input = gc.getInput();
if(input.isKeyDown(Input.KEY_A))
{
this.x -= speed;
this.entityRect.x -= speed;
}
if(input.isKeyDown(Input.KEY_D))
{
this.x += speed;
this.entityRect.x -= speed;
}
if(input.isKeyDown(Input.KEY_W))
{
this.y -= speed;
this.entityRect.y -= speed;
}
if(input.isKeyDown(Input.KEY_S))
{
this.y += speed;
this.entityRect.y += speed;
}
if(input.isKeyPressed(Input.KEY_SPACE))
{
firing = true;
addToList();
}
checkBounds();
fireBullet();
destroyBullets();
}
@Override
public void renderEntity(Graphics g)
{
g.drawImage(this.getImage(), this.getX(), this.getY());
if(firing)
{
for(Bullet b : bulletList)
{
b.renderEntity(g);
}
}
if(com.emeraldzonegames.jinvaders.main.JInvadersGame.debugModeEnabled)
{
g.drawRect(x, y, width, height);
}
}
/**
* Populates the arrayList with instances of the bullet object
*/
private void addToList()
{
Bullet bullet = new Bullet(this.x+40,this.y);
bulletList.add(bullet);
}
/**
* Moves the bullet when player is firing
*/
private void fireBullet()
{
if(firing)
{
for(Bullet b:bulletList)
{
b.moveBullet();
}
}
}
/**
* Destroys intances of the bullet once the bullet goes out of it's bounds
*/
private void destroyBullets()
{
for(int i = 0; i < bulletList.size(); ++i)
{
Bullet bullet = bulletList.get(i);
if(bullet.y <= 0)
{
bulletList.remove(i);
i--;
}
}
}
/**
* Method to check if the player is on the screen at all times
*/
private void checkBounds()
{
if( this.x > 720)
{
this.x = 720;
}
if( this.x < 0)
{
this.x = 0;
}
if( this.y > 450)
{
this.y = 450;
}
}
}
Bullet
package com.emeraldzonegames.jinvaders.entities;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
public class Bullet extends Entity
{
private final String ENTITY_ID = "bullet";
public Bullet(int x , int y)
{
this.x = x;
this.y = y;
this.loadImage(ENTITY_ID);
this.setDimenseions(15, 15);
this.createRectangle();
}
/**
* Moves the bullet up the Y-Axis
*/
public void moveBullet()
{
this.setSpeed(3);
this.y -= speed;
this.entityRect.y -= speed;
}
@Override
public void entityLogic(GameContainer gc, int deltaTime){}
@Override
public void renderEntity(Graphics g)
{
g.drawImage(this.getImage(), this.getX(), this.getY());
if(com.emeraldzonegames.jinvaders.main.JInvadersGame.debugModeEnabled)
{
g.drawRect(x, y, width, height);
}
}
}
Enemy
package com.emeraldzonegames.jinvaders.entities;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
public class Enemy extends Entity
{
private final String ENTITY_ID = "testEnemy";
private final int CREATED = 1;
private final int HIT_LEFT_WALL = 2;
private final int HIT_RIGHT_WALL = 3;
public int currentState;
public Enemy(int x, int y)
{
this.x = x;
this.y = y;
this.speed = 3;
this.currentState = CREATED;
this.setDimenseions(40,35);
this.loadImage(ENTITY_ID);
this.createRectangle();
}
@Override
public void entityLogic(GameContainer gc, int deltaTime)
{
//TODO add enemy logic
/*if(this.x < 0)
{
currentState = HIT_LEFT_WALL;
moveDown();
}
if(this.x > 720)
{
currentState = HIT_RIGHT_WALL;
moveDown();
}
switch(currentState)
{
case 1: moveLeft();
break;
case 2: moveRight();
break;
case 3: moveLeft();
break;
}*/
}
/*private void moveLeft()
{
this.x -= speed;
this.entityRect.x -= speed;
}
private void moveRight()
{
this.x += speed;
this.entityRect.x += speed;
}
private void moveDown()
{
this.y = y+10;
this.entityRect.y = entityRect.y+10;
}*/
@Override
public void renderEntity(Graphics g)
{
g.drawImage(this.getImage(), x, y);
if(com.emeraldzonegames.jinvaders.main.JInvadersGame.debugModeEnabled)
{
g.drawRect(x, y, width, height);
}
}
}
Main Game Class
package com.emeraldzonegames.jinvaders.main;
import java.util.ArrayList;
import org.newdawn.slick.Input;
import org.newdawn.slick.Music;
import org.newdawn.slick.Image;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.AppGameContainer;
import com.emeraldzonegames.jinvaders.entities.Player;
import com.emeraldzonegames.jinvaders.entities.Enemy;
import com.emeraldzonegames.jinvaders.entities.Bullet;
/**
*
* ClassName: JInvadersGame
* -------------------------------------
* Description: The purpose of this class is to
* create all of the assets and display them on screen
* carry out logic if required
*
*/
public class JInvadersGame extends BasicGame
{
private Player player;
private ArrayList<Enemy> enemyList;
private Music backgroundSong;
private Image background;
public static boolean debugModeEnabled = false;
public JInvadersGame(String title)
{
super(title);
}
/**
* Slick2D Method initialise components
*/
@Override
public void init(GameContainer gc) throws SlickException
{
player = new Player();
enemyList = new ArrayList<Enemy>();
backgroundSong = new Music("Assets/Audio/DST-2ndBallad.ogg");
background = new Image("Assets/Graphics/background.jpg");
backgroundSong.loop();
//Creates the enemies
createEnemies(10,3);
}
/**
* Slick2D Method rendering
*/
@Override
public void render(GameContainer gc, Graphics g) throws SlickException
{
g.drawImage(background, 0, 0);
player.renderEntity(g);
for(Enemy e : enemyList)
{
e.renderEntity(g);
}
}
/**
* Slick2D Method game loop
*/
@Override
public void update(GameContainer gc, int deltaTime) throws SlickException
{
if(debugModeEnabled == false && gc.getInput().isKeyPressed(Input.KEY_GRAVE))
{
debugModeEnabled = true;
}
else if(debugModeEnabled == true && gc.getInput().isKeyPressed(Input.KEY_GRAVE))
{
debugModeEnabled = false;
}
player.entityLogic(gc,deltaTime);
for(Enemy e : enemyList)
{
e.entityLogic(gc, deltaTime);
}
checkCollisions();
}
/**
* Creates a grid of enemies
*/
private void createEnemies(int row, int col)
{
for(int i = 1; i <= row; i++)
{
for(int j = 1; j <= col; j++)
{
Enemy enemy = new Enemy(i*50, j*50);
enemyList.add(enemy);
}
}
System.out.println(enemyList.size());
}
/**
* Check for collisions
*/
private void checkCollisions()
{
//Get the rectangles from each bullet and enemy from the respective ArralyLists
for(int i = 0; i < player.bulletList.size(); ++i)
{
Bullet b = player.bulletList.get(i);
for(int j = 0; j < enemyList.size(); ++j)
{
Enemy e = enemyList.get(j);
//If a bullets rectangle connects with an enemies remove both objects from their lists
if(b.entityRect.intersects(e.entityRect))
{
player.bulletList.remove(i);
enemyList.remove(j);
i--;
j--;
}
}
}
}
public static void main(String[] args)
{
try
{
AppGameContainer jinvaders = new AppGameContainer(new JInvadersGame("EmeraldZoneGames - JInvaders"));
jinvaders.setDisplayMode(800, 600, false);
jinvaders.setVSync(true);
jinvaders.setShowFPS(false);
jinvaders.start();
}
catch(SlickException se)
{
se.printStackTrace();
}
}
}