Jump to content

Game - A simple Pong

- - - - -

  • Please log in to reply
18 replies to this topic

#1
eard

eard

    Newbie

  • Members
  • Pip
  • 2 posts
Hello guys, this is my first thread.
And i will show you how to make a simple Pong game. I say simple because i made it in less than 40 min.
First of all, like i'm Mexican, all my variables will be in Spanish, but i will write comments in English about what do each part of code.
Here we go

Points to consider
The Pong game that we are going to make in this tuto will be for 2 players, P1 vs P2. The keys to move the player one will be 'W' and 'S', and for player two will be up arrow and down arrow.
Also, when a player reach to 6 points, the game will end. You can change this value if you want

First Step

We'll create the "container window". This class will just listen the keys pressed and released from the keyboard and send them to the game class, that will be created later. Also, in this class (Main) we'll create a new panel from the game class.
Create a new class and name it like do you prefer. I will call it Main.
import javax.swing.*;

import java.awt.*;

import java.awt.event.*;


public class Main extends JFrame {


	private static final long serialVersionUID = 1L; // Eclipse added this automatically


	private JPanel jContentPane = null;

	

	private PanelPelota panel = null; // This is the panel of the game class

	

	private PanelPelota getPanel() {

		if (panel == null) {

			panel = new PanelPelota(); // The panel is created

		}

		return panel;

	}


	/**

	 * This is the default constructor

	 */

	public Main() {

		super();

		initialize();

        // Listeners for the keyboard

        this.addKeyListener(new KeyAdapter() {

        	//Method for the key pressed

            public void keyPressed(KeyEvent evt) {

                formKeyPressed(evt);

            }

            // Method for the key released

            public void keyReleased(KeyEvent evt) {

                formKeyReleased(evt);

            }

        });

		

	}

	

    //	Here i'm stating the method that will send the key pressed to the game class

	private void formKeyPressed(KeyEvent evt)

    {

        panel.keyPressed(evt);

    }

    

    //	Here i'm stating the method that will send the key released to the game class

    private void formKeyReleased(KeyEvent evt)

    {

        panel.keyReleased(evt);

    }


	/**

	 * This method initializes this

	 * 

	 * @return void

	 */

	private void initialize() {

		this.setResizable(false);

		this.setBounds(new Rectangle(312, 184, 250, 250)); // Position on the desktop

		this.setMinimumSize(new Dimension(250, 250));

		this.setMaximumSize(new Dimension(250, 250));

		this.setContentPane(getJContentPane());

		this.setTitle("Pong");

	}


	/**

	 * This method initializes jContentPane

	 * 

	 * @return javax.swing.JPanel

	 */

	private JPanel getJContentPane() {

		if (jContentPane == null) {

			jContentPane = new JPanel();

			jContentPane.setLayout(new BorderLayout());

			jContentPane.add(getPanel(), BorderLayout.CENTER);

		}

		return jContentPane;

	}

	

	public static void main(String[] args) {

		// TODO Auto-generated method stub

		SwingUtilities.invokeLater(new Runnable() {

			public void run() {

				Main thisClass = new Main();

				thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

				thisClass.setVisible(true);

			}

		});

	}

}

Second Step
Now that we have the container window, we will create the game class. In this class we are going to draw the ball and the "ships" of the players.
I'll create a bew class called PanelPelota, Pelota in English is Ball.
import java.awt.*;

import java.awt.event.KeyEvent;

import javax.swing.*;



public class PanelPelota extends JPanel implements Runnable {

	

	private static final long serialVersionUID = 1L;

        // Positions on X and Y for the ball, player 1 and player 2

	private int pelotaX = 10, pelotaY = 100, jug1X=10, jug1Y=100, jug2X=230, jug2Y=100;

	Thread hilo;

	int derecha=5; // to the right

	int izquierda= -5; //to the left

	int arriba=5; // upward

	int abajo= -5; // down

	int ancho, alto; // Width and height of the ball

	// Scores

	int contPlay1=0, contPlay2=0;

	boolean player1FlagArr,player1FlagAba, player2FlagArr, player2FlagAba;

	boolean juego, gameOver;

	

	public PanelPelota(){

		juego=true;

		hilo=new Thread(this);

		hilo.start();

	}

	

	// Draw ball and ships

