Adding the sprite "racquet"

In this tutorial we will add a racquet using a Sprite called Racquet. The racquet will move to the left or to the right when we press the cursor keys, so our program has to read from the keyboard.

New Sprite "Racquet"

The first thing we have to do is add a new property called racquet in the class "Game", where we keep the racquet sprite. In the move() method we add a call to racquet.move() and in the paint() method a call to racquet.paint(). Until now, everything is similar to the sprite "Ball", but we have to do something else because the position of the racquet responds to the keyboard.

package com.edu4java.minitennis5;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class Game extends JPanel {

	Ball ball = new Ball(this);
	Racquet racquet = new Racquet(this);

	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);
	}
	
	private void move() {
		ball.move();
		racquet.move();
	}

	@Override
	public void paint(Graphics g) {
		super.paint(g);
		Graphics2D g2d = (Graphics2D) g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		ball.paint(g2d);
		racquet.paint(g2d);
	}

	public static void main(String[] args) throws InterruptedException {
		JFrame frame = new JFrame("Mini Tennis");
		Game game = new Game();
		frame.add(game);
		frame.setSize(300, 400);
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		while (true) {
			game.move();
			game.repaint();
			Thread.sleep(10);
		}
	}
}

In the constructor of the class "Game" we can see how we register a listener to capture the events of the keyboard. In the keyPressed() method of the listener, we inform the racquet that a key has been pressed by calling racquet.keyPressed(e). We do the same for keyReleased(). With this the sprite "racquet", will know when a key has been pressed. Let´s look now at the classes "Ball" and "Racquet".

package com.edu4java.minitennis5;

import java.awt.Graphics2D;

public class Ball {
	int x = 0;
	int y = 0;
	int xa = 1;
	int ya = 1;
	private Game game;

	public Ball(Game game) {
		this.game= game;
	}

	void move() {
		if (x + xa < 0)
			xa = 1;
		if (x + xa > game.getWidth() - 30)
			xa = -1;
		if (y + ya < 0)
			ya = 1;
		if (y + ya > game.getHeight() - 30)
			ya = -1;

		x = x + xa;
		y = y + ya;
	}

	public void paint(Graphics2D g) {
		g.fillOval(x, y, 30, 30);
	}
}

The "Ball" class hasn´t got any changes. Let´s compare it with the class "Racquet":

package com.edu4java.minitennis5;

import java.awt.Graphics2D;
import java.awt.event.KeyEvent;

public class Racquet {
	int x = 0;
	int xa = 0;
	private Game game;

	public Racquet(Game game) {
		this.game= game;
	}

	public void move() {
		if (x + xa > 0 && x + xa < game.getWidth()-60)
			x = x + xa;
	}

	public void paint(Graphics2D g) {
		g.fillRect(x, 330, 60, 10);
	}

	public void keyReleased(KeyEvent e) {
		xa = 0;
	}

	public void keyPressed(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_LEFT)
			xa = -1;
		if (e.getKeyCode() == KeyEvent.VK_RIGHT)
			xa = 1;
	}
}

Unlike "Ball", "Racquet" hasn´t got any properties for the position "y" or for the speed "ya". This is because the racquet doesn´t change its vertical position; it will only move left or right, never up or down. In the pait method, the g.fillRect(x, 330, 60, 10)instruction defines a rectangle of 60 by 10 pixels in the position (x,y)=(x,330). As we can see "x" can change but "y" is fixed in 330 pixels from the top border of the canvas.

The move() method is similar to the one in "Ball" as it increases in "xa" the position "x" and controls that the sprite doesn´t go out of the borders.

	public void move() {
		if (x + xa > 0 && x + xa < game.getWidth()-60)
			x = x + xa;
	}

In the beginning the value of "x" is zero, which indicates that the racquet will be in the left border of the canvas. "xa" is also initialize to zero, which makes the racquet look static in the beginning, because x = x + xa won´t change "x" while "xa" is zero.

When someone presses a key, the keyPressed method of "Racquet" will be called and this will set "xa" to 1, if the key pressed is the right direction (KeyEvent.VK_RIGHT), what will move the racquet to the right the next time the move method is called (remember x = x + xa). In the same way if we press the key KeyEvent.VK_LEFT it will move to the left.

	public void keyPressed(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_LEFT)
			xa = -1;
		if (e.getKeyCode() == KeyEvent.VK_RIGHT)
			xa = 1;
	}

When a key is released, the method keyReleased is called and "xa" changes its value to zero, which makes the racquet stop.

	public void keyReleased(KeyEvent e) {
		xa = 0;
	}

If we run the example we can see how the ball moves bouncing against the borders and the racquet moving when we press the direction keys. When the ball collides with the racquet, it goes through as if it didn´t exist. In the next tutorial we will see how to make the ball bounce on the racquet.

 

<< Events. Keyboard input Collision detection >>