BlackPhoenix 0 Junior Poster in Training

Hi guys,

Posted about a week ago saying I was re-learning Java and slowly making my way from basic console stuff to 2D graphics.

Well after a good deal of learning about applets and threads, drawing 2D shapes, and double buffering, I decided to remake "Pong", at least a crappy version of it anyways :-P

http://xioshin.webatu.com/dev/pong/pong.html
This entire game only took me a few hours!
Sorry, you still have to click to get focus.

Am I finally ready for 3D graphics? My goal is really just to create a small 3D world that I can navigate through.

Is it really necessary for me to learn object creation and destruction first (an example being creating bullets that are fired from a weapon, have the bullets travel along a path, and destroy after a certain distance OR collision) before I proceed into the realm of 3D?

I assume I can just strip all the Pong code down into a basic applet again and then try to program ONLY object creation and destruction. Seems difficult but I bet once you break it down it isnt.

Please point me in the next direction!!

I know many will ask, so here is the source code. I know, I need to declare the variables in Main but initialize them in init(). I erroneously gave the variables values during their declaration.

import java.applet.*; // import all classes from java.applet package
import java.awt.*; // import all classes from java.awt package
import java.lang.*; // imported for Thread class

public class Main extends Applet implements Runnable
{    
    private Font myFont;
    private Font debugFont;
    
    private Image offscreenImage; //backbuffer used for double buffering
    Graphics offscr;
    
    int player1_score = 0;
    int player2_score = 0;
    
    //paddle one
    int paddle1_x = 115;
    int paddle1_y = 15;
    int paddle1_width = 70;
    int paddle1_height = 15;
    int paddle1_speed = 3;
    
    //paddle two
    int paddle2_x = 115;
    int paddle2_y = 285;
    int paddle2_width = 70;
    int paddle2_height = 15;
    int paddle2_speed = 3;
    boolean moveLeft = false;
    boolean moveRight = false;
    
    //ball
    int ball_x = 150;
    int ball_y = 150;
    int ball_width = 15;
    int ball_height = 15;
    int ball_xvel = 3; //ball's x velocity
    int ball_yvel = 3; //ball's y velocity
    
    Thread myThread;
    private int counter;
    
    String keyDebug = "key: ";
    
    public void run()
    {
        while (true)
        {    
            counter++;
            
            ball_x += ball_xvel;
            ball_y += ball_yvel;
            
            if(moveLeft == true) { paddle2_x -= paddle2_speed;  }
            if(moveRight == true) { paddle2_x += paddle2_speed; }
            
            //Player 2 Artificial Intelligence
            if(ball_x < paddle1_x)
            {
                paddle1_x -= paddle1_speed;
            }
            if(ball_x > paddle1_x + paddle1_width)
            {
                paddle1_x += paddle1_speed;
            }
            
            //keep bottom paddle within bounds
            if(paddle2_x <= 0)
            {
                paddle2_x = 0;
            }
            if(paddle2_x >= 300 - paddle2_width)
            {
                paddle2_x = 300 - paddle2_width;
            }
            
            //keep top paddle within bounds
            if(paddle1_x <= 0)
            {
                paddle1_x = 0;
            }
            if(paddle1_x >= 300 - paddle1_width)
            {
                paddle1_x = 300 - paddle1_width;
            }
            
            //left level collision
            if(ball_x < 0)
            {
                ball_x = 0;
                ball_xvel = -ball_xvel;
            }
            
            //right level collision
            if(ball_x > (300-ball_width))
            {
                ball_x = (300-ball_width);
                ball_xvel = -ball_xvel;
            }
            
            //bottom paddle collision
            if((ball_y == 285 - ball_height) && (ball_x > paddle2_x - ball_width) && (ball_x < paddle2_x + paddle2_width) && (ball_yvel > 0))
            {
                ball_y = 285 - ball_height;
                ball_xvel++; //increase ball horizontal speed
                ball_yvel++; //increase ball vertical speed
                ball_yvel = -ball_yvel;
            }
            
            //top paddle collision
            if((ball_y == 15 + paddle1_height) && (ball_x > paddle1_x - ball_width) && (ball_x < paddle1_x + paddle1_width) && (ball_yvel < 0))
            {
                ball_y = 15 + ball_height;
                ball_xvel++; //increase ball horizontal speed
                ball_yvel++; //increase ball vertical speed
                ball_yvel = -ball_yvel;
            }
            
            //player1 scores
            if(ball_y < 15)
            {
                player1_score++;
                ball_y = 150;
                ball_x = 150;
                ball_xvel = 3; //reset ball horizontal speed
                ball_yvel = 3; //reset ball vertical speed
                ball_yvel = -ball_yvel; // give other player an advantage
            }
            
            //player2 scores
            if(ball_y > 285)
            {
                player2_score++;
                ball_y = 150;
                ball_x = 150;
                ball_xvel = 3; //reset ball horizontal speed
                ball_yvel = 3; //reset ball vertical speed
                ball_yvel = -ball_yvel; // give other player an advantage
            }
            
            repaint(); // redraw the screen
            
            try {
                myThread.sleep(1000/30);
            } catch (InterruptedException e) {; }
        }
    }
    
    //called when the applet is first loaded
    public void init()
    {
        myThread = new Thread(this); // creates instance of the Main class (Thread)
                                      // init() run for this instance, thread created for this instance
        myThread.start();

        counter = 0;
        
        setSize(300, 300); // sets the size of the applet
        
        offscreenImage = createImage(300, 300);  //create backbuffer the same size as the applet
        offscr = offscreenImage.getGraphics(); //get the graphics context of the backbuffer
        
        myFont = new Font("Arial", Font.PLAIN, 32);
        debugFont = new Font("Arial", Font.BOLD, 12);
        
    }
    
    public boolean keyDown(Event e, int key)
    {
        keyDebug = "keyDown: " + key; //update debug message
        
        if(key == 1006) { moveLeft = true; } //move paddle left
        if(key == 1007) { moveRight = true; } //move paddle right
        
        return true;
    }
    
    public boolean keyUp(Event e, int key)
    {
        keyDebug = "keyUp: " + key; //update debug message
        
        if(key == 1006) { moveLeft = false; }
        if(key == 1007) { moveRight = false; }
        
        return true;
    }
    
    public void paint(Graphics g)
    {
        offscr.setFont(debugFont);
        offscr.setColor(Color.WHITE); // set color to white
        offscr.fillRect(0, 0, 300, 300); // clear the backbuffer (white)
        
        offscr.setColor(Color.BLUE); //set color to blue
        offscr.drawString("counter: " + counter, 10, 280); //draw the counter
        offscr.drawString(keyDebug, 10, 265); //draw the current key event
        
        // score display
        offscr.setFont(myFont);
        offscr.setColor(Color.GRAY);
        offscr.drawString(Integer.toString(player1_score), 140, 200);
        offscr.drawString(Integer.toString(player2_score), 140, 100);
            
        //draw game objects
        offscr.setColor(Color.BLACK);
        offscr.fillRect(paddle1_x, paddle1_y, paddle1_width, paddle1_height);
        offscr.fillRect(paddle2_x, paddle2_y, paddle2_width, paddle2_height);
        offscr.fillOval(ball_x, ball_y, ball_width, ball_height);
        
        
        g.drawImage(offscreenImage, 0, 0, this); // draw backbuffer to the screen
    }
}