You are on page 1of 37

INTRODUCTION

In this book we will introduce you to the Java programming language in ONE DAY- by taking you through the steps necessary to create your irst Java programming pro!ect " a simple game# $o begin with you will need the tools necessary or Java programming# %e will start by installing the Java JD& ' Java Development &it( and J)E 'Java )untime Environment(* and the Eclipse IDE 'Integrated Development Environment(# $hese can be downloaded rom the Oracle website and the Eclipse website respectively# Once you have this basic working environment installed* we will complete a +,ello%orld+ application* so that you can see how the programming environment operates* and then we will go through the steps to complete a basic +-ong+ game# .sing this approach you will see how to set a target 'the creation o a complete working game(* break down that target into components and steps* learn the programming skills necessary to complete each step* and then assemble the complete game# /or our basic game we have chosen to work through the ollowing steps0a( $he creation o a space or board or the game to e1ist b( $he ability to draw on the board c( $he ability to control the movement or animation o ob!ects we have drawn on the board d( $he ability to control the ob!ects we have created using our computer keyboard e( $he ability or the ob!ects we have created to interact ( $o provide an indication when the game ends g( $o add sound

Chapter 1 - Creating a Board


Introducing: JFrame, JPanel, paint method The first thing we will create is a window or board for our game. Foe this we will use a JPanel object, framed in a window made by the JFrame class. 1:1 JFrame: The window The code below performs the following tasks 1) it creates a framed window called "Board", !! pi"els by !! pi"els in si#e. $) %t makes the window &isible by using the "set'isible(true)" command ) %t stops the program when we close the window, using the )"frame.set*efault+lose,peration(-Frame../%T0,10+2,3.)" ) command
import javax.swing.JFrame; public class Game { public static void main(String[] args { JFrame !rame " new JFrame(#$oard# ; !rame.setSi%e(&''( &'' ; !rame.set)isible(true ; !rame.set*e!ault+lose,peration(JFrame.-./01,21+3,S- ; 4 4

%f we run this script. we will obtain a window which looks like this4

5ith these few instructions we will obtain a window which can be ma"imi#ed, minimi#ed, ha&e it6s si#e changed with the mouse, etc. 1:2 JPanel: The canvas

,ur ne"t step is to be able to draw in the framed window we ha&e created. To do this we import a series of -a&a 7bstract 5indow Toolkits (ja&a.awt8s), which enable the creation of graphics.
import import import import import import import java.awt.+olor; java.awt.Grap5ics; java.awt.Grap5ics6*; java.awt.7endering8ints; java.awt.geom.-llipse6*; javax.swing.JFrame; javax.swing.J9anel;

:Suppress;arnings(#serial# public class Game6 extends J9anel { :,verride public void paint(Grap5ics g { Grap5ics6* g6d " (Grap5ics6* g; g6d.set+olor(+olor.$3<- ; g6d.!ill,val('( '( &'( &' ; g6d.draw,val('( ='( &'( &' ; g6d.!ill7ect(='( '( &'( &' ; g6d.draw7ect(='( ='( &'( &' ; g6d.draw(new -llipse6*.*ouble('( >''( &'( &' 4 public static void main(String[] args { JFrame !rame " new JFrame(#$oard# ; !rame.add(new Game6( ; !rame.setSi%e(&''( &'' ; !rame.set)isible(true ; !rame.set*e!ault+lose,peration(JFrame.-./01,21+3,S- ; 4 ;

This script performs the following tasks 1) +hooses the colour we use to draw4 "g$d.set+olor(+olor.9.*):". 7fter, we draw circles and s;uares. $) +reates a filled ,&al shape and locates it on the board ) "g$d.fill,&al(!, !, !, !):" ) *raws the outline of an ,&al shape and locates it on the board ) "g$d.draw,&al(!, <!, !, !):" =) +reates a filled 9ectangle shape and locates it on the board ) "g$d.fill9ect(<!, !, !, !):" <) *raws the outline of an ,&al shape and locates it on the board ) "g$d.draw9ect(<!, <!, !, !):" >) *raws and .llipse and locates it on the board ) "g$d.draw(new .llipse$*.*ouble(!, 1!!, !, !)):"

Positioning in the canvas Coordinate !"! and !#! To draw something inside the can&as we should indicate in which position we are going to start painting. For this, each of the points in the can&as has an associated position (",y) being (!,!) the point of the top)left corner.

Chapter 2 $nimation o% a moving o&'ect


%n this chapter we will animate the mo&ement of a circle on our board. 5e achie&e this animation by creating the circle graphic in one position, then erasing it and drawing it in another position. This creates the appearance of a mo&ing circle. The position o% the circle The current position of our circle is stored in two properties called """ and "y". 5e also create a method called mo&eBall() which will increase in 1 both """ and "y", each time we call it. 1) 5e create two integer &alues ) one for " and one for y $) 5e create a function called mo&eBall which adds a &alue of 1 unit to each of the integers " and y. ) 5e call the paint method, and use it to draw the circle. %n the paint method we draw a circle with a diameter of ! pi"els in the position (",y) gi&en by the properties before described: "g$d.fill,&al(", y, !, !):". (5e also antialias the ball, to impro&e it8s appearance) =) 5e create the window frame and the board <) 7t the end of the main method we start an infinite cycle ) "while (true)" where we repeatedly call mo&eBall() to change the position of the circle, and then we call repaint() to draw the circle in the new position. This cycle is known as "?ame loop" and carries out two operations4 1.@pdate4 it updates of the physics of our world. %n our case the update is gi&en by the mo&eBall() method, which increases the """ and "y" in 1. 2.9ender4 it renders the current state of our world including the changes made before.
import import import import import java.awt.Grap5ics; java.awt.Grap5ics6*; java.awt.7endering8ints; javax.swing.JFrame; javax.swing.J9anel;