	public void paintComponent(Graphics gc){

		setOpaque(false);

		super.paintComponent(gc);

		

		// Draw ball

		gc.setColor(Color.black);

		gc.fillOval(pelotaX, pelotaY, 8,8);

		

		// Draw ships

		gc.fillRect(jug1X, jug1Y, 10, 25);

		gc.fillRect(jug2X, jug2Y, 10, 25);

		

		//Draw scores

		gc.drawString("Jugador1: "+contPlay1, 25, 10);

		gc.drawString("Jugador2: "+contPlay2, 150, 10);

		

		if(gameOver)

			gc.drawString("Game Over", 100, 125);

	}

	

	// Positions on X and Y for the ball

	public void dibujarPelota (int nx, int ny)

	{

		pelotaX= nx; 

		pelotaY= ny; 

		this.ancho=this.getWidth();

		this.alto=this.getHeight();

		repaint();

	}

	

    // Here we receive from the game container class the key pressed

	public void keyPressed(KeyEvent evt)

    {

        switch(evt.getKeyCode())

        {

            // Move ship 1

            case KeyEvent.VK_W :

            	player1FlagArr = true;

            	break;

            case KeyEvent.VK_S : 

            	player1FlagAba = true;

            	break;

                        

            // Move ship 2

            case KeyEvent.VK_UP:

            	player2FlagArr=true;

            	break;

           case KeyEvent.VK_DOWN:

        	   player2FlagAba=true;

            	break;

        }

    }

	

    //	Here we receive from the game container class the key released

    public void keyReleased(KeyEvent evt)

    {

        switch(evt.getKeyCode())

        {

	        // Mover Nave1

	        case KeyEvent.VK_W :

	        	player1FlagArr = false;

	        	break;

	        case KeyEvent.VK_S : 

	        	player1FlagAba = false;

	        	break;

	                    

	        // Mover nave 2

	        case KeyEvent.VK_UP:

	        	player2FlagArr=false;

	        	break;

	        case KeyEvent.VK_DOWN:

	    	   player2FlagAba=false;

	        	break;

        }

    }

    

    // Move player 1

    public void moverPlayer1()

    {

        if (player1FlagArr == true && jug1Y >= 0)

            jug1Y += abajo;

        if (player1FlagAba == true && jug1Y <= (this.getHeight()-25))

            jug1Y += arriba;

        dibujarPlayer1(jug1X, jug1Y);

    }

    

    // Move player 2

    public void moverPlayer2()

    {

        if (player2FlagArr == true && jug2Y >= 0)

            jug2Y += abajo;

        if (player2FlagAba == true && jug2Y <= (this.getHeight()-25))

            jug2Y += arriba;

        dibujarPlayer2(jug2X, jug2Y);

    }

    

    // Position on Y for the player 1

    public void dibujarPlayer1(int x, int y){

    	this.jug1X=x;

    	this.jug1Y=y;

    	repaint();

    }

    // Position on Y for the player 2   

    public void dibujarPlayer2(int x, int y){

    	this.jug2X=x;

    	this.jug2Y=y;

    	repaint();

    }

	

	public void run() {

		// TODO Auto-generated method stub

		boolean izqDer=false;

		boolean arrAba=false;

		

		while(true){

			

			if(juego){

			

            // The ball move from left to right

           	if (izqDer) 

			{

				// a la derecha

				pelotaX += derecha;

				if (pelotaX >= (ancho - 8))

                    izqDer= false;

			}

			else

			{

				// a la izquierda

				pelotaX += izquierda;

				if ( pelotaX <= 0)

                    izqDer =  true;

			}

           	

           	

            // The ball moves from up to down

           	if (arrAba) 

			{

				// hacia arriba

				pelotaY += arriba;

				if (pelotaY >= (alto - 8))

                    arrAba= false;

					

			}

			else

			{

				// hacia abajo

				pelotaY += abajo;

				if ( pelotaY <= 0)

					arrAba =  true;

			}

           	dibujarPelota(pelotaX, pelotaY);

           	

            // Delay

			try 

			{

				Thread.sleep(50);

			}

			catch(InterruptedException ex)

			{

				

			}

			

			// Move player 1

			moverPlayer1();

			

            // Move player 2

			moverPlayer2();

			

            // The score of the player 1 increase

			if (pelotaX >= (ancho - 8))

				contPlay1++;

                			

            // The score of the player 2 increase

			if ( pelotaX == 0)

				contPlay2++;

                            			

			// Game over. Here you can change 6 to any value

                        // When the score reach to the value, the game will end

			if(contPlay1==6 || contPlay2==6){

				juego=false;

			    gameOver=true;

			}

			

			// The ball stroke with the player 1

			if(pelotaX==jug1X+10 && pelotaY>=jug1Y && pelotaY<=(jug1Y+25))

				izqDer=true;

			

            // The ball stroke with the player 2

			if(pelotaX==(jug2X-5) && pelotaY>=jug2Y && pelotaY<=(jug2Y+25))

				izqDer=false;

			}

		}

	}

	

}

