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
}
}