/** * Intelligence class that holds position of bee and * determines how it must think and such. **/ import java.awt.*; public class Creature { Point pPos; // Where the bee is Point pTarget; // The target. Run away from it, etc int x, y, iTime, iIndex, iTheta; // For the logic int iLogic; // The logic to use int iState; // The current state of the FSM int iTimeState; // Time left for that state (if not determined by elsething) Creature() { pPos = new Point(150, 90); pTarget = new Point(0, 0); iLogic=2; iState=0; } /** * The mouse has moved, so our target also has! **/ public void setTarget(int x, int y) { pTarget.move(x, y); } public void setLogic(int log) { iLogic = log; } /** * Move the creature using the selected logic * The logic functions set the X and Y values to * how the bee should change its direction. Then * the move() function does the actual movement * of the bee, and then it does some boundary checking. **/ public void move() { // Call the selected logic method switch ( iLogic ) { case 1: logicFSM(); break; case 2: logicChase(); break; case 3: logicRetreat(); break; case 4: logicPattern(); break; case 5: logicCircle(); break; case 6: logicRandom(); break; } pPos.translate(x, y); // Bounds checking if (pPos.x < 97) pPos.x = 97; if (pPos.x > 272) pPos.x = 272; if (pPos.y < 12) pPos.y = 12; if (pPos.y > 127) pPos.y = 127; } /** * Move the creature using FSM logic * NO:Make the determination by distance to the target * First circle, then touch the mouse, then run away until far enough away * Then do a pattern, and then repeat the sequence. **/ private void logicFSM() { int xdif = Math.abs(pPos.x - pTarget.x); int ydif = Math.abs(pPos.y - pTarget.y); int iDif = (int) Math.sqrt(xdif*xdif + ydif*ydif); switch (iState) { case 0: // Circle around for a little while logicCircle(); if (iTimeState < 1) iState=1; break; case 1: // Chase until touch mouse logicChase(); if ( iDif < 5 ) iState=2; break; case 2: // Run away until distance is 100 logicRetreat(); if (iDif > 70) { iState=3; iTimeState = 80; } break; case 3: // Now do a funky pattern logicPattern(); if (iTimeState < 1) { iState=0; iTimeState = 100; } break; } iTimeState--; } /** * Move the creature using CHASE logic **/ private void logicChase() { // Make sure it moves smoothely, instead of just // always either diag or straight, which sucks int xdif = Math.abs(pPos.x - pTarget.x); int ydif = Math.abs(pPos.y - pTarget.y); if ( xdif > ydif ) { x = 2; y = 1; } if ( ydif > xdif ) { y = 2; x = 1; } if ( xdif == 0 ) { y = 3; x = 0; } if ( ydif == 0 ) { x = 3; y = 0; } if ( xdif == ydif ) { x = 1; y = 1; } if ( pPos.x > pTarget.x ) x*= -1; if ( pPos.y > pTarget.y ) y*=-1; } /** * Move the creature using RETREAT logic **/ private void logicRetreat() { // Retreating is just like chasing in reverse logicChase(); x*=-1; y*=-1; } /** * Move the creature using PATTERN logic * Draws a pretty ankh **/ private void logicPattern() { // The movement structure is arranged so that the first // value is the x direction to move, second is the y dir, // and third is the time to do that for. Each index skips by // 3, duh! int iPattern[] = { 3, 0, 4, -1, -2, 4, -2, -1, 4, -3, 0, 4, 0, 3, 12, -2, -1, 4, -1, -2, 4, 0, -3, 4, 3, 0, 8 }; int iPatSize = 9; if ( iTime == 0 ) { // Retrieve the values x = iPattern[ 3 * iIndex ]; y = iPattern[ 3 * iIndex + 1]; iTime = iPattern[ 3 * iIndex + 2]; // Next entry in pattern array iIndex++; // Cycle the pattern iIndex %= iPatSize; } iTime--; } /** * Move the creature using CIRCLE logic * Always try to remain a certain distance away from * the target, and also move around the target. **/ private void logicCircle() { // Temporary point to save target pt Point pTemp = new Point( pTarget.x, pTarget.y ); // Figure out where the pseudo target should be pTarget.x = pTarget.x + (int) Math.round(100 * Math.cos(iTheta * Math.PI / 180)); pTarget.y = pTarget.y + (int) Math.round(-100 * Math.sin(iTheta * Math.PI / 180)); // Now just do a chase after that target logicChase(); // Increase theta iTheta-=3; iTheta+=360; iTheta%=360; // Restore real target (the mouse) pTarget.move( pTemp.x, pTemp.y ); } /** * Move the creature using RANDOM logic * Basically move in a certain direction for a * while, and then go in another direction **/ private void logicRandom() { if (iTime == 0) { x = (int) ( Math.random() * 4 ); y = 3 - x; if ( Math.random() * 100 < 50 ) x*= -1; if ( Math.random() * 100 < 50 ) y*= -1; iTime = (int) ( Math.random() * 10 + 1); } iTime--; } /** * Display the bee and such * @param g The graphics class to draw it to **/ public void display(Graphics g ) { /* g.setColor( Color.white); g.fillRect( 100, 40, 100, 20); g.setColor( Color.blue); g.drawString( "State: " + iState, 100, 50);*/ // Draw a rect over the bee to erase the old image g.setColor(Color.white); g.fillRect( pPos.x-10, pPos.y-10, 20, 20); // Draw the creature g.setColor(Color.blue); g.fillRect( pPos.x, pPos.y, 3, 3); } }