So, now we save and compile both classes and run the Main class.
So, its play time.
Like you will see, there is a bug with the game. When it starts, both scores are in 1, i didn't try to fix it but if somebody fix it i really will appreciate if you post how :D

I hope you like my first thread.
Feedback will be appreciated.
Suggestions, comments are welcome

P.D. Sorry for my bad English xS

#2
WingedPanther

WingedPanther

    A spammer's worst nightmare

  • Moderators
  • 16,831 posts
  • Location:Upstate, South Carolina
  • Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
  • Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others
Nice job. +rep
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

#3
Egz0N

Egz0N

    Writes binary right handed and hex left handed

  • Members
  • PipPipPipPipPipPipPipPipPip
  • 4,034 posts
nice job ... +rep :)

#4
dragon_breath

dragon_breath

    Newbie

  • Members
  • Pip
  • 1 posts
Your 1-1 score bug is bcoz of two things:
1) Player1 score:
The width of the panel remains zero (i'm assuming its zero but the width value is the cause of the bug) till end of the delay. So your 'ancho' remains zero and (ancho - 8) is negative so 'pelotaX'(which is zero) is greater and Player1 score gets incremented to 1. Change 'ancho' to 'getWidth()'.

2) Player2 score:
i) The y co-ordinate of the ball (pelotaY) has the same value as the jug1Y.The first loop in the run method reduces your 'pelotaY' by 5 and so 'pelotaY' goes out of the 'jug1Y' - 'jug1Y+25' range and Player2 score increments. change initial value of pelotaY to 110.

ii) First loop of run also reduces 'pelotaX' from 10 to 5. but your condition says to change ball direction when (pelotaX = jug1X i.e. 20). So the direction doesn't change and in the next loop 'pelotaX' reduces to 0 and then the direction changes. But since 'pelotaX' is zero, Player2 score gets incremented. Change the condition for direction change from == to <= and for the left side and from == to >= for the right side.

I've highlighted the changes in bold and underlined. It works fine









private int pelotaX = 10, pelotaY = 110, jug1X=10, jug1Y=100, jug2X=230, jug2Y=100;



// Delay
try
{
Thread.sleep(50);
}
catch(InterruptedException ex)
{

}

// Move player 1
moverPlayer1();

// Move player 2
moverPlayer2();


// The score of the player 1 increase
if (pelotaX >= (this.getWidth() - 8)) contPlay1++;

// The score of the player 2 increase
if ( pelotaX == 0)
contPlay2++;

// Game over. Here you can change 6 to any value
// When the score reach to the value, the game will end
if(contPlay1==6 || contPlay2==6){
juego=false;
gameOver=true;
}

// The ball stroke with the player 1
if(pelotaX<=jug1X+10 && pelotaY>=jug1Y && pelotaY<=(jug1Y+25))
izqDer=true;

// The ball stroke with the player 2
if(pelotaX>=(jug2X-5) && pelotaY>=jug2Y && pelotaY<=(jug2Y+25)) izqDer=false;

#5
James.H

James.H

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 866 posts
wow it works, just creatd my very ony pong game.

Thanks!

#6
Phineas

Phineas

    Newbie

  • Members
  • PipPip
  • 11 posts
This is awesome, now if only I knew how to run it lol..

#7
nits

nits

    Newbie

  • Members
  • Pip
  • 1 posts
cud sum1 plz suggest how t run it???

#8
Grespon

Grespon

    Newbie

  • Members
  • Pip
  • 1 posts

nits said:

cud sum1 plz suggest how t run it???

Well I ran it creating a Java project called Pong in Eclipse. Then I added the two classes and ctrl+v the codes. then I needed to add the line "package Pong;" at the beggining of each class. That's all. It's running!

