package djh.games.pavajong ; import java.awt.*; // // This code is released into the public domain as of 3/31/96. // d.j.hudek // /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // class Blump /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // // A Blump is a blob thing-y :-) // It has a position, rectangular shape, // regularly changing color, and value. // If something hits it, the Blump will give up a reward, // and then supply a random new position and velocity // to the thing that hit it. // // It can be used as a "target" to hit on the playing field. // public class Blump { ///////////////////////////////////////////////////////////////// // Class Data ///////////////////////////////////////////////////////////////// protected static int MAX_COLOR_RANGE = 0xFFFFFF; protected static int MAX_COLOR_RANGE_PLUS1 = 0x1000000; protected static int DEF_COLORCHANGE_INT = 20; protected static Color DEF_REWARD_BG_COLOR = Color.yellow; protected static int DEF_VALUE = 500; protected static int DEF_SCORE_DISPLAY_PAUSE = 40; protected static String DEF_RANDOM_REWARD_STRING = "??"; protected static float DEF_VCHANGE_MIN = 0.75f; protected static float DEF_VCHANGE_RANGE = 0.5f; protected static float MIN_VERT_SPACING = 5; protected static float MIN_HORIZ_SPACING = 5; ///////////////////////////////////////////////////////////////// // Instance Variables ///////////////////////////////////////////////////////////////// protected int posX; protected int posY; protected int sizeX; protected int sizeY; protected Rectangle meAsRectangle; protected boolean shouldPaintFresh = true; protected int colorChangeInterval; protected int colorChangeCount; protected Color myColor; protected String myName; protected int myValue; protected boolean randomReward; protected float vChgMin; protected float vChgRange; ///////////////////////////////////////////////////////////////// // Constructors ///////////////////////////////////////////////////////////////// /** * Instantiates a Blump. * * A Blump is a blob thing-y :-) * It has a position, rectangular shape, * regularly changing color, and value. * If something hits it, the Blump will give up a reward, * and then supply a random new position and velocity * to the thing that hit it. * * Default values for color change interval and reward value * will be used by this constructor. * * It can be used as a "target" to hit on the playing field. * * @param x - x position * @param y - y position * @param sx - size in the x dimension * @param sy - size in the y dimension */ public Blump( int x, int y, int sx, int sy ) { posX = x; posY = y; sizeX = sx; sizeY = sy; meAsRectangle = new Rectangle( x, y, sx, sy ); colorChangeInterval = DEF_COLORCHANGE_INT; colorChangeCount = 0; myColor = new Color(MAX_COLOR_RANGE); myValue = DEF_VALUE; randomReward = false; myName = new String( new Integer(myValue).toString() ); vChgMin = DEF_VCHANGE_MIN; vChgRange = DEF_VCHANGE_RANGE; } /** * Instantiates a Blump. * * A Blump is a blob thing-y :-) * It has a position, rectangular shape, * regularly changing color, and value. * If something hits it, the Blump will give up a reward, * and then supply a random new position and velocity * to the thing that hit it. * * * Default value for the reward value will be used by this * constructor. * * It can be used as a "target" to hit on the playing field. * * @param x - x position * @param y - y position * @param sx - size in the x dimension * @param sy - size in the y dimension * @param ccInterval - color change interval (number of * paint invocations) */ public Blump( int x, int y, int sx, int sy, int ccInterval ) { posX = x; posY = y; sizeX = sx; sizeY = sy; meAsRectangle = new Rectangle( x, y, sx, sy ); colorChangeInterval = ccInterval; colorChangeCount = 0; myColor = new Color(MAX_COLOR_RANGE); myValue = DEF_VALUE; randomReward = false; myName = new String( new Integer(myValue).toString() ); vChgMin = DEF_VCHANGE_MIN; vChgRange = DEF_VCHANGE_RANGE; } /** * Instantiates a Blump. * * A Blump is a blob thing-y :-) * It has a position, rectangular shape, * regularly changing color, and value. * If something hits it, the Blump will give up a reward, * and then supply a random new position and velocity * to the thing that hit it. * * It can be used as a "target" to hit on the playing field. * * @param x - x position * @param y - y position * @param sx - size in the x dimension * @param sy - size in the y dimension * @param ccInterval - color change interval (number of * paint invocations) * @param val - fixed reward value */ public Blump( int x, int y, int sx, int sy, int ccInterval, int val ) { posX = x; posY = y; sizeX = sx; sizeY = sy; meAsRectangle = new Rectangle( x, y, sx, sy ); colorChangeInterval = ccInterval; colorChangeCount = 0; myColor = new Color(MAX_COLOR_RANGE); myValue = DEF_VALUE; randomReward = false; myName = new String( new Integer(myValue).toString() ); vChgMin = DEF_VCHANGE_MIN; vChgRange = DEF_VCHANGE_RANGE; } /** * Instantiates a Blump. * * A Blump is a blob thing-y :-) * It has a position, rectangular shape, * regularly changing color, and value. * If something hits it, the Blump will give up a reward, * and then supply a random new position and velocity * to the thing that hit it. * * It can be used as a "target" to hit on the playing field. * * @param x - x position * @param y - y position * @param sx - size in the x dimension * @param sy - size in the y dimension * @param ccInterval - color change interval (number of * paint invocations) * @param val - reward value * @param random - false if reward is to be fixed, * true if reward should be randomly * selected from the range [0,val] */ public Blump( int x, int y, int sx, int sy, int ccInterval, int val, boolean random ) { posX = x; posY = y; sizeX = sx; sizeY = sy; meAsRectangle = new Rectangle( x, y, sx, sy ); colorChangeInterval = ccInterval; colorChangeCount = 0; myColor = new Color(MAX_COLOR_RANGE); myValue = val; randomReward = random; if( randomReward ) { myName = DEF_RANDOM_REWARD_STRING; } else { myName = new String( new Integer(val).toString() ); } vChgMin = DEF_VCHANGE_MIN; vChgRange = DEF_VCHANGE_RANGE; } ///////////////////////////////////////////////////////////////// // Methods ///////////////////////////////////////////////////////////////// /** * returns current x position */ public int getX() { return( posX ); } /** * returns current y position */ public int getY() { return( posY ); } /** * returns a Rectangle object representation of this object * (positional information) */ public Rectangle getRect() { return( meAsRectangle ); } /** * returns size in the X dimension */ public int getSizeX() { return( sizeX ); } /** * returns size in the Y dimension */ public int getSizeY() { return( sizeY ); } /** * Checks to see if the color should change. * If so, sets myColor instance variable to new color * and returns true. * Else, returns false */ public boolean shouldColorChange() { boolean returnValue = false; // assume not, then check if( ++colorChangeCount >= colorChangeInterval ) { int newColorValues; // random() returns value (0.0,1.0); // desire random value from [0,xFFFFFF] newColorValues = (int)(Math.random()*(double)MAX_COLOR_RANGE_PLUS1); myColor = new Color( newColorValues ); colorChangeCount = 0; returnValue = true; } return( returnValue ); } /** * Tells Blump that it should repaint itself fresh * (rather than rely on old image to be hanging around) */ public void setPaintFresh() { shouldPaintFresh = true; } /** * Given another object in terms of a Rectangle object, * returns true if it intersects with this * * @param them - Rectangle object in question */ public boolean didItHit( Rectangle them ) { return( meAsRectangle.intersects(them) ); } /** * Displays an increasing count from 0 to the reward value; * returns the reward value. * (count display occurs within the Blump object w/in the * Graphics). * * This will intentionally take human-significant time to execute... * giving user a perceptable view of rapidly increasing counter. * Time to execute will be on the order of seconds. * * @param myG - Graphics in which the Blump resides */ public int giveReward( Graphics myG ) { Color saveColor = myG.getColor(); int reward = myValue; int strWidth; int strHeight; if( randomReward ) { reward = (int)((Math.random() * reward) + 1); } for( int i = 0; i < reward; i++ ) { Integer curInt = new Integer( i ); String curString = curInt.toString(); myG.setColor( DEF_REWARD_BG_COLOR ); myG.fill3DRect( posX, posY, sizeX, sizeY, true ); myG.setColor( Color.black ); strWidth = myG.getFontMetrics().stringWidth(curString); strHeight = myG.getFontMetrics().getHeight(); myG.drawString( curString, posX + (sizeX - strWidth)/2, posY + strHeight + (sizeY - strHeight)/2 ); for( int j = 0; j < DEF_SCORE_DISPLAY_PAUSE; j++ ) { ; // kill a little time locked in } } myG.setColor( saveColor ); return( reward ); } /** * * Randomly alter the given PlayBall object's velocity * and then position it just outside "this", * such that it won't immediately re-hit * * ASSUMES that the earlier placement was constrained * to place "this" at least MIN_XXX_SPACING (plus * the size of any balls in play) points away * from the canvas edges and any other Blump * * @param theBall - the PlayBall to affect */ public void newPositionAndVelocity( PlayBall theBall ) { int ballXsize = theBall.getSize(); int ballYsize = theBall.getSize(); // Random increase or decrease in magnitude, // and random change in direction theBall.setVx( (theBall.getVx() * (float)((Math.random() * vChgRange) + vChgMin)) ); if( Math.random() < 0.5f ) { theBall.invertVx(); } // Alter velocity in Y dimension // Random increase or decrease in magnitude, // and random change in direction theBall.setVy( (theBall.getVy() * (float)((Math.random() * vChgRange) + vChgMin)) ); if( Math.random() < 0.5f ) { theBall.invertVy(); } // // Now give it a new position such that it is headed // away from "this" // boolean vxNeg = ( theBall.getVx() < 0.0f ); boolean vyNeg = ( theBall.getVy() < 0.0f ); if( vxNeg && vyNeg ) { // headed NorthWesterly direction... theBall.setXY( posX - ballXsize - MIN_HORIZ_SPACING, posY - ballYsize - MIN_VERT_SPACING ); } else if( vxNeg && !vyNeg ) { // headed SouthWesterly direction... theBall.setXY( posX - ballXsize - MIN_HORIZ_SPACING, posY + sizeY + MIN_VERT_SPACING ); } else if( !vxNeg && !vyNeg ) { // headed SouthEasterly direction... theBall.setXY( posX + sizeX + MIN_HORIZ_SPACING, posY + sizeY + MIN_VERT_SPACING ); } else { // must be !vxNeg && vyNeg // headed in NorthEasterly direction... theBall.setXY( posX + sizeX + MIN_HORIZ_SPACING, posY - ballYsize - MIN_VERT_SPACING ); } } /** * Paint method. * * A Blump appears as a 3D rectangle with a String in the middle * (string contains either an integer value if a fixed reward, * or "??" if a random reward) * * Only repaint if color changed or if consumer has told us to * (via setPaintFresh()) */ public synchronized void paint( Graphics g ) { if( shouldColorChange() || shouldPaintFresh ) { shouldPaintFresh = false; // turn off the flag Color saveColor = g.getColor(); g.setColor( myColor ); g.fill3DRect( posX, posY, sizeX, sizeY, true ); g.setColor( Color.black ); int strWidth = g.getFontMetrics().stringWidth(myName); int strHeight = g.getFontMetrics().getHeight(); g.drawString( myName, posX + (sizeX - strWidth)/2, posY + strHeight + (sizeY - strHeight)/2 ); g.setColor( saveColor ); } } }