:Suppress;arnings(#serial# public class Game extends J9anel { int x " '; int ? " '; private void move$all( x " x @ >; ? " ? @ >; 4 {

:,verride public void paint(Grap5ics g super.paint(g ;

Grap5ics6* g6d " (Grap5ics6* g; g6d.set7endering8int(7endering8ints.A-B1C20/C3/CS/2G( 7endering8ints.)C3<-1C20/C3/CS1,2 ; g6d.!ill,val(x( ?( &'( &' ;

public static void main(String[] args t5rows /nterrupted-xception { JFrame !rame " new JFrame(#Dini 0ennis# ; Game game " new Game( ; !rame.add(game ; !rame.setSi%e(&''( E'' ; !rame.set)isible(true ; !rame.set*e!ault+lose,peration(JFrame.-./01,21+3,S- ; w5ile (true { game.move$all( ; game.repaint( ; 05read.sleep(>' ; 4 4 4

5hen we run this code we obtain a circle mo&ing across the can&as.

The instruction ) "g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)" softens the borders of the figures, as you can see in the following graphic. The circle on the left is without applying 71T%72%73 and the one on the right applying 71T%72%73.

Chapter *:1 Constraining the &all to the &oard


7ll the objects mo&ing in the screen ha&e their own characteristics such as the position (",y), speed and direction, etc. 7ll of these characteristics can be isolated in an object which we are going to call "3prite".

+peed and direction %n the last tutorial we got the ball (circle) to mo&e. %t mo&ed one pi"el downwards and to the right for e&ery iteration of the ?ame 2oop. 5hen it got to the border of the screen the ball continued, &anishing from the can&as. 1ow, we are going to make the ball bounce back once it touches the borders of the can&as, changing its direction.
import import import import import java.awt.Grap5ics; java.awt.Grap5ics6*; java.awt.7endering8ints; javax.swing.JFrame; javax.swing.J9anel;

:Suppress;arnings(#serial# public class Game extends J9anel { int int int int x " '; ? " '; xa " >; ?a " >;

private void move$all( { i! (x @ xa F ' xa " >; i! (x @ xa G get;idt5( H &' xa " H>; i! (? @ ?a F ' ?a " >; i! (? @ ?a G get8eig5t( H &' ?a " H>; x " x @ xa; ? " ? @ ?a; 4 :,verride public void paint(Grap5ics g { super.paint(g ; Grap5ics6* g6d " (Grap5ics6* g; g6d.set7endering8int(7endering8ints.A-B1C20/C3/CS/2G( 7endering8ints.)C3<-1C20/C3/CS1,2 ; g.!ill,val(x( ?( &'( &' ; 4 public static void main(String[] args t5rows /nterrupted-xception { JFrame !rame " new JFrame(#Dini 0ennis# ; Game game " new Game( ; !rame.add(game ;

!rame.setSi%e(&''( E'' ; !rame.set)isible(true ; !rame.set*e!ault+lose,peration(JFrame.-./01,21+3,S- ; w5ile (true { game.move$all( ; game.repaint( ; 05read.sleep(>' ; 4 4 4

%n this code we ha&e two more properties: ""a" and "ya", which represents the speed with which the ball is mo&ing. %f "aA1, the ball mo&es to the right, one pi"el e&ery round of the ?ame 2oop, if "aA)1, the ball mo&es to the left. %n the same way yaA1 mo&es the ball down and yaA)1 mo&es the ball up. This is done with the lines, "" A " B "a" and "y A y B ya" of the mo&eBall() method. Before running the pre&ious instructions, we &erify that the ball doesn6t go out of the borders of the can&as. For e"ample, when the ball gets to the right border, or when (" B "a C get5idth() ) !), what weDll do, is to change the direction of the mo&ement on the """ a"is or what is the same we assign )1 to ""a": ""a A )1".
private void move$all( { i! (x @ xa F ' xa " >; i! (x @ xa G get;idt5( H &' xa " H>; i! (? @ ?a F ' ?a " >; i! (? @ ?a G get8eig5t( H &' ?a " H>; x " x @ xa; ? " ? @ ?a;

.ach "if" statement delimits a border of the can&as.

Creation o% the !Ball! +prite


The idea is to create a class called Ball which isolates e&erything that has to do with the ball. %n the following code we can see how we e"tract all the code from the class ?ame$, which has to do with the ball, and we add it to our new class Ball.
pacIage com.eduEjava.minitennis&; import import import import import java.awt.Grap5ics; java.awt.Grap5ics6*; java.awt.7endering8ints; javax.swing.JFrame; javax.swing.J9anel;

:Suppress;arnings(#serial#

public class Game6 extends J9anel { $all ball " new $all(t5is ; private void move( { ball.move( ; 4 :,verride public void paint(Grap5ics g { super.paint(g ; Grap5ics6* g6d " (Grap5ics6* g; g6d.set7endering8int(7endering8ints.A-B1C20/C3/CS/2G( 7endering8ints.)C3<-1C20/C3/CS1,2 ; ball.paint(g6d ; 4 public static void main(String[] args t5rows /nterrupted-xception { JFrame !rame " new JFrame(#Dini 0ennis# ; Game6 game " new Game6( ; !rame.add(game ; !rame.setSi%e(&''( E'' ; !rame.set)isible(true ; !rame.set*e!ault+lose,peration(JFrame.-./01,21+3,S- ; w5ile (true { game.move( ; game.repaint( ; 05read.sleep(>' ; 4

4 4

The Ball sprite needs the reference to the ?ame object to obtain the borders of the can&as and in this way know when to change the direction. %n the mo&e() method the Ball class calls the methods game.get5idth() and game.getEeight().
pacIage com.eduEjava.minitennis&; import java.awt.Grap5ics6*; public class $all { int x " '; int ? " '; int xa " >; int ?a " >; private Game6 game; public $all(Game6 game { t5is.game" game; 4 void move( { i! (x @ xa xa i! (x @ xa xa i! (? @ ?a ?a F " G " F " ' >; game.get;idt5( H>; ' >;

H &'

i! (? @ ?a G game.get8eig5t( ?a " H>; x " x @ xa; ? " ? @ ?a; 4 public void paint(Grap5ics6* g { g.!ill,val(x( ?( &'( &' ; 4

H &'

%f we e"ecute ?ame$, we will obtain the same result as if we e"ecute the last ?ame &ersion. The con&enience of putting the code of the Ball into a 3prite type class becomes more clear when we include the rac;uet with a new 3prite, in the ne"t tutorial.

Chapter ,:1 Creation o% the !Ball! +prite


The use of "sprites" enables the isolation of parameters concerned with a particular object in the program. %n this case, the idea is to create a class called "Ball", which isolates e&erything that has to do with the ball. %n the following code we can see how we e"tract all the code which has to do with the ball from the class "?ame$", and we add it to our new class "Ball".
import import import import import java.awt.Grap5ics; java.awt.Grap5ics6*; java.awt.7endering8ints; javax.swing.JFrame; javax.swing.J9anel;

:Suppress;arnings(#serial# public class Game6 extends J9anel { $all ball " new $all(t5is ; private void move( { ball.move( ; 4 :,verride public void paint(Grap5ics g { super.paint(g ; Grap5ics6* g6d " (Grap5ics6* g; g6d.set7endering8int(7endering8ints.A-B1C20/C3/CS/2G( 7endering8ints.)C3<-1C20/C3/CS1,2 ; ball.paint(g6d ; 4 public static void main(String[] args t5rows /nterrupted-xception { JFrame !rame " new JFrame(#Dini 0ennis# ; Game6 game " new Game6( ; !rame.add(game ; !rame.setSi%e(&''( E'' ; !rame.set)isible(true ; !rame.set*e!ault+lose,peration(JFrame.-./01,21+3,S- ; w5ile (true { game.move( ; game.repaint( ; 05read.sleep(>' ; 4

4 4

The "Ball" sprite needs the reference to the "?ame" object to obtain the borders of the can&as, and in this way know when to change the direction. %n the mo&e() method the Ball class calls the methods "game.get5idth()" and "game.getEeight()".

import java.awt.Grap5ics6*; public class $all { int x " '; int ? " '; int xa " >; int ?a " >; private Game6 game; public $all(Game6 game { t5is.game" game; 4 void move( { i! (x @ xa xa i! (x @ xa xa i! (? @ ?a ?a i! (? @ ?a ?a x " x @ xa; ? " ? @ ?a; 4 public void paint(Grap5ics6* g { g.!ill,val(x( ?( &'( &' ; 4 F " G " F " G " ' >; game.get;idt5( H &' H>; ' >; game.get8eig5t( H &' H>;

%f we e"ecute "?ame$", we will obtain the same result as if we e"ecute the last "?ame" &ersion. The &alue of putting the code for the "Ball" into a 3prite type class becomes e&ident when we create a new 3prite for the "9ac;uet", in the ne"t +hapter.

Chapter -:1

.vents - /e#&oard input

%n order to play our game we will need to be able to control parameters and objects using the computer keyboard. To being with, we will take a break from working on our game and e"plain the capture of keyboard e&ents using a simple e"ample. /e#&oard listening e"ample To register information from the keyboard it is necessary to register an object which will register when a key is pressed. This object is known as a "0istener", and it will ha&e methods which will be called when someone presses a key. %n the following e"ample the 2istener is registered in the -Fanel (or Geyboard."ample) using the addGey2istener(Gey2istener listener) method.
import import import import java.awt.event.Ae?-vent; java.awt.event.Ae?3istener; javax.swing.JFrame; javax.swing.J9anel;

:Suppress;arnings(#serial# public class Ae?board-xample extends J9anel { public Ae?board-xample( { Ae?3istener listener " new D?Ae?3istener( ; addAe?3istener(listener ; setFocusable(true ; 4 public static void main(String[] args { JFrame !rame " new JFrame(#$oard# ; Ae?board-xample Ie?board-xample " new Ae?board-xample( ; !rame.add(Ie?board-xample ; !rame.setSi%e(6''( 6'' ; !rame.set)isible(true ; !rame.set*e!ault+lose,peration(JFrame.-./01,21+3,S- ; 4 public class D?Ae?3istener implements Ae?3istener { :,verride public void Ie?0?ped(Ae?-vent e { 4 :,verride public void Ie?9ressed(Ae?-vent e { ;

S?stem.out.println(#Ie?9ressed"#@Ae?-vent.getAe?0ext(e.getAe?+ode( 4 :,verride public void Ie?7eleased(Ae?-vent e {

S?stem.out.println(#Ie?7eleased"#@Ae?-vent.getAe?0ext(e.getAe?+ode( 4 4 4

%f you run this script, and then type on the computer keyboard, you will see the keys you press registered by the -a&a console.

Chapter 1:1 - +prites part 2


$dding the sprite !rac2uet! %n this chapter we will add a rac;uet using a 3prite called 9ac;uet. The rac;uet will mo&e to the left or to the right when we press the cursor keys, so our program has to read from the keyboard. 3ew +prite !4ac2uet! The first thing we ha&e to do is add a new property called "9ac;uet" in the class "?ame", where we keep the 9ac;uet sprite. %n the mo&e() method we add a call to rac;uet.mo&e() and in the paint() method a call to rac;uet.paint(). @ntil now, e&erything is similar to the sprite "Ball", but we ha&e to do something else because the position of the rac;uet responds to the keyboard.
import import import import import import import java.awt.Grap5ics; java.awt.Grap5ics6*; java.awt.7endering8ints; java.awt.event.Ae?-vent; java.awt.event.Ae?3istener; javax.swing.JFrame; javax.swing.J9anel;

:Suppress;arnings(#serial# public class Game extends J9anel { $all ball " new $all(t5is ; 7acJuet racJuet " new 7acJuet(t5is ; public Game( { addAe?3istener(new Ae?3istener( { :,verride public void Ie?0?ped(Ae?-vent e 4

:,verride public void Ie?7eleased(Ae?-vent e racJuet.Ie?7eleased(e ; 4 :,verride public void Ie?9ressed(Ae?-vent e racJuet.Ie?9ressed(e ; 4 {

4 ; setFocusable(true ;

private void move( { ball.move( ; racJuet.move( ; 4 :,verride public void paint(Grap5ics g { super.paint(g ; Grap5ics6* g6d " (Grap5ics6* g; g6d.set7endering8int(7endering8ints.A-B1C20/C3/CS/2G(

7endering8ints.)C3<-1C20/C3/CS1,2 ; ball.paint(g6d ; racJuet.paint(g6d ; 4 public static void main(String[] args t5rows /nterrupted-xception { JFrame !rame " new JFrame(#Dini 0ennis# ; Game game " new Game( ; !rame.add(game ; !rame.setSi%e(&''( E'' ; !rame.set)isible(true ; !rame.set*e!ault+lose,peration(JFrame.-./01,21+3,S- ; w5ile (true { game.move( ; game.repaint( ; 05read.sleep(>' ; 4

4 4

This is the code for the "Ball" class.


import java.awt.Grap5ics6*; public class $all { int x " '; int ? " '; int xa " >; int ?a " >; private Game game; public $all(Game game { t5is.game" game; 4 void move( { i! (x @ xa xa i! (x @ xa xa i! (? @ ?a ?a i! (? @ ?a ?a x " x @ xa; ? " ? @ ?a; F " G " F " G " ' >; game.get;idt5( H &' H>; ' >; game.get8eig5t( H &' H>;

public void paint(Grap5ics6* g { g.!ill,val(x( ?( &'( &' ; 4 4

There are no changes to the "Ball" class. 5e will now create the "9ac;uet" class.

import java.awt.Grap5ics6*; import java.awt.event.Ae?-vent; public class 7acJuet { int x " '; int xa " '; private Game game; public 7acJuet(Game game t5is.game" game; 4 {

public void move( { i! (x @ xa G ' KK x @ xa F game.get;idt5( HL' x " x @ xa; 4 public void paint(Grap5ics6* g { g.!ill7ect(x( &&'( L'( >' ; 4 public void Ie?7eleased(Ae?-vent e xa " '; 4 {

public void Ie?9ressed(Ae?-vent e { i! (e.getAe?+ode( "" Ae?-vent.)A13-F0 xa " H>; i! (e.getAe?+ode( "" Ae?-vent.)A17/G80 xa " >; 4 4

@nlike the "Ball" class, the "9ac;uet" class has no properties for the position "y" or for the speed "ya", because the rac;uet doesn6t change its &ertical position: it will only mo&e left or right, ne&er up or down. 5hen we run the e"ample we can see that the ball mo&es bouncing against the borders and the rac;uet mo&es, when we press the direction keys. Eowe&er, when the ball meets the rac;uet, it goes right through rather than colliding. %n the ne"t tutorial we will see how to make the ball bounce on the rac;uet.

Chapter 5:1 - Collision 6etection


The ne"t thing we need to achie&e in our game is to ha&e the ball "collide" with the "9ac;uet", so that we can use it to play the game. %n this chapter we will learn how to detect when one sprite collides with another. %n our game we will make the ball bounce on the rac;uet. +prite collision To detect the collision between the 8ball8 and the 8rac;uet8 we will use rectangles. %n the case of the ball we will use a s;uare around the ball, as you can see in the figure $.

The class ja&a.awt.9ectangle has an "intersects" method (9ectangle r) which returns "true" when two rectangles occupy the same space, like in the case of the figure or =. This method is not ;uite e"act, because as you can see in the figure =, the ball doesn6t touch the rac;uet, but for our e"ample it it more than enough. Below we can see the 4ac2uet class, with the only difference that we ha&e added a getBounds() method, which returns a rectangle type of object, indicating the position of the rac;uet. This method will be used by the sprite "Ball", to know the position of the rac;uet and in this way to detect the collision.

import java.awt.Grap5ics6*; import java.awt.7ectangle; import java.awt.event.Ae?-vent; public class 7acJuet { private static !inal int B " &&'; private static !inal int ;/*08 " L'; private static !inal int 8-/G80 " >'; int x " '; int xa " '; private Game game; public 7acJuet(Game game { t5is.game " game; 4 public void move( { i! (x @ xa G ' KK x @ xa F game.get;idt5( x " x @ xa; 4 public void paint(Grap5ics6* g { g.!ill7ect(x( B( ;/*08( 8-/G80 ; 4 public void Ie?7eleased(Ae?-vent e xa " '; 4 { H ;/*08

public void Ie?9ressed(Ae?-vent e { i! (e.getAe?+ode( "" Ae?-vent.)A13-F0 xa " H>; i! (e.getAe?+ode( "" Ae?-vent.)A17/G80 xa " >; 4 public 7ectangle get$ounds( { return new 7ectangle(x( B( ;/*08( 8-/G80 ; 4 public int get0opB( return B; 4 4 {

Eere is the Ball class code4)


import java.awt.Grap5ics6*; import java.awt.7ectangle; public class $all { private static !inal int */CD-0-7 " &'; int x " '; int ? " '; int xa " >; int ?a " >; private Game game;

public $all(Game game { t5is.game" game; 4 void move( { i! (x @ xa F ' xa " >; i! (x @ xa G game.get;idt5( H */CD-0-7 xa " H>; i! (? @ ?a F ' ?a " >; i! (? @ ?a G game.get8eig5t( H */CD-0-7 game.game,ver( ; i! (collision( { ?a " H>; ? " game.racJuet.get0opB( H */CD-0-7; 4 x " x @ xa; ? " ? @ ?a; 4 private boolean collision( { return game.racJuet.get$ounds( .intersects(get$ounds( 4 public void paint(Grap5ics6* g { g.!ill,val(x( ?( */CD-0-7( */CD-0-7 ; 4 public 7ectangle get$ounds( { return new 7ectangle(x( ?( */CD-0-7( */CD-0-7 ; 4 ;

%f we run the e"ample we can see the ball and paddle mo&ing.

Chapter 7
$dding sound to our game
7 game with no sound is not complete. %n this tutorial we will add background music, the noise of the bouncing of the ball and a "?ame ,&er" with funny &oice at the end of the game. To a&oid copyright problems we are going to create the sounds oursel&es.

Creating sounds
To create the sounds % looked up in ?oogle to find a "free audio editor" and % found http4HHfree)audio)editor.comH. % ha&e to say that the free &ersion of this product is powerful and easy to use.

5ith this editor % ha&e created the archi&es4 back.wa&, gameo&er.wa& y ball.wa&. %n the youtube &ideo you can see how % did it and you can create them yoursel&es. Iou can also download those three and use them, which % now declare them copyright free. 5hat you ha&e to do is copy these archi&es to the com.edu=ja&a.minitennisJ package.

Pla# sounds using $udioClip


To play these sound archi&es we will use the 7udio+lip class. 5e will create 7udio+lip objects, using the static method4 7pplet.new7udio+lip(@92 url) of the 7pplet class. This method needs un @92 object which indicates where is the audio archi&e we are wanting to load and play. The following instruction creates a new @92 object, using a location in %nternet4
<73 url " new <73(#5ttpMNNwww.eduEjava.comNesNgameNsoundNbacI.wav# ;

The ne"t instruction uses a directory inside the local archi&e system4
<73 url " new <73(#!ileMN+MN<sersN-liNworIspaceNminitennisNsrcNcomNeduEjavaNminitennisONbacI. wav# ;

5e will look for our archi&e using the classpath. This is the system which uses ja&a to load the classes or more specifically the K.class archi&es which define the classes of the program. To obtain an @92 from the classpath we use the get9esource(3tring name) method of the +lass class, where "name" is the name of the archi&e we want to obtain. Below we can see two ways of how to obtain the @92 of the "back.wa&" archi&e, which is located in the same package as the 3oundTest class or what is the same, in the same directory as the 3oundTest.class archi&e.
<73 url " Sound0est.class.get7esource(#bacI.wav# ; <73 url " new Sound0est( .get+lass( .get7esource(#bacI.wav# ;

Both "3oundTest.class" and "new 3oundTest().get+lass()" gi&es us a class object which has the get9esource method we want to use.

% ha&e created the 3oundTest class to show you how does 7udio+lip work but it isn6t necessary for our game. Below we can see the 3oundTest source code complete4
pacIage com.eduEjava.minitennisO; import java.applet.Cpplet; import java.applet.Cudio+lip; import java.net.<73; public class Sound0est { public static void main(String[] args NN NN NN NN NN NN NN NN t5rows -xception {

S?stem.out.println(#># ; <73 url " new <73(#5ttpMNNwww.eduEjava.comNsoundNbacI.wav# ; S?stem.out.println(#6# ; Cudio+lip clip " Cpplet.newCudio+lip(url ; S?stem.out.println(#&# ; clip.pla?( ; S?stem.out.println(#E# ; 05read.sleep(>''' ;

NN <73 url " new <73( NN #!ileMN+MN<sersN-liNworIspaceNminitennisNsrcNcomNeduEjavaNminitennisONbacI.wav# ; <73 url " Sound0est.class.get7esource(#bacI.wav# ; Cudio+lip clip " Cpplet.newCudio+lip(url ; Cudio+lip clip6 " Cpplet.newCudio+lip(url ; clip.pla?( ; 05read.sleep(>''' ; clip6.loop( ; 05read.sleep(6'''' ; clip6.stop( ; S?stem.out.println(#end# ; 4 4

This is the way to obtain the back.wa& archi&e from the classpath. The classpath is the directories and archi&es K.jar collection from where our program can read the classes (K.class archi&es). ,ne ad&antage of this metodology is that we only ha&e to indicate the position of the archi&e regarding the class which uses it. %n our case as it is in the same package we only ha&e to write "back.wa&". 7nother ad&antage is that the sound archi&es can be included in the K.jar archi&e. 5e6ll see more about K.jar archi&es later on. ,nce we ha&e the @92 object we can create 7udio+lip objects using 7pplet.new7udio+lip(url).
Cudio+lip clip " Cpplet.newCudio+lip(url ; Cudio+lip clip6 " Cpplet.newCudio+lip(url ;

The 7udio+lip object has a play() method which starts an independent thread which plays the audio of the archi&e just once. To play the audio more than once we can use the loop() method of 7udio+lip which will play the sound repeatedly until the stop() method is called o&er the same 7udio+lip object. Two audio+lips can play at the same time. %n the e"ample % create two

audio+lips with the same audio4 clip and clip$. % play "clip" with play, % wait a second Thread.sleep(1!!!) and play clip$ with loop. The result is a mi"ture of the two audios. 2astly, after $! seconds Thread.sleep($!!!!) % call clip$.stop() and % stop the repetition of clip$.

Chapter 8
Creating a +ound class %or our game
To keep the audioclips of our game we create a 3ound class, which we6ll ha&e a constant with an audioclip for each of the sounds we use. These constants are public so that any object which ha&e access to them, can play them. For e"ample, in the Ball class we can play the sound of the bouncing of the ball using 3ound.B722.play() at the moment we know the ball changes its direction.

pacIage com.eduEjava.minitennisO; import java.applet.Cpplet; import java.applet.Cudio+lip; public class Sound { public static !inal Cudio+lip $C33 " Cpplet.newCudio+lip(Sound.class.get7esource(#ball.wav# ; public static !inal Cudio+lip GCD-,)-7 " Cpplet.newCudio+lip(Sound.class.get7esource(#gameover.wav# public static !inal Cudio+lip $C+A " Cpplet.newCudio+lip(Sound.class.get7esource(#bacI.wav# ; 4

The audioclips objects will be created when the 3ound class loads, the first time someone uses the 3oung class. From this moment on, they will be re) used. 2et6s now look at the modifications in the ?ame class4
pacIage com.eduEjava.minitennisO; import import import import import import import import java.awt.Grap5ics; java.awt.Grap5ics6*; java.awt.7endering8ints; java.awt.event.Ae?-vent; java.awt.event.Ae?3istener; javax.swing.JFrame; javax.swing.J,ption9ane; javax.swing.J9anel;

:Suppress;arnings(#serial# public class Game extends J9anel { $all ball " new $all(t5is ; 7acJuet racJuet " new 7acJuet(t5is ; public Game( { addAe?3istener(new Ae?3istener( { :,verride public void Ie?0?ped(Ae?-vent e 4

:,verride public void Ie?7eleased(Ae?-vent e racJuet.Ie?7eleased(e ; 4

4 ; setFocusable(true ; Sound.$C+A.loop( ; 4 private void move( { ball.move( ; racJuet.move( ; 4

:,verride public void Ie?9ressed(Ae?-vent e racJuet.Ie?9ressed(e ; 4

:,verride public void paint(Grap5ics g { super.paint(g ; Grap5ics6* g6d " (Grap5ics6* g; g6d.set7endering8int(7endering8ints.A-B1C20/C3/CS/2G( 7endering8ints.)C3<-1C20/C3/CS1,2 ; ball.paint(g6d ; racJuet.paint(g6d ; 4 public void game,ver( { Sound.$C+A.stop( ; Sound.GCD-,)-7.pla?( ; J,ption9ane.s5owDessage*ialog(t5is( #Game ,ver#( #Game ,ver#( J,ption9ane.B-S12,1,90/,2 ; S?stem.exit(C$,70 ; 4 public static void main(String[] args t5rows /nterrupted-xception { JFrame !rame " new JFrame(#Dini 0ennis# ; Game game " new Game( ; !rame.add(game ; !rame.setSi%e(&''( E'' ; !rame.set)isible(true ; !rame.set*e!ault+lose,peration(JFrame.-./01,21+3,S- ; w5ile (true { game.move( ; game.repaint( ; 05read.sleep(>' ; 4 4 4

%n the last line of the ?ame class constructor, we add 3ound.B7+G.loop(), which will initiate the playing of our background music and will play repeatedly till it gets to the game,&er() method, where we stop the background music with 3ound.B7+G.stop(). 7fter 3ound.B7+G.stop() and before the popup, we inform that the game is o&er playing "?ame ,&er" 3ound.?7L.,'.9.play(). %n the Ball class, we change the mo&e() method so that it plays 3ound.B722 when the ball bounces.
pacIage com.eduEjava.minitennisO; import java.awt.Grap5ics6*; import java.awt.7ectangle;

public class $all { private static !inal int */CD-0-7 " &'; int x " '; int ? " '; int xa " >; int ?a " >; private Game game; public $all(Game game { t5is.game " game; 4 void move( { boolean c5ange*irection " true; i! (x @ xa F ' xa " >; else i! (x @ xa G game.get;idt5( H */CD-0-7 xa " H>; else i! (? @ ?a F ' ?a " >; else i! (? @ ?a G game.get8eig5t( H */CD-0-7 game.game,ver( ; else i! (collision( { ?a " H>; ? " game.racJuet.get0opB( H */CD-0-7; 4 else c5ange*irection " !alse; i! (c5ange*irection Sound.$C33.pla?( ; x " x @ xa; ? " ? @ ?a; 4 private boolean collision( { return game.racJuet.get$ounds( .intersects(get$ounds( 4 public void paint(Grap5ics6* g { g.!ill,val(x( ?( */CD-0-7( */CD-0-7 ; 4 public 7ectangle get$ounds( { return new 7ectangle(x( ?( */CD-0-7( */CD-0-7 ; 4 ;

5hat % did in mo&e() is add a change*irection &ariable, which % initiali#e to true. 7dding an "else" to e&ery "if" and writing a change*irection A false which only will runs if none of the conditions in the "if" are true, we will know if the ball has bounced. %f the ball has bounced, change*irection will be true and 3ound.B722.play() will be e"ecuted.

Chapter 19
$dding punctuation and speed increase
.&ery game needs a measurement of success. %n our case we will include in the top left corner of the screen the punctuation, which will be the number of times we are able to hit the ball with the rac;uet. ,n the other hand, the game should be a bit more complicated each time, so that the player doesn6t get bored. The mo&ing objects of the game are the ball and the rac;uet. +hanging the speed of these two objects, we will modify the speed of the game. 5e are going to include a property called "speed" in the ?ame class to keep the speed of the game. The property "speed" will be 1 initially, and it will increase each time we hit the ball with the rac;uet. For the punctuation we need another property to increase each time we hit the ball. %nstead of creating a new property, % am going to re)use "speed". The only incon&enience is that the punctuations start in ! and not in 1 as "speed". The solution % thought of was, add a get3core() method which returns the &alue of speed, minus 1.
private int getScore( { return speed H >; 4

2et6s see what are the modifications made to the ?ame class4
pacIage com.eduEjava.minitennisP; import import import import import import import import import import java.awt.+olor; java.awt.Font; java.awt.Grap5ics; java.awt.Grap5ics6*; java.awt.7endering8ints; java.awt.event.Ae?-vent; java.awt.event.Ae?3istener; javax.swing.JFrame; javax.swing.J,ption9ane; javax.swing.J9anel;

:Suppress;arnings(#serial# public class Game extends J9anel { $all ball " new $all(t5is ; 7acJuet racJuet " new 7acJuet(t5is ; int speed " >; private int getScore( { return speed H >; 4 public Game( { addAe?3istener(new Ae?3istener( { :,verride public void Ie?0?ped(Ae?-vent e 4

:,verride public void Ie?7eleased(Ae?-vent e racJuet.Ie?7eleased(e ; 4 :,verride public void Ie?9ressed(Ae?-vent e racJuet.Ie?9ressed(e ; 4 {

4 ; setFocusable(true ; Sound.$C+A.loop( ; 4 private void move( { ball.move( ; racJuet.move( ; 4

:,verride public void paint(Grap5ics g { super.paint(g ; Grap5ics6* g6d " (Grap5ics6* g; g6d.set7endering8int(7endering8ints.A-B1C20/C3/CS/2G( 7endering8ints.)C3<-1C20/C3/CS1,2 ; ball.paint(g6d ; racJuet.paint(g6d ; g6d.set+olor(+olor.G7CB ; g6d.setFont(new Font(#)erdana#( Font.$,3*( &' ; g6d.drawString(String.value,!(getScore( ( >'( &' ;

public void game,ver( { Sound.$C+A.stop( ; Sound.GCD-,)-7.pla?( ; J,ption9ane.s5owDessage*ialog(t5is( #?our score isM # @ getScore( ( #Game ,ver#( J,ption9ane.B-S12,1,90/,2 ; S?stem.exit(C$,70 ; 4 public static void main(String[] args t5rows /nterrupted-xception { JFrame !rame " new JFrame(#Dini 0ennis# ; Game game " new Game( ; !rame.add(game ; !rame.setSi%e(&''( E'' ; !rame.set)isible(true ; !rame.set*e!ault+lose,peration(JFrame.-./01,21+3,S- ; w5ile (true { game.move( ; game.repaint( ; 05read.sleep(>' ; 4

4 4

To paint the punctuation in the top left corner, we add the following code at the end of the paint method4
g6d.set+olor(+olor.G7CB ;

g6d.setFont(new Font(#)erdana#( Font.$,3*( &' ; g6d.drawString(String.value,!(getScore( ( >'( &' ;

%n the first line we choose the color: grey, in the second line the type of letter: 'erdana, bold type of ! pi"eles and finally the position (",y) A (1!, !), where we paint the punctuation. %n the game,&er() method, we modify the second parameter to show the punctuation achie&ed4
getScore( ( J,ption9ane.s5owDessage*ialog(t5is( #?our score isM # @ #Game ,ver#( J,ption9ane.B-S12,1,90/,2 ;

The mo&e() method of the Ball class has been modified to take into account the new property "game.speed". 5hen the ball changed direction, the properties of speed ""a" and "ya" were changed to 1 or )1. 1ow, taking into account speed, these properties, change to game.speed or )game.speed. 5e ha&e also added in the conditional if(collision()), that "speed" increases "game.speedBB".
pacIage com.eduEjava.minitennisP; import java.awt.Grap5ics6*; import java.awt.7ectangle; public class $all { private static !inal int */CD-0-7 " &'; int x " '; int ? " '; int xa " >; int ?a " >; private Game game; public $all(Game game { t5is.game " game; 4 void move( { boolean c5ange*irection " true; i! (x @ xa F ' xa " game.speed; else i! (x @ xa G game.get;idt5( H */CD-0-7 xa " Hgame.speed; else i! (? @ ?a F ' ?a " game.speed; else i! (? @ ?a G game.get8eig5t( H */CD-0-7 game.game,ver( ; else i! (collision( { ?a " Hgame.speed; ? " game.racJuet.get0opB( H */CD-0-7; game.speed@@; 4 else c5ange*irection " !alse; i! (c5ange*irection Sound.$C33.pla?( ; x " x @ xa; ? " ? @ ?a;

private boolean collision( { return game.racJuet.get$ounds( .intersects(get$ounds( 4 public void paint(Grap5ics6* g { g.!ill,val(x( ?( */CD-0-7( */CD-0-7 ; 4 public 7ectangle get$ounds( { return new 7ectangle(x( ?( */CD-0-7( */CD-0-7 ; 4

Below we can see the class 9ac;uet4 package com.edu=ja&a.minitennisM:


import java.awt.Grap5ics6*; import java.awt.7ectangle; import java.awt.event.Ae?-vent; public class 7acJuet { private static !inal int B " &&'; private static !inal int ;/08 " L'; private static !inal int 8-/G80 " >'; int x " '; int xa " '; private Game game; public 7acJuet(Game game { t5is.game " game; 4 public void move( { i! (x @ xa G ' KK x @ xa F game.get;idt5( x " x @ xa; 4 public void paint(Grap5ics6* g { g.!ill7ect(x( B( ;/08( 8-/G80 ; 4 public void Ie?7eleased(Ae?-vent e xa " '; 4 { H ;/08

public void Ie?9ressed(Ae?-vent e { i! (e.getAe?+ode( "" Ae?-vent.)A13-F0 xa " Hgame.speed; i! (e.getAe?+ode( "" Ae?-vent.)A17/G80 xa " game.speed; 4 public 7ectangle get$ounds( { return new 7ectangle(x( B( ;/08( 8-/G80 ; 4 public int get0opB( { return B H 8-/G80;

4 4

Eere, the modification is similar to Ball. %n the keyFressed(Gey.&ent e) method, the modification of "speed" "a changes from )1 and 1 to )game.speed and game.speed. 1ote4 "-a&a Beans" standard says that the access to the property "game.speed" should be done using a method in this way "game.get3peed()". The direct access to a property is not considered correct in business ja&a. 3trangely enough, in the area of the games de&elopment it is &ery common and it is justified because of its efficiency. This is &ery important in mobile programming due to the shortage of resources.

Chapter 11
Creating an e"ecuta&le 'ar %ile and what is a virtual 'ava machine
%n this tutorial we will see how to create an e"ecutable file for a ja&a application, in particular for our game. 7 ja&a program needs a &irtual machine to be e"ecuted. Below we will e"plain what is a &irtual ja&a machine and how it works.

Java :irtual ;achine (J:;)


Before -a&a, we wrote a program in a high le&el programming language like + or Fascal and then we had to translate it to machine language with a compiler. The "machine language" or "machine code" is the language which the machine understands. 7 machine with 5indows and a Lac of 7pple talk different machine language. That is why we need a different compiler for each machine. %n the case of ja&a, when we use the compiler, we don6t obtain machine code. 5e obtain a code called bytecode which doesn6t e"ecute directly on a real machine. This bytecode can only e"ecute on a &irtual machine. 7 &irtual machine is a program which works as if it was a machine. For each different operati&e system there will be a specific &irtual machine program but the bytecode e"ecuted will be the same.

7s the bytecode is potentially the same, it can be e"ecuted in any operati&e system when there is an implementation of the -'L for that operati&e system. The following famous sentence is based in this idea4 "5rite once, run anywhere" (5,97).

Compilation and e"ecution in 'ava


There are two installation &ersions for ja&a for each operati&e system -9. and -*G. -9. -a&a 9untime .n&ironment, is a reduced &ersion which contains the -'L, but doesn6t include the ja&a compilator. -*G -a&a *e&elopment Git contains the -'L, the ja&a compilator and other aditional tools for the de&elopment of ja&a aplications. %f you don6t ha&e the -*G &ersion installed, you should install it to be able to continue with this tutorial. %f we ha&e the -*G installed, we ha&e a directory with all the files which make up the ja&a platform. This directory is known as ja&a Eome or -7'70E,L.. %n my case it is "+4NFrogram Files ("M>)N-a&aNjdk1.>.!0$J". %nside -7'70E,L. there is a folder bin which contains the e"ecutable with the compilator4 ja&ac.e"e and the &irtual machine4 ja&a.e"e. To show how these programs work, we are going to create a file called Eello5orld.ja&a in a directory +4Ntestja&a with the following content4
import javax.swing.J,ption9ane; public class 8ello;orld { public static void main(String[] args { S?stem.out.println(#8ello ;orld ; # ; J,ption9ane.s5owDessage*ialog(null( #8ello ;orld# ; 4 4

5e open a command window, we e"ecute "cd +4Ntestja&a" to locate us in the directory where our ja&a file is and to compilate we e"ecute4
javac 8ello;orld.java or #+MQ9rogram Files (xPL QJavaQjdI>.L.'16OQbinQjavac# 8ello;orld.java

7s a result we can see that a new file Eellow5orld.class has been created with the bytecode. 5e can e"ecute this bytecode with the following instruction4
java 8ello;orld or #+MQ9rogram Files (xPL QJavaQjdI>.L.'16OQbinQjava# 8ello;orld

7 ja&a program is made up of se&eral ja&a files and conse;uently se&eral K.class files. 5e also ha&e the resources files, as for e"ample, the sounds of our aplication. -a&a allows us to pack an aplication with all the files we6&e talked about before, in a K.jar file.

J$4 %ile
7 jar file is a compressed file with the #ip algorithm of compression, which can contain4 1.The K.class files which are generated from the compilation of the K.ja&a files, which make up our application. $.The resources files needed by our application (For e"ample the sound file K.wa&) .,ptionally, we can include the source code files K.ja&a =.,ptionally, we can ha&e a configuration file "L.T7)%1FHL71%F.3T.LF".

Creating an e"ecuta&le J$4 %ile


For the jar file to be e"ecutable, we ha&e to include in the L71%F.3T.LF file, a line indicating the class which contains the static method main() which will be used to start the aplication. %n our last e"ample it would be like this4
DainH+lassM 8ello;orld

%t is important to highlight, that at the end of the line, we ha&e to add a carriage return so that it works. % in&ite you to create a testja&a.#ip file containing a Eello5orld.class file, the L.T7)%1F directory and inside it a L71%F.3T.LF file with the Lain)+lass line4 Eello5orld. For this you can use the 5in#ip or 5in979 programs, which you can download free (look for it in ?oogle).

,nce you ha&e created the testja&a.#ip file, we change its name for testja&a.jar and we e"ecute it from the command line4

5e can also e"ecute it with a double click on the -79 file.

<ow to create an e"ecuta&le J$4 %ile %rom eclipse


To create an e"ecutable -79 we go to File)."port and select 9unnable -79 file

7s we can see below, in "2aunch configuration" we select the one we use to e"ecute the final &ersion of our application and in "."port destination" we indicate where we want to sa&e our -79 and with what name4

%f ja&a is correctly installed o&er 5indows, a doble click on minitennis.jar would be enough to e"ecute our application.

0oo=ing at minitennis 'ar


%f we decompress our minitennis.jar file, we will find the K.class files which make up our game. This files are inside the directory tree with the names of the ja&a packages which contain the classes. %nside L.T7)%1FHL71%F.3T.LF, we can see in the last line, how the game must start with the main() method of the ?ame class, which is in the com.edu=ja&a.minitennisM package.

.clipse does a great job, compiling, e"ecuting and creating -79 files, but is good to understand that eclipse uses the ja&a installation in a similar way as in our Eello5orld e"ample.