#9
GMVResources

GMVResources

    Learning Programmer

  • Members
  • PipPipPip
  • 72 posts
Its really easy to run and you dont have to download an IDE like Eclipse just use the notepad and run it inside there.

#10
Art

Art

    Newbie

  • Members
  • Pip
  • 1 posts
I've got a problem with with the rackets squares, as soon as game starts they go down till no one can see them, and if i press up arrow key and 'w' they would stop. I didn't just copied the code, i tried to retype it so I would learn more, but as you can see it didn't went well. Couldn't fix the problem. Please help me.

This is Main class, in my case it's Game class

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;


public class Game extends JFrame{

	private static final long serialVersionUID = 1L;

	private JPanel jContentPane = null;

	private Ball panel = null;

	private Ball getPanel(){

		if(panel == null){

			panel = new Ball();

		}

		return panel;

		

	}


public Game(){

	super();

	initialize();

	this.addKeyListener(new KeyAdapter(){

		public void keyPressed(KeyEvent e){

			formKeyPressed(e);

		}

		public void keyReleased(KeyEvent e){

			formKeyReleased(e);

		}

	});

	}

	private void formKeyPressed(KeyEvent e){

		panel.KeyPressed(e);

	}

	private void formKeyReleased(KeyEvent e){

		panel.keyReleased(e);

	}

	private void initialize(){

		this.setResizable(false);

		this.setBounds(new Rectangle(312, 184, 250,  250));

		this.setMaximumSize(new Dimension(250, 250));

		this.setMinimumSize(new Dimension(250, 250));

		this.setContentPane(getJContentPane());

		this.setTitle("Huy Ping Pong");

	}

	private JPanel getJContentPane(){

		if(jContentPane == null){

			jContentPane = new JPanel();

			jContentPane.setLayout(new BorderLayout());

			jContentPane.add(getPanel(), BorderLayout.CENTER);

		}

		return jContentPane;

	}

	public static void main(String[] args){

		SwingUtilities.invokeLater(new Runnable(){

			public void run(){

				Game thisClass = new Game();

				thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

				thisClass.setVisible(true);

			}

		});

	}

}


This would be panelPelota and in my case Ball

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;


public class Ball extends JPanel implements Runnable{

	private static final long serialVersionUID = 1L;

	private int ballX = 100, ballY = 110, rock1X = 10, rock1Y = 100, rock2X =230, rock2Y = 100;

	Thread hilo;

	int right = 5;

	int left = -5;

	int up = 5;

	int down = -5;

	int width, height;

	int GamePlayer1 = 0, GamePlayer2 = 0;

	boolean player1FlagUp, player1FlagDown, player2FlagUp, player2FlagDown;

	boolean playing, gameOver;

	

	public Ball(){

		playing = true;

		hilo = new Thread(this);

		hilo.start();

	}

	public void paintComponent(Graphics gc){

		setOpaque(false);

		super.paintComponent(gc);

		gc.setColor(Color.red);

		gc.fillOval(ballX, ballY, 8, 8);

		

		gc.fillRect(rock1X, rock1Y, 10, 25);

		gc.fillRect(rock2X, rock2Y, 10, 25);

		

		gc.drawString("Score Player 1:"+GamePlayer1, 25,10);

		gc.drawString("Score Player 2:"+GamePlayer2, 125, 10);

		

		if(gameOver)

			gc.drawString("Game Over", 100,125);

	}

	public void positionBall(int nx, int ny)

	{

		ballX = nx;

		ballY = ny;

		this.width=this.getWidth();

		this.height=this.getHeight();

		repaint();

	}

	public void KeyPressed(KeyEvent e){

		switch(e.getKeyCode()){

		case KeyEvent.VK_W:

			player1FlagUp =true;

			break;

		case KeyEvent.VK_S:

			player1FlagDown = true;

			break;

		case KeyEvent.VK_UP:

			player2FlagUp = true;

			break;

		case KeyEvent.VK_DOWN:

			player2FlagDown = true;

			break;

			

		}

	}

	public void keyReleased(KeyEvent e){

		switch(e.getKeyCode()){

		case KeyEvent.VK_W:

			player1FlagUp = false;

			break;

		case KeyEvent.VK_S:

			player1FlagDown = false;

			break;

		case KeyEvent.VK_UP:

			player2FlagUp = false;

			break;

		case KeyEvent.VK_DOWN:

			player2FlagDown = false;

			break;

		}

	}

