Hi, guys. I posted a discussion about this simulation a while ago but I have a different problem now. I want the guy (Scavenger) to only collect the metal objects that are on the world (which is getX() > 400 since the width of my world is 800. but it isnt working right now. can you see how i would do that or any other errors i have? I will post all the classes just in case.
Scavenger (Collector) Class:
Metal Class:
World Class:
ScoreBar Class (for displaying number of metals collected):
TextButton Class (which is used by ScoreBar class):
Thanks for any help you can provide in advance. And if anyone's wondering, this code is to be used as part of a bigger war simulation. im just coding one portion of it for now.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) import java.util.ArrayList; /** * Write a description of class Scavenger here. * * @author (your name) * @version (a version number or a date) */ public class Scavenger extends Actor { private Metal targetMetal; int numMetals; private ArrayList<Metal> metals; private int metalCount; private int metalCollect = 0 ; private int mySpeed = 2 ; private int count = 0 ; private int offset; //int initialX = this.getX(); //int initialY = this.getY(); /** * Act - do whatever the Scavenger wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { { //hp -= DesertWorld.BUG_DEATH_RATE; if (count % 8 == 0 ) // Only run every 8 acts to avoid lag { targetClosestMetal (); //hpBar.update(hp); } // If my current target Metal exists, move toward it if (targetMetal != null && targetMetal.getWorld() != null ) { moveTowardOrCollectMetal(); } else if (getWorld().getObjects(Metal. class ).size()== 0 ) this .setRotation( 0 ); // If I can't find anything to eat, move in a random direction /*else { moveRandomly(); }*/ } count++; //collectMetal(); } //Constructor that initializes a new metal collector guy public Scavenger() { GreenfootImage guy = new GreenfootImage( "scav guy.png" ); guy.scale( 100 , 100 ); this .setImage(guy); } public void targetClosestMetal() { double closestTargetDistance = 0 ; double distanceToActor; numMetals = getWorld().getObjects(Metal. class ).size(); metals = (ArrayList)getWorld().getObjects(Metal. class ); if (metals.size() > 0 ) { // set the first one as my target targetMetal = metals.get( 0 ); // Use method to get distance to target. This will be used // to check if any other targets are closer closestTargetDistance = MyWorld.getDistance ( this , targetMetal); // Loop through the objects in the ArrayList to find the closest target for (Metal o : metals) { // Cast for use in generic method Actor a = (Actor) o; // Measure distance from me distanceToActor = MyWorld.getDistance( this , a); // If I find a Flower closer than my current target, I will change // targets if (distanceToActor < closestTargetDistance && a.getX()> 400 ) { targetMetal = o; closestTargetDistance = distanceToActor; } } } } /** * Private method, called by act(), that moves toward the target, * or eats it if within range. */ private void moveTowardOrCollectMetal () { turnTowards(targetMetal.getX(), targetMetal.getY()); if ( this .getNeighbours ( 30 , true , Metal. class ).size() > 0 ) { // If I was able to eat, increase by life by flower's nibble power getWorld().removeObject(targetMetal); /*if (tryToCollect > 0) * { metalCollect += tryToCollect; }*/ } else { move (mySpeed); } } private void randomMove() { if (Greenfoot.getRandomNumber ( 100 ) == 50 ) { turn (Greenfoot.getRandomNumber( 360 )); } else move (mySpeed); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) import java.util.ArrayList; /** * Write a description of class Metal here. * * @author (your name) * @version (a version number or a date) */ public class Metal extends Actor { //A list of all the metals that has been collected by a team public static ArrayList<Integer> collectedMetals = new ArrayList<Integer>(); public static int numMetals = 0 ; /** * Act - do whatever the Metal wants to do. This method is called whenever * the 'Act' or 'Run' button gets pressed in the environment. */ public void act() { } public Metal() { GreenfootImage metal = new GreenfootImage( "metal.png" ); metal.scale( 100 , 100 ); this .setImage(metal); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) import java.util.ArrayList; /** * Write a description of class MyWorld here. * * @author (your name) * @version (a version number or a date) */ public class MyWorld extends World { private int actCounter = 0 ; private boolean scoreShowing; private int metalCount; private int initialX; private int initialY; private ScoreBar scoreBar; private TextButton metalButton; private Scavenger g1; /** * Constructor for objects of class MyWorld. * */ public MyWorld() { // Create a new world with 600x400 cells with a cell size of 1x1 pixels. super ( 800 , 600 , 1 ); GreenfootImage bg = new GreenfootImage( "white back.png" ); bg.scale(getWidth(), getHeight()); setBackground(bg); Metal.numMetals = 0 ; Metal m1 = new Metal(); addObject(m1, 300 , 300 ); Metal m2 = new Metal(); addObject(m2, 350 , 350 ); g1 = new Scavenger(); addObject(g1, Greenfoot.getRandomNumber( 400 ), Greenfoot.getRandomNumber( 480 )+ 120 ); initialX = g1.getX(); initialY = g1.getY(); ScoreBar scoreBar = new ScoreBar ( 800 ); addObject(scoreBar, 400 , 15 ); scoreBar.update( "Hi!" ); // Add the spawn button to the world metalButton = new TextButton ( " -> Metals <- " , 24 ); addObject (metalButton, 400 , 550 ); spawnMetal(); } public void act() { actCounter++; if (actCounter % 30 == 0 ) { //statUpdates(); //if (scoreShowing) //{ //scoreBar.update(metals); //} } if (Greenfoot.mouseClicked(metalButton)) { spawnMetal(); } returnHome(); } /** * Method to spawn a single bug at a random location */ private void spawnMetal () { addObject ( new Metal (), Greenfoot.getRandomNumber( 800 ), Greenfoot.getRandomNumber( 480 )+ 120 ); scoreShowing = true ; } /** * Static method that gets the distance between the x,y coordinates of two Actors * using Pythagorean Theorum. * * @param a First Actor * @param b Second Actor * @return float */ public static float getDistance (Actor a, Actor b) { double distance; double xLength = a.getX() - b.getX(); double yLength = a.getY() - b.getY(); distance = Math.sqrt(Math.pow(xLength, 2 ) + Math.pow(yLength, 2 )); return ( float )distance; } private void returnHome() { metalCount = getObjects(Metal. class ).size(); if (metalCount == 0 ) { g1.setLocation(initialX, initialY); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) // Need Color and Font for drawing ScoreBar /** * ScoreBar is a Greenfoot Actor that displays text. * The text is white on a reddish brown * background and designed to work in a scenario that is * 800x600 pixels. * <p> * Display any String that fits, or send * game info straight to customized method. * @author Jordan Cohen * @version April 2013 */ public class ScoreBar extends Actor { // Declare Objects private GreenfootImage scoreBoard; private Color background; private Color foreground; private Font textFont; private String text; // Declare Variables: private int width; private int totalMetals = 0 ; /** * Construct a ScoreBar of the appropriate size. * * @param width width of the World where the * ScoreBar will be placed */ public ScoreBar ( int width) { scoreBoard = new GreenfootImage (width, 30 ); background = new Color ( 175 , 20 , 23 ); foreground = new Color ( 255 , 255 , 255 ); textFont = new Font ( "Courier" , true , false , 24 ); scoreBoard.setColor(background); scoreBoard.fill(); this .setImage (scoreBoard); scoreBoard.setFont(textFont); this .width = width; } public void act() { update(totalMetals); } /** * Updates this ScoreBar with game stats. This method should be * re-written to work with your specific labels/values * * @param alive current number of living Bugs * @param maxAlive largest number of bugs alive during game * @param dead number of dead bugs * @param averageLifespan */ public void update ( int metalCollected) { // In order to make uniform sizes and preceding zeros: String metalString; // If there is only one digit metalString = zeroAdder (metalCollected, 3 ); text = "Metal pieces: " + Metal.numMetals; // Now that we have built the text to output... // this.update (String) calls the other version of update(), in this case // update(String) - see below this .update (text); } /** * Takes a String and displays it centered to the screen. * * @param output Text for displaying. */ public void update (String output) { // Refill the background with background color scoreBoard.setColor(background); scoreBoard.fill(); // Write text over the solid background scoreBoard.setColor(foreground); // Smart piece of code that centers text int centeredY = (width/ 2 ) - ((output.length() * 14 )/ 2 ); // Draw the text onto the image scoreBoard.drawString(output, centeredY, 22 ); } /** * Method that aids in the appearance of the scoreboard by generating * Strings that fill in zeros before the score. For example: * * 27 ===> to 5 digits ===> 00027 * * @param value integer value to use for score output * @param digits number of zeros desired in the return String * @return String built score, ready for display */ public static String zeroAdder ( int value, int digits) { // Figure out how many digits the number is int numDigits = digitCounter(value); // If not extra digits are needed if (numDigits >= digits) return Integer.toString(value); else // Build the number with zeroes for extra place values: { String zeroes = "" ; for ( int i = 0 ; i < (digits - numDigits); i++) { zeroes += "0" ; } return (zeroes + value); } } /** * Useful private method that counts the digit in any integer. * * @param number The number whose digits you want to count * @return int The number of digits in the given number */ private static int digitCounter ( int number) { if (number < 10 ) { return 1 ; } int count = 0 ; while (number > 0 ) { number /= 10 ; count++; } return count; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo) /** * A Generic Button to display text that is clickable. * * This should be added to, and controlled by, a world. * * @author Jordan Cohen * @version v0.1.5 */ public class TextButton extends Actor { // Declare variables private GreenfootImage myImage; private GreenfootImage myAltImage; private String buttonText; private int textSize; /** * Construct a TextButton given only a String * @param String String to be displayed */ public TextButton (String text) { this (text, 20 ); } /** * Construct a TextButton given a String and a text size * @param String String to be displayed */ public TextButton (String text, int textSize) { // Assign value to my internal String buttonText = text; this .textSize = textSize; // Draw a button with centered text: updateMe (text); } public void act () { if (Greenfoot.mousePressed( this )) { setImage (myAltImage); } else { setImage (myImage); } } /** * Update current TextButton text */ public void updateMe (String text) { buttonText = text; GreenfootImage tempTextImage = new GreenfootImage (text, textSize, Color.RED, Color.WHITE); myImage = new GreenfootImage (tempTextImage.getWidth() + 8 , tempTextImage.getHeight() + 8 ); myImage.setColor (Color.WHITE); myImage.fill(); myImage.drawImage (tempTextImage, 4 , 4 ); myImage.setColor (Color.BLACK); myImage.drawRect ( 0 , 0 ,tempTextImage.getWidth() + 7 , tempTextImage.getHeight() + 7 ); setImage(myImage); tempTextImage = new GreenfootImage (text, textSize, Color.WHITE, Color.RED); myAltImage = new GreenfootImage(tempTextImage.getWidth() + 8 , tempTextImage.getHeight() + 8 ); myAltImage.setColor (Color.WHITE); myAltImage.fill(); myAltImage.drawImage (tempTextImage, 4 , 4 ); myAltImage.setColor (Color.BLACK); myAltImage.drawRect ( 0 , 0 ,tempTextImage.getWidth() + 7 , tempTextImage.getHeight() + 7 ); } } |