///// F. Permadi 1998
///// Compiled with JDK 1.0
import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
class CBub
{
static CMBubble mGame;
static Graphics mOffScrGraphics;
static int mAppletWidth, mAppletHeight;
// status code
int mStatus;
int mVDir, mHDir;
static final int DEAD=3;
static final int UP=1;
static final int DOWN=2;
static final int LEFT=3;
static final int RIGHT=4;
// PLAYER'S STUFF
int mStartX, mStartY;
int mLeftX, mTopY;
int mYSpeed, mXSpeed;
static int mWidth, mHeight;
static Image mImage;
int mLifeTime;
/////////////////////////////////////////////////////////////////////
// standard constructor
/////////////////////////////////////////////////////////////////////
public CBub()
{
mStatus=DEAD;
}
static void setupStatic(Graphics g, int gameAreaWidth, int gameAreaHeight, CMBubble game)
{
mOffScrGraphics=g;
mAppletWidth=gameAreaWidth;
mAppletHeight=gameAreaHeight;
mGame=game;
String s=game.getParameter("bubbleImage");
if (s!=null)
mImage=mGame.loadImage(s);
else
{
int width=20;
mImage=game.createImage(width,width);
Graphics gr=mImage.getGraphics();
int transColorValue=0xFF000000;
Color transparentColor=new Color(transColorValue);
gr.setColor(transparentColor);
gr.fillRect(0,0,width,width);
gr.setColor(Color.white);
gr.fillOval(0,0,width-1,width-1);
gr.setColor(Color.blue);
gr.drawOval(0,0,width-1,width-1);
// MAKE TRANSPARENT
//Allocate buffer to hold the image's pixels
int pixels[] = new int[width * width];
PixelGrabber pg = new PixelGrabber(mImage, 0, 0,
width, width, pixels, 0, width);
try
{
pg.grabPixels();
}
catch (InterruptedException e)
{
};
for (int i=0; i<width*width;i++)
{
if (pixels[i]==transColorValue)
pixels[i]=0x00000000;
}
mImage = game.createImage(new MemoryImageSource(width,
width, pixels, 0, width));
}
mWidth=mImage.getWidth(null);
mHeight=mImage.getHeight(null);
}
public void deploy(int x, int y, int dir)
{
mLeftX=x;
mTopY=y;
mStatus=DOWN;
mVDir=DOWN;
mLifeTime=0;
mHDir=dir;
}
public void move()
{
if (mStatus==DEAD)
return;
mLifeTime++;
if (mHDir==LEFT)
mLeftX-=mXSpeed;
else
mLeftX+=mXSpeed;
if ((mLifeTime%3)==0)
{
mXSpeed++;
if (mXSpeed>10)
mXSpeed=10;
}
if (mVDir==DOWN)
{
mTopY+=mYSpeed;
mYSpeed++;
if (mTopY+mHeight>=mAppletHeight)
{
mTopY=mAppletHeight-mHeight;
mVDir=UP;
mYSpeed=3;
mXSpeed=3;
}
}
else if (mVDir==UP)
{
mTopY-=mYSpeed;
mYSpeed++;
if (mTopY<=0)
{
mTopY=0;
mVDir=DOWN;
mYSpeed=3;
mXSpeed=3;
}
}
}
public void draw()
{
if (mStatus==DEAD)
return;
mOffScrGraphics.drawImage(mImage,
mLeftX, mTopY,null);
}
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
public class CMBubble extends Applet implements Runnable
{
Thread mThread = null;
int mAppletWidth, mAppletHeight;
Image mOffScrImage;
Graphics mOffScrGraphics;
boolean mStillDrawingOffScreen;
// status code
int mStatus;
static final int PLAYING=2;
static final int LOADING=3;
// background image
Image mBgrImage;
// FONTS
static final Font mFont1=new Font("Helvetica", Font.BOLD, 12);
static final boolean DEBUG=false;
CBub mBubbles[];
int mNumOfBubbles;
int mCurrentBubble;
int mMouseX, mMouseY, mDir;
boolean mUserHasMoved;
/////////////////////////////////////////////////////////////////////
// Create background image
/////////////////////////////////////////////////////////////////////
public void createBackground()
{
String s=getParameter("bgrImage");
if (s!=null)
mBgrImage=loadImage(s);
else
{
mBgrImage=createImage(mAppletWidth, mAppletHeight);
Graphics g=mBgrImage.getGraphics();
g.setColor(Color.red);
g.fillRect(0,0,mAppletWidth,mAppletHeight);
}
}
/////////////////////////////////////////////////////////////////////
// standard constructor
/////////////////////////////////////////////////////////////////////
public CMBubble()
{
}
/////////////////////////////////////////////////////////////////////
// standard applet info
/////////////////////////////////////////////////////////////////////
public String getAppletInfo()
{
return "Buble, programmed by F. Permadi";
}
/////////////////////////////////////////////////////////////////////
// standard applet initializer
/////////////////////////////////////////////////////////////////////
public void init()
{
}
/////////////////////////////////////////////////////////////////////
// load image
/////////////////////////////////////////////////////////////////////
public Image loadImage(String imageName)
{
MediaTracker tracker=new MediaTracker(this);
//Load image
Image i=getImage(getCodeBase(),imageName);
tracker.addImage(i,0);
try
{
tracker.waitForID(0);
}
catch (InterruptedException e)
{
System.out.println(e);
}
return i;
}
/////////////////////////////////////////////////////////////////////
// for painting the applet
/////////////////////////////////////////////////////////////////////
public void update(Graphics g)
{
if (!mStillDrawingOffScreen)
g.drawImage(mOffScrImage,0,0,this);
}
public void drawOffScreen()
{
mStillDrawingOffScreen=true;
if (mStatus==PLAYING)
{
// draw background
mOffScrGraphics.drawImage(mBgrImage,0,0,this);
for (int i=0;i<mNumOfBubbles; i++)
{
mBubbles[i].draw();
mBubbles[i].move();
}
}
else if (mStatus==LOADING)
{
mOffScrGraphics.setColor(Color.black);
mOffScrGraphics.fillRect(0,0,size().width, size().height);
mOffScrGraphics.setFont(mFont1);
drawTextCentered(0, mAppletHeight/2, mAppletWidth,
"LOADING...", mOffScrGraphics);
}
mStillDrawingOffScreen=false;
}
////////////////////////////////////////////////////////////////////
// standard applet startup
/////////////////////////////////////////////////////////////////////
public void start()
{
if (mThread == null)
{
mThread = new Thread(this);
mThread.start();
}
requestFocus();
}
/////////////////////////////////////////////////////////////////////
// this will be called when user leave the applet page
/////////////////////////////////////////////////////////////////////
public void stop()
{
if (mThread != null)
{
mThread.stop();
mThread = null;
}
}
/////////////////////////////////////////////////////////////////////
// create the game image/bitmap/objects, etc
// this should only be called once
/////////////////////////////////////////////////////////////////////
public void createGame()
{
// create offscreen buffer
mAppletWidth=size().width;
mAppletHeight=size().height;
mOffScrImage=createImage(mAppletWidth, mAppletHeight);
mOffScrGraphics=mOffScrImage.getGraphics();
// show "LOADING" message
mStatus=LOADING;
drawOffScreen();
repaint();
// create background
mBgrImage=createImage(mAppletWidth, mAppletHeight);
createBackground();
CBub.setupStatic(mOffScrGraphics, mAppletWidth,
mAppletHeight, this);
mNumOfBubbles=30;
mBubbles=new CBub[mNumOfBubbles];
for (int i=0; i<mNumOfBubbles; i++)
mBubbles[i]=new CBub();
}
/////////////////////////////////////////////////////////////////////
// applet thread runner
/////////////////////////////////////////////////////////////////////
public void run()
{
int delay=50;
createGame();
mStatus=PLAYING;
mUserHasMoved=false;
mMouseX=mAppletWidth/2;
mMouseY=mAppletHeight-20;
while (true)
{
drawOffScreen();
repaint();
if (!mUserHasMoved)
{
if ((int)(Math.random()*2)==1)
{
mMouseX=mAppletWidth/2+(int)(Math.random()*20);
mDir=CBub.RIGHT;
}
else
{
mMouseX=mAppletWidth/2-(int)(Math.random()*20);
mDir=CBub.LEFT;
}
}
if (mCurrentBubble<mNumOfBubbles)
mBubbles[mCurrentBubble].deploy(mMouseX-(mBubbles[0].mWidth>>1),
mMouseY-(mBubbles[0].mHeight>>1), mDir);
mCurrentBubble++;
if (mCurrentBubble>=mNumOfBubbles)
mCurrentBubble=0;
try
{
Thread.sleep(delay);
}
catch (InterruptedException e)
{
stop();
}
}
}
///////////////////////////////////////////////////////////////
// The user has clicked in the applet.
///////////////////////////////////////////////////////////////
public boolean mouseDown(Event evt, int x, int y)
{
mCurrentBubble=0;
return true;
}
public boolean mouseDrag(Event evt, int x, int y)
{
mUserHasMoved=true;
if (mMouseX>x)
mDir=CBub.RIGHT;
else
mDir=CBub.LEFT;
mMouseX=x;
mMouseY=y;
return true;
}
public boolean mouseMove(Event evt, int x, int y)
{
mUserHasMoved=true;
if (mMouseX>x)
mDir=CBub.RIGHT;
else
mDir=CBub.LEFT;
mMouseX=x;
mMouseY=y;
return true;
}
public boolean mouseExit(Event evt, int x, int y)
{
mUserHasMoved=false;
return false;
}
///////////////////////////////////////////////////////////////
// draw raised texts on the center
///////////////////////////////////////////////////////////////
public void drawTextCentered(
int left, int top, int right, String s, Graphics g)
{
FontMetrics fm=g.getFontMetrics();
int x=left+(((right-left)-fm.stringWidth(s))>>1);
g.setColor(Color.white);
g.drawString(s, x, top);
}
}
BACK