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.
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); } }
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); } }
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); } } }
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; } }
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); } }