INTRODUCTION
Hi guys, I was learning how to make a little game where you are a racquet (rectangle) and all the asteroids (enemies) are falling down the screen and you have to avoid them
PROBLEM
When the game starts the enemies (asteroids) are paint on the screen in a very high speed, and they occupy all the size of the screen so there is no way to avoid them (try the game), I just want that between painting an enemy and the next one there is a mininum time to delay (for example 0,5 seconds). But I just don't know how to do that, I tried to use Thread.sleep() and TimeUnit but they just make the game slower. Surfing on stackoverflow I've find out that I may try to use Swing timers, I've read some stuff on the web but I want to know how can I use swing timers in my code (if they can solve my problem).
Here it is the code: The main class:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
@SuppressWarnings("serial")
public class Game extends JPanel {
Racquet racquet = new Racquet(this);
Enemy Enemy = new Enemy(this);
static ArrayList<Enemy> enemyList = new ArrayList<Enemy>();
public Game() {
addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
racquet.keyReleased(e);
}
@Override
public void keyPressed(KeyEvent e) {
racquet.keyPressed(e);
}
});
setFocusable(true);
}
/** TO SET THE RANDOM POSITION ON WHERE THE ENEMIES HAVE TO APPEAR ON THE SCREEN **/
public int random(int x, int y, ArrayList<Enemy> pa){
int r = 0;
for(int i = 0; i<pa.size(); i++){
Random rand = new Random();
r = rand.nextInt(x+y)-1;
return r;
}
return r;
}
/** letting the enemies move on the screen **/
private void move() {
for(int i = 0; i < enemyList.size(); i++){
enemyList.get(i).move();
}
racquet.move();
}
/** Painting on the screen enemies and the racquet **/
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for(int i = 0; i < enemyList.size(); i++){
enemyList.get(i).paint(g2d);
}
racquet.paint(g2d);
}
public void gameOver() {
JOptionPane.showMessageDialog(this, "Game Over", "Game Over", JOptionPane.YES_NO_OPTION);
System.exit(ABORT);
}
public void createEnemy(){
enemyList.add(new Enemy(this));
}
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("Asteroids");
Game game = new Game();
frame.add(game);
frame.setSize(300, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.random(200, 300, enemyList);
while (true) {
game.createEnemy();
game.move();
game.repaint();
Thread.sleep(5);
}
}
}
The racquet class:
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
public class Racquet {
private static final int Y = 330;
private static final int WIDTH = 30;
private static final int HEIGHT = 6 ;
int x = 0;
int xa = 0;
private Game game;
public Racquet(Game game) {
this.game = game;
}
/** letting the racquet moves on the screen **/
public void move() {
if (x + xa > 0 && x + xa < game.getWidth() - WIDTH)
x = x + xa;
}
/** Creating the rectangle racquet **/
public void paint(Graphics2D g) {
g.fillRect(x, Y, WIDTH, HEIGHT);
}
/** // Setting xa everytime to 0, if we don't do this it just takes a single pression to go to a direction until we press the other key **/
public void keyReleased(KeyEvent e) {
xa = 0;
}
/** Choosing the direction **/
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT)
xa = -1;
if (e.getKeyCode() == KeyEvent.VK_RIGHT)
xa = 1;
}
public Rectangle getBounds() {
return new Rectangle(x, Y, WIDTH, HEIGHT);
}
public int getTopY() {
return Y;
}
}
And the enemy class:
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.util.*;
public class Enemy {
private Game game;
int x = 0;
int y = 0;
int xa = 1;
int ya = 1;
/** Generating a random position where the enemies have to appear **/
public Enemy(Game game){
this.game = game;
x = game.random(0, 320, game.enemyList);
}
/** Paint the enemies **/
public void paint(Graphics2D g) {
g.fillRect(x, y, 20, 20);
}
/** move the enemies and detect collisions **/
public void move(){
y += ya;
if(collision()){
game.gameOver();
}
}
/** returns true if the enemy rectangle touch the racquet **/
public boolean collision(){
return game.racquet.getBounds().intersects(getBounds());
}
public Rectangle getBounds() {
return new Rectangle(x, y, 20, 20);
}
}