Hello everyone! I am new to that forum (actually joined a few mins ago) and i need your advice concerning a game i made.
I made a simple game which is pretty hard.
I have a few problems though that i don't know how to solve:
1) The high score mechanic doesn't work well and in general i don't really know how should i make one (High score sometimes change).
2) The game doesn't work on all platforms. I tried it on windows XP and it doesn't work. But on another XP it does work which is weird.
3) When the game starts it shows a black screen and i need to minimize it and maximize again in order for it to work.
4) The window's bounds are a bit messy and i have no idea why.
5) Lastly, I want advice concerning how well the code is written and if there is a more simple or easy way to do it.
6) Of course any other bugs you find that can be fixed are "welcomed".
As i said i am new to the forum so i am not sure how should i post the code, so forgive me if i do something against the rules or not in the wanted way. Oh, last thing before i post the code - I wrote it using the regular graphic library (May be the problem).
Sorry that there are no comments
Main.java
package TheGame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.Timer;
public class Main
{
static JFrame frame = new JFrame();
static boolean startGame = false;
static String str;
public static void main (String [] args) throws InterruptedException
{
frame.setSize(Game.WIDTH, Game.HEIGHT);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
runnit();
}
public static void runnit() throws InterruptedException
{
final Game game = new Game();
Timer animationTimer = new Timer(40, new ActionListener() //Game Loop
{
public void actionPerformed(ActionEvent event)
{
game.repaint();
game.move();
};
});
frame.add(game);
game.setVisible(true);
frame.revalidate();
animationTimer.start();
}
}
Game.java
package TheGame;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class Game extends JPanel
{
private static final long serialVersionUID = 1L;
static int HEIGHT = 650;
static int WIDTH = 1200;
static int score = 0;
static String deathMessage = "Click to start" ;
static boolean dead = false;
static boolean startGame = false;
static Player spaceShip = new Player(1,3,100,HEIGHT/2-110,WIDTH/3);
static HighscoreManager hm = new HighscoreManager(0);
static int highscore = hm.getScores();
static int max = highscore; //Not sure if needed so i won't delete O_O
Meteor asteroid = new Meteor(WIDTH+600,(int) ((Math.random() * 440) + 110),-18,60);
Meteor asteroid2 = new Meteor(WIDTH + (WIDTH / 5)+600,(int) ((Math.random() * 440) + 110),-18,60);
Meteor asteroid3 = new Meteor(WIDTH + (WIDTH / 5)*2+600,(int) ((Math.random() * 440) + 110),-18,60);
Meteor asteroid4 = new Meteor(WIDTH + (WIDTH / 5)*3+600,(int) ((Math.random() * 440) + 110),-18,60);
Meteor asteroid5 = new Meteor(WIDTH + (WIDTH / 5)*4+600,(int) ((Math.random() * 440) + 110),-18,60);
int scrollX = 0;
BufferedImage img;
{
try
{
img = ImageIO.read(getClass().getResourceAsStream("/4.png"));
}
catch (IOException e) {}
}
public Game()
{
this.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent event) {}
public void keyReleased(KeyEvent event)
{
if (event.getKeyCode() == KeyEvent.VK_UP)
{
spaceShip.jumpUp();
}
if (event.getKeyCode() == KeyEvent.VK_DOWN)
{
spaceShip.jumpDown();
}
}
public void keyTyped(KeyEvent event)
{
if (event.getKeyCode() == KeyEvent.VK_UP)
{
spaceShip.jumpUp();
}
if (event.getKeyCode() == KeyEvent.VK_DOWN)
{
spaceShip.jumpDown();
}
}
});
}
public void move()
{
this.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent arg0)
{
setFocusable(true);
requestFocusInWindow();
deathMessage = "" ;
startGame = true;
}
});
if(!startGame)
{
asteroid.setMeteor(WIDTH+600);
asteroid2.setMeteor(WIDTH + (WIDTH / 5)+600);
asteroid3.setMeteor(WIDTH + (WIDTH / 5)*2+600);
asteroid4.setMeteor(WIDTH + (WIDTH / 5)*3+600);
asteroid5.setMeteor(WIDTH + (WIDTH / 5)*4+600);
}
else
{
spaceShip.move();
asteroid.move();
asteroid2.move();
asteroid3.move();
asteroid4.move();
asteroid5.move();
scrollX += asteroid.getSpeed();
if (scrollX == -1800)
{
scrollX = 0;
}
if (dead)
{
asteroid.setMeteor(WIDTH+600);
asteroid2.setMeteor(WIDTH + (WIDTH / 2)+600);
dead = false;
}
}
}
public static void score()
{
score += 1;
}
public void paint(Graphics g)
{
super.paint(g);
g.drawImage(img, 0, 0, null);
g.setFont(new Font("comicsans", Font.BOLD, 40));
g.setColor(Color.WHITE);
g.drawString("Score: " + score/9, WIDTH / 2 - 80, 580);
g.drawString("Highscore: " + highscore/9, WIDTH / 2 - 120, 40);
g.setColor(Color.RED);
g.drawString(deathMessage, 200, 200);
spaceShip.paint(g);
asteroid.paint(g);
asteroid2.paint(g);
asteroid3.paint(g);
asteroid4.paint(g);
asteroid5.paint(g);
}
public static void reset()
{
spaceShip.setY(Game.HEIGHT/2-spaceShip.getSize()+10);
spaceShip.setSpeed(2);
if(score > highscore && score!=0)
{
highscore = score;
hm.setScore(score);
}
score = 0;
deathMessage = "you died, click to try again";
startGame = false;
}
}
Player.java
package TheGame;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Player
{
private int speed;
private int gravity;
private int size;
private int y;
private int x;
BufferedImage img;
{
try {img = ImageIO.read(getClass().getResourceAsStream("/2.png"));}
catch (IOException e) {}
}
public Player(int speed, int gravity, int size, int y, int x)
{
this.speed = speed;
this.gravity = gravity;
this.size = size;
this.y = y;
this.x = x;
}
public void jumpUp()
{
speed = 17;
}
public void jumpDown()
{
speed = -17;
}
public void move()
{
if(y>0 && y<=255)
{
speed = speed - gravity;
y = y - speed;
}
if(y>=255 && y<=Game.HEIGHT)
{
speed = speed + gravity;
y = y - speed;
}
if(y<0 || y>=510)
{
Game.reset();
Game.dead = true;
}
}
public void setSpeed (int speed)
{
this.speed = speed;
}
public void setGravity(int gravity)
{
this.gravity = gravity;
}
public void setSize(int size)
{
this.size = size;
}
public int getSize()
{
return size;
}
public void setX(int x)
{
this.x = x;
}
public void setY(int y)
{
this.y = y;
}
public void paint(Graphics g)
{
g.drawImage(img, x, y, null);
/*==DEBUG ONLY!!!==*/
//g.drawRect(x, y, DIAMETER, DIAMETER);
}
public Rectangle getBounds()
{
return new Rectangle(x, y, size, size);
}
}
Meteor.java
package TheGame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Meteor
{
private int x;
private int y;
private int speed;
private int size; //Width = Length = Size!!
BufferedImage img;
{
try {img = ImageIO.read(getClass().getResourceAsStream("/6.png"));}
catch (IOException e) {}
}
public Meteor(int x, int y, int speed, int size)
{
this.x = x;
this.y = y;
this.speed = speed;
this.size = size;
}
public void setMeteor(int i)
{
this.x = i;
}
public void setSpeed (int speed)
{
this.speed = speed;
}
public int getSpeed()
{
return speed;
}
public void setSize(int size)
{
this.size = size;
}
public int getSize()
{
return size;
}
public void setX(int x)
{
this.x = x;
}
public void setY(int y)
{
this.y = y;
}
public void paint(Graphics g)
{
g.drawImage(img, x, y, null);
g.setColor(Color.RED);
/*==DEBUG ONLY!!!==*/
//g.drawRect(x, 0, WIDTH, Game.HEIGHT);
//g.drawRect(x, y, WIDTH, HEIGHT);
}
public void move()
{
x += speed;
Rectangle wallBounds = new Rectangle(x, 0, size, Game.HEIGHT);
Rectangle wallBoundsCritical = new Rectangle(x, y, size, size);
if ( (wallBoundsCritical.intersects(Game.spaceShip.getBounds()) ))
{
Game.reset();
setMeteor(x);
died();
}
if ((wallBounds.intersects(Game.spaceShip.getBounds())))
{
Game.score();
}
if (x <= 0 - size)
{
x = Game.WIDTH;
y = (int) ((Math.random() * 440) + 80);
}
}
public Rectangle getScoreBounds()
{
return new Rectangle(x, 0, size, Game.HEIGHT);
}
public Rectangle getCriticalBounds()
{
return new Rectangle(x, y, size, size);
}
public void died()
{
y = (int) ((Math.random() * 440) + 110);
}
}
HighscoreManager.java
package TheGame;
import java.io.*;
public class HighscoreManager
{
private Score scores;
private static final File file = new File("D:\\scores.dat");
OutputStream outputStream = null;
InputStream inputStream = null;
public HighscoreManager(int score)
{
scores = new Score(score);
}
public int getScores()
{
loadScoreFile();
return scores.getScore();
}
public void setScore(int score)
{
loadScoreFile();
scores.setScore(score);
updateScoreFile();
}
public void loadScoreFile()
{
try
{
Runtime.getRuntime().exec("attrib -H D:\\scores.dat");
inputStream = new FileInputStream(file);
scores.setScore(inputStream.read());
}
catch (FileNotFoundException e) {}
catch (IOException e) {System.out.println("oops1");}
finally
{
try
{
if (outputStream != null)
{
outputStream.flush();
outputStream.close();
}
}
catch (IOException e) {}
}
}
public void updateScoreFile()
{
try {
outputStream = new FileOutputStream(file, false);
outputStream.write(scores.getScore());
Runtime.getRuntime().exec("attrib +H D:\\scores.dat");
}
catch (FileNotFoundException e) {}
catch (IOException e) {System.out.println("oops2");}
finally
{
try
{
if (outputStream != null)
{
outputStream.flush();
outputStream.close();
}
}
catch (IOException e){}
}
}
public int getHighscore()
{
return scores.getScore();
}
}
Score.java
package TheGame;
import java.io.Serializable;
public class Score implements Serializable
{
private static final long serialVersionUID = 1L;
private int score;
public int getScore()
{
return score;
}
public void setScore(int score)
{
this.score = score;
}
public Score(int score)
{
this.score = score;
}
}
That's it. I will be very grateful for solving what i asked\ giving me some advises for further programming.
Lastly, I am adding the game itself as a .jar file for those who want to see the game\ play it\ seeing the bugs i mentioned.
The code probably won't run because the resources files are missing - for that purpose i am adding the game itself.
http://www.sendspace.com/file/0tnl5g - this is the download link, for some reason i cant attach the file here.
The game's idea is simple - you move with the UP and DOWN arrows and evade the Meteors. The "problem" is that the gravity is in the middle.
P.S - Another thing i just remembered is that the Spaceship and Meteors bounds are rectangles and not the actual shape. Any way to make the bounds look like the actual shape and not as a rectangle?