	public void moverPlayer1(){

		if(player1FlagUp == true && rock1Y>=0)

			rock1Y+=down;

		if(player1FlagDown == true && rock1Y<=(this.getHeight()-25));

			rock1Y+=up;

		positionPlayer1(rock1X, rock1Y);

	}

	public void moverPlayer2(){

		if(player2FlagUp == true && rock2Y>=0)

			rock2Y+=down;

		if(player2FlagDown == true && rock2Y<=(this.getHeight()-25));

			rock2Y+=up;

		positionPlayer2(rock2X, rock2Y);

	}

	public void positionPlayer1(int x, int y){

		this.rock1X = x;

		this.rock1Y = y;

		repaint();

	}

	public void positionPlayer2(int x, int y){

		this.rock2X = x;

		this.rock2Y = y;

		repaint();

	}

	public void run(){

		boolean leftRight = false;

		boolean upDown = false;

		

		while(true){

			if(playing){

				if(leftRight){

					ballX+=right;

					if(ballX>=(width - 8))

						leftRight = false;

				}

				else{

					ballX += left;

					if(ballX<= 0)

						leftRight = true;

				}

				if(upDown){

					ballY+=up;

					if(ballY>=(height -8))

						upDown = false;

					

				}

				else{

					ballY+=down;

					if(ballY<=0)

						upDown = true;

				}

				positionBall(ballX,ballY);

				try{

					Thread.sleep(50);

				}catch(InterruptedException ex){

					

				}

				moverPlayer1();

				moverPlayer2();

				if(ballX>=(getWidth() - 8))

					GamePlayer1++;

				if(ballX == 0)

					GamePlayer2++;

				if(GamePlayer1 == 6 || GamePlayer2 == 6){

					playing =false;

					gameOver = true;

				}

				if(ballX <= (rock1X+10) && ballY>=rock1Y&& ballY<=(rock1Y+25))

					leftRight = true;

				if(ballX>=(rock2X-5)&& ballY>=rock2Y && ballY<=(rock2Y+25))

					leftRight = false;

			}

		}

	}

}



#11
fastrthnu

fastrthnu

    Newbie

  • Members
  • Pip
  • 1 posts
This is to help all the newcomers. This is how setup my environment to compile and run this:

1. Downloaded and installed Java SE JDK from Sun's website.
2. Added C:\Program Files\Java\jdk1.6.0_21\bin; to my beginning of my path (right click my computer, properties, advanced, environment variables). You do this so when you try to run the java compiler (javac.exe) it will find the executable.
3. Created a folder called c:\java
4. Copied and pasted the contents of both windows into notepad separately and saved them to c:\java\Main.java and c:\java\PanelPelota.java (make sure you change the Save As Type from Text Files (*.txt) to all files so that notepad won't add a ".txt" to the end of the filename).
5. Opened a command window (start / run / cmd)
6. Went to the folder where the java source code files were (cd \java)
7. Typed this to compile each one:
javac Main.java
javac PanelPelota.java
8. Typed this to run the game:
java Main

If things aren't working, check the case (upper case and lower case are different) and the file extensions. Notepad may have saved the files as Main.Java.txt if you didn't say "show all files" when you saved. When you compiled, it shouldn't have given any errors, and should have created two files Main.class and PanelPelota.class

#12
Whur

Whur

    Newbie

  • Members
  • Pip
  • 2 posts
Art
Just worked it out! You have semicolons on the end of the test statements in the Ball move player routines!

	public void moverPlayer1(){

		if(player1FlagUp == true && rock1Y>=0)

			rock1Y+=down;

		if(player1FlagDown == true && rock1Y<=(this.getHeight()-25))[B];[/B] // [B]Remove semicolon here[/B]

			rock1Y+=up;

		positionPlayer1(rock1X, rock1Y);

	}

	public void moverPlayer2(){

		if(player2FlagUp == true && rock2Y>=0)

			rock2Y+=down;

		if(player2FlagDown == true && rock2Y<=(this.getHeight()-25))[B];[/B] // [B]and here[/B]

			rock2Y+=up;

		positionPlayer2(rock2X, rock2Y);

	}

Edited by Roger, 28 May 2011 - 12:20 PM.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users