So I got the bullet class:
import java.awt.*;
public class Bullet extends GameObject
{
private Player player;
private int deltaX;
public Bullet(final Player player, final int deltaX, final int xPos, final int yPos, final int width, final int height, final String img) {
this.deltaX = deltaX;
this.player = player;
this.xPos = xPos;
this.yPos = yPos;
this.height = height;
this.width = width;
this.rect = new Rectangle(xPos, yPos, width, height);
this.img = getImage(img);
}
#Override
public void draw(Graphics g)
{
g.drawImage(img, xPos, yPos, width, height, null);
}
#Override
void update(final Shooter shooter, final int id)
{
if(rect.intersects(player.rect))
{
shooter.bullets.remove(this);
if(!(shooter.player1.getHull() == 0))
{
player.setHealth(player.getHealth() - 1);
if(!(getStamina() < 1))
if(shooter.player1.getStamina() > 10)
shooter.player1.setStamina(shooter.player1.getStamina() - 10);
else
shooter.player1.setStamina(shooter.player1.getStamina() - 1);
else
shooter.player1.setStamina(shooter.player1.getStamina() - 0);
}
else
{
player.setHealth(player.getHealth() - 2);
}
if(!(player.getHull() == 0))
player.setHull(player.getHull() - 2);
else
player.setHull(player.getHull() - 0);
}
else if (yPos < -100 || yPos > 2000)
{
shooter.bullets.remove(this);
}
else
{
if(deltaX == 1)
{
yPos++;
rect.y++;
}
else
{
yPos--;
rect.y--;
yPos--;
rect.y--;
}
}
}
public void setPlayer(Player player) {
this.player = player;
}
public Player getPlayer()
{
return player;
}
#Override
Image getImage(String img) {
return Toolkit.getDefaultToolkit().getImage(img);
}
public int getDeltaX() {
return deltaX;
}
public void setDeltaX(int deltaX) {
this.deltaX = deltaX;
}
}
And this is my Meteor class:
import java.awt.*;
public class Meteor extends GameObject
{
private Player player;
private int deltaX;
public Meteor(final Player player, final int deltaX, final int xPos, final int yPos, final int width, final int height, final String img) {
this.deltaX = deltaX;
this.player = player;
this.xPos = xPos;
this.yPos = yPos;
this.height = height;
this.width = width;
this.rect = new Rectangle(xPos, yPos, width, height);
this.img = getImage(img);
}
#Override
public void draw(Graphics g)
{
g.drawImage(img, xPos, yPos, width, height, null);
}
#Override
void update(final Shooter shooter, final int id)
{
if (yPos < -100 || yPos > 2000)
{
shooter.meteors.remove(this);
}
else
{
if(deltaX == 1)
{
yPos++;
rect.y++;
}
else
{
yPos++;
rect.y++;
}
}
if(rect.intersects(shooter.player1.rect))
{
System.out.println("Collision");
shooter.meteors.remove(this);
shooter.player1.setHealth(shooter.player1.getHealth() - 100);
}
}
public void setPlayer(Player player) {
this.player = player;
}
public Player getPlayer()
{
return player;
}
#Override
Image getImage(String img) {
return Toolkit.getDefaultToolkit().getImage(img);
}
public int getDeltaX() {
return deltaX;
}
public void setDeltaX(int deltaX) {
this.deltaX = deltaX;
}
}
Now in the Meteor class i want to use this:
if(bullet.rect.intersect(shooter.player1.rect)
{..}
But this is not working because I cannot reference from it the bullet class. Is there any way to make it working?
This is the GameObject class
import java.awt.*;
public abstract class GameObject
{
protected Rectangle rect;
protected int xPos;
protected int yPos;
protected int height;
protected int width;
protected Image img;
protected int health;
protected int stamina;
protected int hull;
abstract void draw(Graphics g);
abstract void update(final Shooter shooter, final int id);
abstract Image getImage(String img);
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getStamina() {
return stamina;
}
public void setStamina(int stamina) {
this.stamina = stamina;
}
public Rectangle getRect() {
return rect;
}
public void setRect(Rectangle rect) {
this.rect = rect;
}
public int getHull() {
return hull;
}
public void setHull(int hull) {
this.hull = hull;
}
public int getxPos() {
return xPos;
}
public void setxPos(int xPos) {
this.xPos = xPos;
}
public int getyPos() {
return yPos;
}
public void setyPos(int yPos) {
this.yPos = yPos;
}
public Image getImg() {
return img;
}
public void setImg(Image img) {
this.img = img;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
}
Rect seems to be a protected attribute of the GameObject class.
You can add a public getter in your Bullet class.
public Rectangle getRect() {
return rect;
}
and then call it:
if(bullet.getRect().intersect(shooter.player1.rect))
The quick fix is
bullet.getRect().intersect(shooter.getPlayer().getRect())
A longer answer is
You need to give some thought to how your classes interact with each other. A book I would recommend is called "Head First Design Patterns."
One example is that you could simplify your code with a delegate method on the GameObject class. Your bullets, shooters, and meteors probably don't need to know or care whether the collision logic is implemented using Rectangle. Additionally, you might need to change your collision logic.
Sample method on GameObject
public boolean intersect (GameObject anotherObject) {
return this.rect.intersect(anotherObject.rect);
}
Then your code would be
bullet.intersect(shooter.getPlayer())
First of all you need a reference to Bullet within Meteor. For instance create a property
private Bullet bullet;// in this moment reference is not set up (it means bullet == null)
and set it by a defined by yourself setter method or pass a reference as a constructor parameter (depends on what are objects relations and your design).
Rectangle property of Bullet object should be defined as private/ protected and inside Meteor fetched by getter (because of encapsulation good pattern).
So it means
Rectangle rectangle = bullet.getRectangle();
where getRectangle() is a defined, by you, getter for rect property.
Additionally I advice you to read about encapsulation.
At the beginning take a look here
http://docs.oracle.com/javase/tutorial/java/javaOO/variables.html
http://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html
Related
The Program is simple enough. I'm trying to get 3-10 random looking faces to print on a panel in a frame in Java. The problem is the faces won't print on the panel. I'm pretty new to this so I'm not sure what I've mucked up, and I've been trying to find a solution to my problem for a while. Any help?
//Leonard
//Random Face Drawer(3-10)
//Last Modified: 10/6/18
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Random;
//Main Class
public class FaceDraw {
public static void main(String[] args) {
int width = 900;
int height = 600;
Random rand = new Random();
ArrayList<Face> myFaceList = new ArrayList<Face>();
for( int i = 1; i < (rand.nextInt(8)+3); i ++) {
myFaceList.add(new Face(rand.nextInt(width-50)+50,rand.nextInt(height-50)+50,rand.nextInt(101),rand.nextInt(101)));
System.out.print(myFaceList);
}
FaceFrame myFaceFrame = new FaceFrame(myFaceList, width, height);
myFaceFrame.setVisible(true);
}
}
class OvalDraw extends Oval{
public OvalDraw () {
super(0,0,0,0);
}
public OvalDraw (int positionXIn, int positionYIn, int widthIn, int heightIn) {
super(positionXIn, positionYIn, widthIn, heightIn);
}
public void paintComponent(Graphics g) {
g.drawOval(getPositionX(),getPositionY(),getWidth(),getHeight());
System.out.format("OvalDraw.paintComponent(x = %d, y = %d, w = %d, h = %d)", getPositionX(),getPositionY(),getWidth(),getHeight());
}
}
//Face Class, extends from OvalDraw makes the face
class Face extends OvalDraw {
private OvalDraw eye1;
private OvalDraw eye2;
private Random smile;
private int smileStatus;
public Face () {
super(0, 0, 0, 0);
eye1 = new OvalDraw(0,0,0,0);
eye2 = new OvalDraw(0,0,0,0);
smileStatus = smile.nextInt(2);
}
public Face (int positionXIn, int positionYIn, int widthIn, int heightIn) {
super(positionXIn, positionYIn, widthIn, heightIn);
// variables to set my eyes to be the same size but in two different spots on the same y axis
int eyeHeight = heightIn/12;
int eyeWidth = widthIn/10;
int eye1PositionX = positionXIn + positionXIn/3;
int eyePositionY = positionYIn + positionYIn/12;
int eye2PositionX = eye1PositionX + (positionXIn/3)*2;
eye1 = new OvalDraw(eye1PositionX,eyePositionY,eyeWidth,eyeHeight);
eye2 = new OvalDraw(eye2PositionX,eyePositionY,eyeWidth,eyeHeight);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
eye1.paintComponent(g);
eye2.paintComponent(g);
if(smileStatus == 0) {
g.drawArc(getPositionX(), getPositionY() + getHeight()/2, getWidth(), getHeight(), 45, 90);
}else if(smileStatus == 1){
g.drawArc(getPositionX(), getPositionY() + getHeight()/2, getWidth(), getHeight(), 45, 90);
}else{
g.drawArc(getPositionX(), getPositionY() + getHeight()/2, getWidth(), getHeight(), 45, 90);
}
}
}
class FacePanel extends JPanel{
private ArrayList<Face> FaceList;
public void setFaceList(ArrayList<Face> FaceListIn) {
FaceList = FaceListIn;
}
//draw panel
FacePanel(){
super();
assert false:"unexpected error...(shape draw panel)";
}
FacePanel(ArrayList<Face> FaceListIn){
setFaceList(FaceList);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (Face oD : FaceList) {
oD.paintComponent(g);
}
}
}
class FaceFrame extends JFrame{
private FacePanel myFacePanel;
public FaceFrame(ArrayList<Face> faceListIn, int width, int height) {
setBounds(100,100,900,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FacePanel myFacepanel = new FacePanel(faceListIn);
}
}
//Main class for my Shapes
abstract class Shape {
//setting of position
//positioning for x
public final void setPositionX(int positionXIn) {
positionX = positionXIn;
}
public final int getPositionX() {
return positionX;
}
private int positionX;
//positioning for y
public final int getPositionY() {
return positionY;
}
public final void setPositionY(int positionYIn) {
positionY = positionYIn;
}
private int positionY;
//The Width of the Shape
public final void setWidth(int widthIn) {
width = OneOrGreater(widthIn);
}
public final int getWidth() {
return width;
}
private int width;
//The Height of the Shape
public final void setHeight(int heightIn) {
height = OneOrGreater(heightIn);
}
public final int getHeight() {
return height;
}
private int height;
//function for shape
public Shape() {
this(0,0,0,0);
}
public Shape(int positionXIn, int positionYIn, int widthIn, int heightIn) {
setPositionX(positionXIn);
setPositionY(positionYIn);
setWidth(widthIn);
setHeight(heightIn);
}
protected static int OneOrGreater(int valueIn) {
assert valueIn>=1:"Shape parameter is unexeptedly less than 1.";
int returnValue = valueIn;
if (valueIn < 1) {
returnValue = 1;
}
return returnValue;
}
//strings
public String toString() {
return String.format("positionX=%d, positionY=%d, width=%d, height=%d", positionX, positionY, getWidth(), getHeight());
}
abstract public double CalcArea();
abstract public double CalcPerimeter();
}
//The Rectangle class that inherits from Shape
class Rectangle extends Shape {
public Rectangle() {
this(0,0);
}
public Rectangle(int widthIn, int heightIn) {
setWidth(widthIn);
setHeight(heightIn);
}
public Rectangle(int positionXIn, int positionYIn, int widthIn, int heightIn) {
super(positionXIn, positionYIn, widthIn, heightIn);
}
//calculating area for rectangle is base * height
public double CalcArea() {
return getWidth() * getHeight();
}
//calculating rectangle perimeter is 2(width+height)
public double CalcPerimeter() {
return getWidth() + getWidth() + getHeight() + getHeight();
}
}
//Class for Oval that inherits from Shape
class Oval extends Shape {
Oval () {
super();
}
Oval(int positionXIn, int positionYIn, int widthIn, int heightIn) {
super(positionXIn, positionYIn, widthIn, heightIn);
}
//Calculating area of oval with oval formula
public double CalcArea() {
return Math.PI * (getWidth()/2) * (getHeight()/2);
}
//The perimeter of an oval is 2 pi * square root of ((a^2+b^2)/2)
public double CalcPerimeter() {
double a = getWidth() / 2.0;
double b = getHeight() / 2.0;
double perimeter =2*Math.PI*Math.sqrt((Math.pow(a,2)+Math.pow(b,2))/2);
return perimeter;
}
}
class FaceFrame extends JFrame {
private FacePanel myFacePanel;
public FaceFrame(ArrayList<Face> faceListIn, int width, int height) {
setBounds(100, 100, 900, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FacePanel myFacepanel = new FacePanel(faceListIn);
}
}
Adding myFacepanel to the JFrame might be a good start...
public FaceFrame(ArrayList<Face> faceListIn, int width, int height) {
setBounds(100, 100, 900, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FacePanel myFacepanel = new FacePanel(faceListIn);
// This might be a good place to start
add(myFacepanel);
}
... next problem ...
FacePanel(ArrayList<Face> FaceListIn){
setFaceList(FaceList);
}
Your assigning FaceList to itself (you're not using FaceListIn).
I'd get rid of the static and update the code...
class FacePanel extends JPanel {
private ArrayList<Face> FaceList;
public void setFaceList(ArrayList<Face> FaceListIn) {
FaceList = FaceListIn;
}
//draw panel
FacePanel() {
super();
}
FacePanel(ArrayList<Face> FaceListIn) {
setFaceList(FaceListIn);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (Face oD : FaceList) {
oD.paintComponent(g);
}
}
}
I am trying to make this program that has two images that move in the straight line and when they read the end of frame, they turn their direction... But the thing is, the images aren't appearing on the screen idk why.. Here is my code for Actor class
public class Actor {
private Image img;
private int x,y,width,height;
private final int RIGHT=1,LEFT=-1;
private byte direction=RIGHT;
public Actor(Image img, int x,int y, int width, int height){
this.x=x;
this.y=y;
this.width=width;
this.height=height;
}
public Image getImg() {
return img;
}
public void setImg(Image img) {
this.img = img;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public void movement(int frameWidth){
setX(getX()+direction);
if(getX()<0) direction= RIGHT;
if(getX()>(frameWidth-width)) direction= LEFT;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
and here is my main class:
public class game extends JFrame implements Runnable{
private int framewidth=1000;
private int frameheight=1500;
Image image= new ImageIcon("pics/buffy.png").getImage();
Image image2= new ImageIcon("pics/buffythelayer.jpg").getImage();
private Thread thread;
private int picX=100;
private int c=1;
private int xSpeed=3;
private int xFly=1;
private int yFly=100;
private Actor greenCar,pinkCar;
public game(){
setBounds(100,100,framewidth,frameheight);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
thread= new Thread(this);
thread.start();
greenCar=new Actor(image,30,70,98,40);
pinkCar=new Actor(image2,400,70,98,40);
}
public void paint(Graphics g){
g.fillRect(xFly, yFly, 10, 10);
g.drawImage(greenCar.getImg(), greenCar.getX(), greenCar.getY(), null);
g.drawImage(pinkCar.getImg(), pinkCar.getX(), pinkCar.getY(), null);
if(c==2){
g.setColor(Color.CYAN);
g.fillOval(100, 200, 150, 200);
}
}
public static void main(String[] args) {
new game();
}
public void run() {
while(true)
{
xFly++;
greenCar.movement(framewidth);
pinkCar.movement(framewidth);
/*if(picX>280){
xSpeed=-xSpeed;
picX=picX+xSpeed;
c=2;
}
if(picX>=100){
xSpeed=3;
picX=picX+xSpeed;
}*/
repaint();
try{
thread.sleep(13);
}
catch(InterruptedException e){
}
}
}
}
I think I see the problem. When you run the code below, you set the last value, the ImageObserver, to null.
g.drawImage(greenCar.getImg(), greenCar.getX(), greenCar.getY(), null);
g.drawImage(pinkCar.getImg(), pinkCar.getX(), pinkCar.getY(), null);
Instead, you should write it like this:
g.drawImage(greenCar.getImg(), greenCar.getX(), greenCar.getY(), this);
g.drawImage(pinkCar.getImg(), pinkCar.getX(), pinkCar.getY(), this);
Therefore, the JFrame is the object that is notified as the image loads and can be drawn on the screen correctly.
If that's not the case, then you should add super.paint(g) to your paint method.
Your paint(g) method should look like this:
public void paint(Graphics g){
super.paint(g);
g.fillRect(xFly, yFly, 10, 10);
g.drawImage(greenCar.getImg(), greenCar.getX(), greenCar.getY(), this);
g.drawImage(pinkCar.getImg(), pinkCar.getX(), pinkCar.getY(), this);
if(c==2){
g.setColor(Color.CYAN);
g.fillOval(100, 200, 150, 200);
}
}
I hope this helps.
The problem is you run thread before you construct the car object, so
creat object first, the run the thread
greenCar=new Actor(image,30,70,98,40);
pinkCar=new Actor(image2,400,70,98,40);
thread.start();
and you forget set image in Actor constructor
public Actor(Image img, int x,int y, int width, int height){
this.x=x;
this.y=y;
this.width=width;
this.height=height;
this.img = img;
}
This is my bullet class. I have been trying to make my bullet go in a direction I get from the mouse.
But the problem is when I shoot a bullet it is not going in the direction I want. Sometimes it is right but mostly it is off by around 20 pixels.
public class Bullet extends Entity {
public Bullet(int x, int y, int width, int height, boolean solid, Id id,
GameHandler handler,int targetPosX, int targetPosY, int speed) {
super(x, y, width, height, solid, id, handler);
this.setTargetPosX(targetPosX);
this.setTargetPosY(targetPosY);
this.speed = speed;
angle = Math.toDegrees(Math.atan2(targetPosY-y, targetPosX-x));
}
#Override
public void render(Graphics g) {
g.setColor(Color.BLACK);
g.fillOval(x-(width/2), y-(height/2), width, height);
}
#Override
public void update() {
x += (float)(Math.cos(Math.toRadians(angle)))*speed;
y += (float)(Math.sin(Math.toRadians(angle)))*speed;
}
public void moveToTarget(){
}
public int getTargetPosX() {
return targetPosX;
}
private void setTargetPosX(int targetPosX) {
this.targetPosX = targetPosX;
}
public int getTargetPosY() {
return targetPosY;
}
private void setTargetPosY(int targetPosY) {
this.targetPosY = targetPosY;
}
public int getSpeed() {
return speed;
}
}
This is my Cursor class:
public class GameCursor extends Entity {
private LinkedList<Bullet> bulletList = new LinkedList<Bullet>();
private enum State{
AIM,
DEFULT,
RELODING;
}
public GameCursor(Entity en,GameHandler handler) {
super(MouseInfo.getPointerInfo().getLocation().x, MouseInfo.getPointerInfo().getLocation().y, 0, 0, false, Id.cursor , handler);
this.state = State.AIM;
this.en = en;
}
#Override
public synchronized void render(Graphics g) {
switch(this.state){
case AIM:
g.setColor(Color.red);
g.drawOval(x-15, y-15, 30, 30);
g.fillRect(x, y, 1, 1);
break;
}
for(Bullet b: getBulletList()){
b.render(g);
}
}
#Override
public synchronized void update() {
x = MouseInput.getMousePosX()-(-en.getX() + Frame.WIDTH/2);
y = MouseInput.getMousePosY()-(-en.getY() + Frame.HEIGHT/2 + 100);
for(Bullet b: getBulletList()){
b.update();
}
}
public void shoot(){
Bullet b = new Bullet(en.getX() + (en.width/2) ,en.getY()+ (en.height/2),10,10,true, Id.bullet, handler, getX(), getY(), 12);
addBullet(b);
}
}
I am using LWJGL and SlickUtil to make a game, and I made my own GLButton class that you can click. It works fine, but I want to add action listener implementation so I don't have to make a new class for each button that has a different action when it gets clicked. I want it so I can do
GLButton.addActionListener((ActionEvent e) -> {
//do method here
});
Here is the code of the class
public class GLButton {
private boolean alive = false;
private float x1;
private float y1;
private float x2;
private float y2;
private String text;
private final Texture tex;
private final Texture texOver;
private final Texture texPressed;
private Texture currentTexture;
private boolean pressed=false;
public GLButton(float x, float y, float width, float height, String text) {
this.x1=x;
this.y1=y;
this.x2=width;
this.y2=height;
this.text=text;
tex=loadTexture("btn");
texOver=loadTexture("btnOver");
texPressed=loadTexture("btnPressed");
currentTexture = tex;
alive=true;
}
public void draw() {
if(!alive) return;
pollInput();
currentTexture.bind();
glColor3f(1,1,1);
glBegin(GL_QUADS);
glTexCoord2f(0,0);glVertex2f(x1,y1);
glTexCoord2f(0,1);glVertex2f(x1,y1+y2);
glTexCoord2f(1,1);glVertex2f(x1+x2,y1+y2);
glTexCoord2f(1,0);glVertex2f(x1+x2,y1);
glEnd();
}
public void setText(String text) {
this.text=text;
}
public void setLocation(float x, float y) {
this.x1=x;
this.y1=y;
}
public void setSize(float width, float height) {
this.x2=width;
this.y2=height;
}
private Texture loadTexture(String key) {
try {
return TextureLoader.getTexture("PNG", new FileInputStream(
Start.main_dir+"\\res\\textures\\"+key+".png"));
} catch (IOException ex) {
Logger.getLogger(GLButton.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
private void pollInput() {
if(GameWindow.grabbed==true) return;
int mouseY = Math.abs(Mouse.getY()-Display.getHeight());
currentTexture = tex;
if(Mouse.getX()>=(int)x1 && Mouse.getX()<=(int)x1+(int)x2 && mouseY >= (int)y1 && mouseY <= (int)y1+(int)y2) {
currentTexture = texOver;
if(Mouse.isButtonDown(0)&&pressed==false) {
pressed=true;
currentTexture = texPressed;
} else if(!Mouse.isButtonDown(0)) {
pressed=false;
}
}
}
public boolean isAlive() {
return alive;
}
public void destroy() {
alive=false;
}
public float getX() {
return x1;
}
public float getY() {
return y1;
}
public float getWidth() {
return x2;
}
public float getHeight() {
return y2;
}
}
I'm very new to game design (this is my first attempt) and this project will be used to create an android game.
I'm trying to make a simple game (as simple as possible).
What I need:
A background
a ship (that can move left an right at the bottom of the screen)
Enemies (Bombs dropping down from the sky)
projectiles (to shoot bombs with, shoot straight up)
Score (in the upper corner)
I have studied this tutorial:
http://www.kilobolt.com/game-development-tutorial.html
and changed code to get this:
http://i297.photobucket.com/albums/mm231/mabee84/Battleship.png
the black rectangles are projectiles.
Now I need to create the bombs but I can't figure out how to implement them.
they need to spawn at fixed y-value and a random x-value (within the screen)
Upon shooting on the bombs they should die but if bombs hit the ship game is over.
Please help i'm a bit stuck.
package kiloboltgame;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.net.URL;
import java.util.ArrayList;
public class StartingClass extends Applet implements Runnable, KeyListener {
private Ship ship;
public static Bomb b1, b2;
public static int score = 0;
private Font font = new Font(null, Font.BOLD, 30);
private Image image, Battleship, Background, Bomb;
private static Background bg1, bg2;
private URL base;
private Graphics second;
#Override
public void init() {
setSize(800, 480);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("BattleShip");
try{
base = getDocumentBase();
}catch (Exception e){
//TODO: handle exception
}
//Image Setups
Battleship = getImage(base, "data/Battleship.png");
Background = getImage(base, "data/Background.png");
Bomb = getImage(base, "data/Bomb1.png");
}
#Override
public void start() {
bg1 = new Background(0, 0);
bg2 = new Background(800, 0);
ship = new Ship();
b1 = new Bomb(340, 100);
b2 = new Bomb(700, 100);
Thread thread = new Thread(this);
thread.start();
}
#Override
public void stop() {
// TODO Auto-generated method stub
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void run() {
while (true) {
ship.update();
ArrayList projectiles = ship.getProjectiles();
for(int i = 0; i < projectiles.size(); i++){
Projectile p = (Projectile) projectiles.get(i);
if(p.isVisible() == true){
p.update();
}else{
projectiles.remove(i);
}
}
b1.update();
b2.update();
bg1.update();
bg2.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void update(Graphics g) {
if(image == null){
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
g.drawImage(Background, bg1.getBgX(), bg1.getBgY(), this);
ArrayList projectiles = ship.getProjectiles();
for(int i = 0; i < projectiles.size(); i++){
Projectile p = (Projectile) projectiles.get(i);
g.setColor(Color.BLACK);
g.fillRect(p.getX(), p.getY(), 5, 10);
}
g.drawImage(Battleship, ship.getCenterX() + 230, ship.getCenterY() -23, this);
g.drawImage(Bomb, b1.getCenterX() - 20, b1.getCenterY() - 20, this);
g.drawImage(Bomb, b2.getCenterX() - 20, b2.getCenterY() - 20, this);
g.setFont(font);
g.setColor(Color.BLACK);
g.drawString(Integer.toString(score), 710, 30);
}
#Override
public void keyPressed(KeyEvent e) {
switch(e.getKeyCode()){
case KeyEvent.VK_LEFT:
ship.moveLeft();
break;
case KeyEvent.VK_RIGHT:
ship.moveRight();
break;
case KeyEvent.VK_CONTROL:
ship.shoot();
score = score +100;
break;
}
}
#Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_LEFT:
ship.stop();
break;
case KeyEvent.VK_RIGHT:
ship.stop();
break;
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public static Background getBg1() {
return bg1;
}
}
package kiloboltgame;
import java.util.ArrayList;
public class Ship {
//In Java, Class Variables should be private so that only its methods can change them.
private int centerX = 100;
private int centerY = 382;
private int speedX = 0;
private int speedY = 1;
private ArrayList<Projectile> projectiles = new ArrayList<Projectile>();
public void update() {
// Moves Character or Scrolls Background accordingly.
if (speedX < 0) {
centerX += speedX;
} else if (speedX == 0) {
System.out.println("Do not scroll the background.");
} else {
if (centerX <= 440) {
centerX += speedX;
} else {
System.out.println("Scroll Background Here");
}
}
// Updates Y Position
if (centerY + speedY >= 382) {
centerY = 382;
}else{
centerY += speedY;
}
// Prevents going beyond X coordinate of 0
if (centerX + speedX <= -230) {
centerX = -229;
}
}
public void moveRight() {
speedX = 6;
}
public void moveLeft() {
speedX = -6;
}
public void shoot(){
Projectile p = new Projectile(centerX + 285, centerY -10);
projectiles.add(p);
}
public ArrayList getProjectiles(){
return projectiles;
}
public void stop() {
speedX = 0;
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public int getSpeedX() {
return speedX;
}
public int getSpeedY() {
return speedY;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
}
package kiloboltgame;
public class Background {
private int bgX, bgY, speedX;
public Background(int x, int y){
bgX = x;
bgY = y;
speedX = 0;
}
public void update() {
bgX += speedX;
if (bgX <= -800){
bgX += 1600;
}
}
public int getBgX() {
return bgX;
}
public int getBgY() {
return bgY;
}
public int getSpeedX() {
return speedX;
}
public void setBgX(int bgX) {
this.bgX = bgX;
}
public void setBgY(int bgY) {
this.bgY = bgY;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
}
public class Projectile {
private int x, y, speedY;
private boolean visible;
public Projectile(int startX, int startY) {
x = startX;
y = startY;
speedY = -7;
visible = true;
}
public void update() {
y += speedY;
if(y > 480){
visible = false;
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getSpeedY() {
return speedY;
}
public boolean isVisible() {
return visible;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setSpeedY(int speedY) {
this.speedY = speedY;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
}
package kiloboltgame;
public class Enemy {
private int maxHealth, currentHealth, power, speedX, centerX, centerY;
private Background bg = StartingClass.getBg1();
//Behavioral Methods
public void update(){
centerX += speedX;
speedX = bg.getSpeedX();
}
public void die(){
}
public void attack(){
}
public int getMaxHealth() {
return maxHealth;
}
public int getCurrentHealth() {
return currentHealth;
}
public int getPower() {
return power;
}
public int getSpeedX() {
return speedX;
}
public int getCenterX() {
return centerX;
}
public int getCenterY() {
return centerY;
}
public Background getBg() {
return bg;
}
public void setMaxHealth(int maxHealth) {
this.maxHealth = maxHealth;
}
public void setCurrentHealth(int currentHealth) {
this.currentHealth = currentHealth;
}
public void setPower(int power) {
this.power = power;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setCenterX(int centerX) {
this.centerX = centerX;
}
public void setCenterY(int centerY) {
this.centerY = centerY;
}
public void setBg(Background bg) {
this.bg = bg;
}
}
package kiloboltgame;
public class Bomb extends Enemy {
public Bomb(int centerX, int centerY) {
setCenterX(centerX);
setCenterY(centerY);
}
}
This is all code that i have so far (I know the background is f*ed since the game this is based on is scrolling right and i haven't fixed it yet.
I recommend putting all object creation in a seperate part of the program. I'd make a BombFactory with a makeBomb mathod that returns a new Bomb instance. Inside the factory, figure out the x-coordinate, for instance using a randomiser. As parameters, you could specify a y-coordinate and possibly an upper and lower bound for the x. This way you can make new Bombs on the fly.
public class BombFactory {
private final Random rand;
public BombFactory() {
this.rand = new Random();
}
public Bomb makeBomb(int lowerboundX, int rangeX, int yPos) {
final int xPos = lowerboundX + rand.nextInt(rangeX);
return new Bomb(xPos, yPos);
}
}
As for the behaviour, I'd look into inheritance and interfaces some more. I see a lot of methods occurring more than once. You generally want to avoid that kind of duplication. You can start by taking all the methods having something to do with coords or movement and putting them in an abstract base class.
You can make a method inside Enemy that checks for a collision and responds to that in different ways, depending on how the subclass overrides it. In case of a Bomb, it would probably always kill itself and whatever it came in contact with.