So for my class I have to use the Greenfoot IDE. And my goal is to:
“the pig eats all the mushrooms currently in the barrel”
The pig will have to call the barrel’s getMushroom() method to find out how many mushrooms the barrel currently stores. The pig can add this amount to its count of mushrooms eaten. Remember, the mushrooms are already gone from the world - this happened when the barrel “stored them.”
However if I try and go into the Pig class and use Barrel.getMushrooms(); it says non-static method getMushrooms() cannot be referenced from a static context.
But when I try using stuff like
Barrel b1 = new Barrel();
b1.getMushrooms();
My counter with shrooms never works out right..
Class Barrel
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.List;
/**
* Write a description of class Barrel here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class Barrel extends Actor
{
private final double SCALE_FACTOR_5 = 1.05;
private final double SCALE_FACTOR_25 = 1.25;
public int mushroomsStored;
private int ns;
public Barrel() {
mushroomsStored = 0;
ns = 0;
}
/**
* Main method of Barrel
*/
public void act() {
followMouse();
storeMushrooms();
reset();
}
/**
* Follows mouse drag-and-drop motion.
*/
public void followMouse() {
if(Greenfoot.mouseDragged(this)) {
MouseInfo mouse = Greenfoot.getMouseInfo();
setLocation(mouse.getX(), mouse.getY());
}
}
/**
* Eats nearby mushrooms when dropped.
* Increases its current image scale by 5% when it eats one mushroom.
* Increases its current image scale by 25% when it eats five mushrooms.
* If this barrel stores more than 10 mushrooms, this barrel has itself removed from
* this world.
*/
public void storeMushrooms() {
if(Greenfoot.mouseDragEnded(this)) {
List<Mushroom> nearby = getObjectsInRange(75, Mushroom.class);
ns = nearby.size();
for(Mushroom m : nearby) {
getWorld().removeObject(m);
mushroomsStored++;
}
if(ns < 5 ) {
GreenfootImage img = getImage();
int width = (int)(img.getWidth() * SCALE_FACTOR_5);
int height = (int)(img.getHeight() * SCALE_FACTOR_5);
img.scale(width, height);
}
if (ns >= 5) {
GreenfootImage img = getImage();
int width = (int)(img.getWidth() * SCALE_FACTOR_25);
int height = (int)(img.getHeight() * SCALE_FACTOR_25);
img.scale(width, height);
}
if(mushroomsStored == 10) {
getWorld().removeObject(this);
}
}
}
/**
* Returns this barrel to its original (x,y) location and its
* original image scale.
*/
public void reset() {
if(Greenfoot.mouseClicked(this)) {
MouseInfo mouse = Greenfoot.getMouseInfo();
if(mouse.getButton() == 3) {
this.setLocation(565, 350);
setImage(new GreenfootImage("barrel.png"));
mushroomsStored = 0;
}
}
}
/**
* Returns how many mushrooms this barrel has stored.
*/
public int getMushrooms() {
return mushroomsStored;
}
/**
* Automatically called by Greenfoot whenever a Barrel object
* is placed in a world. In this assigment, we use it to remember
* the initial state of this barrel - its (x,y) position and its
* original image size.
*/
public void addedToWorld(World world) {
GreenfootImage img = new GreenfootImage("barrel.png");
setImage(img);
final int originalX = getX();
final int originalY = getY();
final int originalWidth = img.getWidth();
final int originalHeight = img.getHeight();
}
}
Class Pig
import greenfoot.*; // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
/**
* Write a description of class Pig here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class Pig extends Actor
{
/** Keeps track of how many mushrooms this pig has eaten. */
private int shrooms;
/**
* Constructs a Pig object and initializes it as having
* eaten no mushrooms.
*/
public Pig() {
shrooms = 0;
}
/**
* Follows the mouse movement and eats mushrooms on mouse clicks.
* Stops the scenario once this pig has eaten at least 15 mushrooms.
*/
public void act()
{
followMouse();
eatMushrooms();
getMS();
}
public void getMS() {
b
}
public void followMouse() {
if (Greenfoot.mouseMoved(null)) {
MouseInfo mouse = Greenfoot.getMouseInfo();
setLocation(mouse.getX(), mouse.getY());
}
}
public void eatMushrooms() {
if (Greenfoot.mouseClicked(null)) {
Mushroom m = (Mushroom) getOneIntersectingObject(Mushroom.class);
if (m != null) {
shrooms++;
getWorld().removeObject(m);
}
}
if (shrooms > 29) {
Greenfoot.stop();
}
}
}
Your pig needs a reference to the barrel class. Typically in Greenfoot, class A gets a reference to class B in one of two ways:
Class A is passed the reference to B on creation. This is typical if B creates A: for example if a gun fires bullets, the gun passes a gun reference to the bullet.
Class A collides with class B, for example your player character runs into a collectable, or an enemy collides with your player.
I'm not certain, but I suspect you fall under case 2, in which case you want to use:
Barrel b = (Barrel)getOneIntersectingObject(Barrel.class);
The b variable will be null when you're not touching a barrel, and otherwise it will be a Barrel object which you can call methods on.
When calling the method with the class name like
Barril.getMushrooms()
Your method should be coupled to your class and not an instance. How would you do that? By making it a static method.
I assume that you want to have an instance method used in this context so the right way to do it is the one you presented :
Barril b = new Barril();
b.getMushrooms();
But think about it. What is the value of mushroomsStored if you just created your object?
... You guessed it. You did not even initialized it so it will return the value by default : 0
Related
I've been working on a cell evolution simulation in Java. Just so everyone knows, I'm a beginner/intermediate Java programmer. I know pretty much all the basics and then a little bit, but I don't quite have the skills to write code from scratch. The code I have here is roughly based on a source I found online, I added my own touches and some other pieces I found online as well. It seems to work just fine, except the screen flickers. It seems every time the repaint() is called it flickers, probably clearing and redrawing. It creates something that is practically impossible to look at. There are no errors in my code. I am new to using applets, so if there is a better way to do this, please let me know. How can I stop the screen from flickering? Is there an easy way to buffer the images to prevent that? Here's the class that draws the applet
/* <!-- Defines the applet element used by the appletviewer. -->
<applet code='CellLife.java' width='1920' height='1080'></applet> */
import java.applet.Applet;
import java.awt.Event;
import java.awt.Graphics;
import java.util.Enumeration;
import java.util.Vector;
public class CellLife extends Applet implements Runnable {
// ========================================================================
// VARIABLES
// ========================================================================
// Data
/** Thread object for CellLife applet */
private Thread m_cellLife = null;
// Static constants
/**
* the maximum number of creatures in the world. When the number of
* creatures alive drops below half this, a new one is created to bring the
* numbers back up.
*/
protected static final int MAX_CREATURES = 60;
// Data
/**
* A list of the creatures currently alive. Stores CLCreature references.
*/
protected Vector creatures;
/** The world is a rectangle from (0,0) to (limit.x,limit,y) */
protected CL2dVector limit;
/**
* The number of creatures that have been born since the simulation started
*/
protected long generations;
/** A test creature controllable by the user to allow response testing */
private CLCreature testCreature;
/** space-partitioning structure to speed collision detection */
protected CLBuckets buckets;
// ========================================================================
// METHODS
// ========================================================================
public CellLife() {
creatures = new Vector();
limit = new CL2dVector(500.0F, 500.0F);
generations = 0;
// initilaize our bucket structure
float bucketScale = CLCell.RADIUS; // could stretch to root-two times
// this
buckets = new CLBuckets(bucketScale, (int) Math.ceil(limit.x / bucketScale), (int) Math.ceil(limit.y / bucketScale));
}
public String getAppletInfo() {
return "Name: Cell Evolution\r\n" + "Author: Josh Marchand\r\n" + "Made in Eclipse";
}
// first time initialazion
public void init() {
resize((int) limit.x, (int) limit.y);
for (int i = 0; i < MAX_CREATURES; i++) {
CLCreature new_creature = new CLCreature();
new_creature.InitSimple(limit, buckets);
creatures.addElement(new_creature);
}
}
public void destroy() {
// TODO: Place applet cleanup code here
}
public void paint(Graphics g) {
g.drawString("No. creatures: " + creatures.size(), 0, 11);
g.drawString("Births: " + generations, 0, 22);
// draw cells
for (int i = 0; i < creatures.size(); i++) {
((CLCreature) creatures.elementAt(i)).Draw(g);
}
// DEBUG: also indicate the contents of the buckets
// buckets.Draw(g);
// get all creatures to do their stuff
CLCreature creature;
for (int i = 0; i < creatures.size(); i++) {
creature = (CLCreature) creatures.elementAt(i);
if (creature.DoTimeStep(g, buckets, limit) && creatures.size() < MAX_CREATURES) {
// inherit new creature from current
CLCreature newCreature = new CLCreature();
newCreature.InheritFrom(creature, buckets, limit);
creatures.addElement(newCreature);
generations++;
}
}
// delete the ones that died doing it
for (Enumeration e = creatures.elements(); e.hasMoreElements();) {
creature = (CLCreature) e.nextElement();
if (creature.hasDied) creatures.removeElement(creature);
}
// breed nwe creatures if pop. is low
if (creatures.size() < MAX_CREATURES / 2) {
// just add one for now,fix later
CLCreature newCreature = new CLCreature();
newCreature.InheritFrom((CLCreature) creatures.elementAt((int) Math.random() * creatures.size()), buckets, limit);
creatures.addElement(newCreature);
generations++;
}
}
public void start() {
if (m_cellLife == null) {
m_cellLife = new Thread(this);
m_cellLife.start();
}
// TODO: place any additional startup code here
}
public void stop() {
if (m_cellLife != null) {
m_cellLife.stop();
m_cellLife = null;
}
}
public void run() {
while (true) {
try {
repaint();
// quick nap here to allow user interface to catch up
Thread.sleep(100);
} catch (InterruptedException e) {
stop();
}
}
}
public boolean mouseDown(Event e, int x, int y) {
// create a single celled creature at specific loc
testCreature = new CLCreature();
testCreature.rootCell.location.x = x;
testCreature.rootCell.location.y = y;
testCreature.rootCell.type = CLGene.RED;
creatures.addElement(testCreature);
buckets.PutCell(testCreature.rootCell);
return true;
}
public boolean mouseDrag(Event e, int x, int y) {
testCreature.rootCell.location.x = x;
testCreature.rootCell.location.y = y;
return true;
}
public boolean mouseUp(Event evt, int x, int y) {
creatures.removeElement(testCreature);
buckets.RemoveCell(testCreature.rootCell);
return true;
}
}
Thank you all so much for the help, and I'm very sorry about my "noobiness", I am doing my best to teach myself!
I would consider using technique called double buffering, where you create an offscreen Graphics object bound to and Image, perform all the drawing on that then paint the result to screen.
You can find a handy tutorial on creating graphics from image here. More complete sample can be found here.
I have a program that runs edge detection on pictures that I load into Java. How can I take the processed image that Java returns, turn it into a JPG file, and save it?
At the moment, the program will turn each image into a Picture object. The edge detection works on that Picture object, and then returns the processed image. I have the main class below, and can upload the class that defines the Picture object if requested. I would like to be able to take the "swan" object here, turn it into a JPG file, and then save it.
import java.util.Scanner;
public class PictureTester
{
private static Scanner input = new Scanner(System.in);
public static void testEdgeDetection2()
{
Picture swan = new Picture("clone_1_water-timelapse_t0.jpg");
swan.edgeDetection2(10);
swan.explore();
}
public static void main(String[] args)
{
testEdgeDetection2();
}
}
Source code for Picture:
import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.text.*;
import java.util.*;
import java.util.List; // resolves problem with java.awt.List and java.util.List
/**
* A class that represents a picture. This class inherits from
* SimplePicture and allows the student to add functionality to
* the Picture class.
*
*/
public class Picture extends SimplePicture
{
///////////////////// constructors //////////////////////////////////
/**
* Constructor that takes no arguments
*/
public Picture ()
{
/* not needed but use it to show students the implicit call to super()
* child constructors always call a parent constructor
*/
super();
}
/**
* Constructor that takes a file name and creates the picture
* #param fileName the name of the file to create the picture from
*/
public Picture(String fileName)
{
// let the parent class handle this fileName
super(fileName);
}
/**
* Constructor that takes the width and height
* #param height the height of the desired picture
* #param width the width of the desired picture
*/
public Picture(int height, int width)
{
// let the parent class handle this width and height
super(width,height);
}
/**
* Constructor that takes a picture and creates a
* copy of that picture
* #param copyPicture the picture to copy
*/
public Picture(Picture copyPicture)
{
// let the parent class do the copy
super(copyPicture);
}
/**
* Constructor that takes a buffered image
* #param image the buffered image to use
*/
public Picture(BufferedImage image)
{
super(image);
}
////////////////////// methods ///////////////////////////////////////
/**
* Method to return a string with information about this picture.
* #return a string with information about the picture such as fileName,
* height and width.
*/
public String toString()
{
String output = "Picture, filename " + getFileName() +
" height " + getHeight()
+ " width " + getWidth();
return output;
}
public void edgeDetection2(int edgeDist)
{
Pixel topPixel = null;
Pixel bottomPixel = null;
Pixel[][] pixels = this.getPixels2D();
Color bottomColor = null;
for (int row = 0; row < pixels.length-1; row++)
{
for (int col = 0;
col < pixels[0].length; col++)
{
topPixel = pixels[row][col];
bottomPixel = pixels[row+1][col];
bottomColor = bottomPixel.getColor();
if (topPixel.colorDistance(bottomColor) >
edgeDist)
topPixel.setColor(Color.BLACK);
else
topPixel.setColor(Color.WHITE);
}
}
}
/* Main method for testing - each class in Java can have a main
* method
*/
public static void main(String[] args)
{
Picture beach = new Picture("beach.jpg");
beach.explore();
}
} // this } is the end of class Picture, put all new methods before this
the "picture" class is something that your class provided you, its not a built in class. that said i took a class in java at my college and they also gave me a class titled picture. try this
Picture myPicture = new Picture("input-file-name.jpg");
myPicture.write("name-for-new-file.jpg");
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm trying to program something in which a lobster can get eaten by a pelican, but the pelican must disappear after eating said lobster. What code would remove the Pelican from world?
The current (full) code is:
import greenfoot.*;
/**
* Write a description of class Pelican here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class Pelican extends Animal
{
/**
* Act - do whatever the Pelican wants to do. This method is called whenever
* the 'Act' or 'Run' button gets pressed in the environment.
*/
private boolean lobsterEaten=false;
public void act()
{
randomTurn();
turnAtEdge();
lookForLobster();
move();
}
public void randomTurn()
{
if(Greenfoot.getRandomNumber(100)<10)
{
turn(Greenfoot.getRandomNumber(91)-45);
}
}
public void turnAtEdge()
{
if(atWorldEdge())
{
turn(17);
}
}
public void lookForLobster()
{
eat(Lobster.class);
}
}
Animal code:
import greenfoot.*;
import java.util.List;
import java.util.ArrayList;
/**
* Animal. This is the base class for all animals. In addition to the standard Actor
* methods, it provides the ability to move and turn.
*
* #author Michael Kolling
* #version 1.0
*/
public class Animal extends Actor
{
private static final double WALKING_SPEED = 5.0;
/**
* Constructor for Animal - nothing to do.
*/
public Animal()
{
}
/**
* Act - empty method. Animals have no default action.
*/
public void act()
{
}
/**
* Turn 'angle' degrees towards the right (clockwise).
*/
public void turn(int angle)
{
setRotation(getRotation() + angle);
}
/**
* Move forward in the current direction.
*/
public void move()
{
double angle = Math.toRadians( getRotation() );
int x = (int) Math.round(getX() + Math.cos(angle) * WALKING_SPEED);
int y = (int) Math.round(getY() + Math.sin(angle) * WALKING_SPEED);
setLocation(x, y);
}
/**
* Test if we are close to one of the edges of the world. Return true is we are.
*/
public boolean atWorldEdge()
{
if(getX() < 20 || getX() > getWorld().getWidth() - 20)
return true;
if(getY() < 20 || getY() > getWorld().getHeight() - 20)
return true;
else
return false;
}
/**
* Return true if we can see an object of class 'clss' right where we are.
* False if there is no such object here.
*/
public boolean canSee(Class clss)
{
Actor actor = getOneObjectAtOffset(0, 0, clss);
return actor != null;
}
/**
* Try to eat an object of class 'clss'. This is only successful if there
* is such an object where we currently are. Otherwise this method does
* nothing.
*/
public void eat(Class clss)
{
Actor actor = getOneObjectAtOffset(0, 0, clss);
if(actor != null) {
getWorld().removeObject(actor);
}
}
}
You will want to call getWorld().removeObject(this); inside of your Pelican's lookForLobster method. Or you could override Pelican's eat() method and do it there, but only after calling super.eat(); first.
My question is: How do I access values from another thread?
I have two .java files, Main.java and TrackHands.java
Main.java
/**
* This is the main class, it is used to start the program. The only use of this
* is to make everything more organized.
*/
package Kinect;
//import processing.core.PApplet;
/**
* #author Tony Nguyen <Tony.Nguyen#HvA.nl>
*
*/
public class Main
{
public static void main(String _args[])
{
Thread trackHands = new Thread(new TrackHands());
trackHands.start();
}
}
TrackHands.java
/*
* This uses the normal Java layout to track the user and prints out the coordinates of the left and right hand
*/
package Kinect;
import SimpleOpenNI.*;
import processing.core.PApplet;
import processing.core.PVector;
/**
* #author Tony Nguyen <Tony.Nguyen#HvA.nl>
* #version 1.0
*/
public class TrackHands extends PApplet implements Runnable
{
private int handLeftX, handLeftY = 0; // Holds the coordinates of the left hand
SimpleOpenNI kinect = new SimpleOpenNI(this); // kinect object
/**
* Constructor Takes no parameters
*/
public TrackHands()
{
}
/**
* run This will be executed when the thread starts
*/
#Override
public void run()
{
IntVector userList = new IntVector(); // Make a vector of ints to store the list of users
PVector leftHand = new PVector(); // Make a vector to store the left hand
PVector convertedLeftHand = new PVector();
kinect.enableDepth();
kinect.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL);
kinect.setMirror(true);
while (true)
{
kinect.update();
kinect.getUsers(userList); // Write the list of detected users into the vector
if (userList.size() > 0) // Checks if a user is found
{
int userId = userList.get(0); // Get first user
if (kinect.isTrackingSkeleton(userId)) // If successfully calibrated
{
kinect.getJointPositionSkeleton(userId,
SimpleOpenNI.SKEL_LEFT_HAND, leftHand); // Put the position of the left hand into that vector
kinect.convertRealWorldToProjective(leftHand,
convertedLeftHand);
this.handLeftX = round(convertedLeftHand.x);
this.handLeftY = round(convertedLeftHand.y);
}
}
}
}
// User-tracking callbacks!
public void onNewUser(int userId)
{
System.out.println("Start pose detection");
kinect.startPoseDetection("Psi", userId);
}
public void onEndCalibration(int userId, boolean successful)
{
if (successful)
{
System.out.println(" User calibrated !!!");
kinect.startTrackingSkeleton(userId);
} else
{
System.out.println(" Failed to calibrate user !!!");
kinect.startPoseDetection("Psi", userId);
}
}
public void onStartPose(String pose, int userId)
{
System.out.println("Started pose for user");
kinect.stopPoseDetection(userId);
kinect.requestCalibrationSkeleton(userId, true);
}
}
I have tried to use a getter and a setter to get the values from TrackHands.java into another thread.
Tried creating objects and passing the values as parameters, but then my program will not use these new values in the run() method.
To get values from TrackHands, use a get method that accesses an instance variable that is set in run()
class TrackHands {
Object output;
public void run() {
while(true) {
output = new Object();
}
}
public Object getOutput() {
return output;
}
}
Pass TrackHands into your consumer object and use it to call get getOutput() method.
Passing values in is a bit trickier, because you might cause race condition. Try something like this
class TrackHands {
Object input = null;
public boolean setInput(Object input) {
if(this.input == null) {
this.input = input;
return true;
} else {
return false;
}
}
}
When your run() method uses input, set it to null so that another thread can pass in another input. Your producer thread will use this loop to pass in input:
public void sendInput(TrackHands th, Object input) {
boolean done = false;
while(!done) {
done = th.setInput(input);
}
}
This will keep trying to pass in input until it succeeds.
setInput uses the synchronized keyword so that only one thread can call this method at once, otherwise you'll get a race condition.
A friend of mine solved my problem.
I want to thank everyone for helping me!
Main.java
/**
* This is the main class, it is used to start the program. The only use of this
* is to make everything more organized.
*/
package Kinect;
//import processing.core.PApplet;
/**
* #author Tony Nguyen <Tony.Nguyen#HvA.nl>
*
*/
public class Main
{
public static void main(String _args[])
{
// PApplet.main(new String[]
// {
// Sensor.class.getName()
// });
ValueStore valueStore = new ValueStore(); // ADDED THIS LINE
Thread trackHands = new Thread(new TrackHands(valueStore)); // ADDED THIS LINE
trackHands.start();
}
}
TrackHands.java
/*
* This uses the normal Java layout to track the user and prints out the coordinates of the left and right hand
*/
package Kinect;
import SimpleOpenNI.*;
import processing.core.PApplet;
import processing.core.PVector;
/**
* #author Tony Nguyen <Tony.Nguyen#HvA.nl>
* #version 1.0
*/
public class TrackHands extends PApplet implements Runnable
{
private int handLeftX, handLeftY, handRightX, handRightY = 0; // Holds the coordinates of the left hand
SimpleOpenNI kinect = new SimpleOpenNI(this); // kinect object
private ValueStore valuesStore; // ADDED THIS LINE
/**
* Constructor Takes no parameters
*/
public TrackHands()
{
}
public TrackHands(ValueStore valuesStore)
{
this.valuesStore = valuesStore;
}
/**
* run This will be executed when the thread starts
*/
#Override
public void run()
{
IntVector userList = new IntVector(); // Make a vector of ints to store the list of users
PVector leftHand = new PVector(); // Make a vector to store the left hand
PVector rightHand = new PVector(); // Make a vector to store the right hand
PVector convertedLeftHand = new PVector(); // Make a vector to store the actual left hand
PVector convertedRightHand = new PVector(); // Make a vector to store the actual right hand
kinect.enableDepth();
kinect.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL);
kinect.setMirror(true);
while (true)
{
kinect.update();
kinect.getUsers(userList); // Write the list of detected users into the vector
if (userList.size() > 0) // Checks if a user is found
{
int userId = userList.get(0); // Get first user
if (kinect.isTrackingSkeleton(userId)) // If successfully calibrated
{
kinect.getJointPositionSkeleton(userId,
SimpleOpenNI.SKEL_LEFT_HAND, leftHand); // Put the position of the left hand into that vector
kinect.getJointPositionSkeleton(userId,
SimpleOpenNI.SKEL_RIGHT_HAND, rightHand); // Put the position of the left hand into that vector
kinect.convertRealWorldToProjective(leftHand,
convertedLeftHand);
kinect.convertRealWorldToProjective(rightHand,
convertedRightHand);
this.handLeftX = round(convertedLeftHand.x);
this.handLeftY = round(convertedLeftHand.y);
this.handRightX = round(convertedRightHand.x);
this.handRightY = round(convertedRightHand.y);
valuesStore.setHandValues(handLeftX, handLeftY, handRightX, handRightY); // ADDED THIS LINE
}
}
}
}
// User-tracking callbacks!
public void onNewUser(int userId)
{
System.out.println("Start pose detection");
kinect.startPoseDetection("Psi", userId);
}
public void onEndCalibration(int userId, boolean successful)
{
if (successful)
{
System.out.println(" User calibrated !!!");
kinect.startTrackingSkeleton(userId);
} else
{
System.out.println(" Failed to calibrate user !!!");
kinect.startPoseDetection("Psi", userId);
}
}
public void onStartPose(String pose, int userId)
{
System.out.println("Started pose for user");
kinect.stopPoseDetection(userId);
kinect.requestCalibrationSkeleton(userId, true);
}
}
Then added a class to store the values so another class can access it.
ValueStore.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package Kinect;
/**
*
* #author Tony Nguyen <Tony.Nguyen#HvA.nl>
*/
public class ValueStore
{
private int leftX, leftY, rightX, rightY = 0;
public void setHandValues(int leftX, int leftY, int rightX, int rightY)
{
this.leftX = leftX;
this.leftY = leftY;
this.rightX = rightX;
this.rightY = rightY;
}
public int getLeftX()
{
return this.leftX;
}
}
Problem: When a skeleton enters a place, I want all the Players screens updated using this method in my World object:
/**
* Say `text' in the Place `place'. The text will become visible at the
* bottom of the text window of any Players currently watching `place'.
*
* #param place
* The place where the string will be displayed.
* #param text
* The string to be diplayed.
*/
public void sayAtPlace(Place place, String text) {
synchronized (players) {
Iterator<Player> ls = players.iterator();
while (ls.hasNext()) {
Player p = ls.next();
if (p.currentPlace() == place) {
p.say(text);
}
}
}
}
I've got two classes, Person and Player and I want a Person to write to the textarea when the method goTo is called but I can't make the Person object have a proper reference to a Player that has the textarea:
package adventure;
import java.awt.*;
import java.util.*;
/**
* ADT for persons which is completed which subclasses to creating actors with
* specific properties
*/
public class Person {
public Player player = null;
/**
* Name of the Person.
*/
public String name;
/**
* The World which this Person is associated with.
*/
public World world;
/**
* Tells where this Person is at the moment.
*/
public Place where;
/**
* Create Person named `name' in world `world'.
*
* #param world
* The world where the Person is created.
* #param name
* Name of the Person.
* #param app
* An image used to display the Person.
*/
public Person(World world, String name, Image app) {
this.world = world;
this.name = name;
this.appearance = app;
// this.player = player;
where = world.defaultPlace();
where.enter(this);
inventory = Collections.synchronizedCollection(new LinkedList<Thing>());
}
/**
* Go directly, and quietly, to 'place'. That is to say, without posting a
* message that you're doing so.
*
* #param place
* A string referring to the Place to go to.
* #see #goTo(Place)
* #see #go
*/
public void goTo(String place) {
goTo(world.getPlace(place), null);
}
/**
* Go directly, and quietly, to `whereTo'. That is to say, without posting a
* message that you're doing so.
*
* #param whereTo
* The Place to go to. Can be null in which case nothing happens.
* #see #goTo(String)
* #see #go
*/
public void goTo(Place whereTo, Player player) {
if (whereTo != null) {
where.exit(this);
whereTo.enter(this);
// Update any Player's which are viewing place `where'.
world.update(where);
// Record our new position.
where = whereTo;
// Also update Player's here.
world.update(where);
}
System.out.println("player:"+player);
if(player != null){
player.say("A terrifying skeleton warrior appears!");
}
// send a msg which doors are available
Object[] doorNames = whereTo.exits.keySet().toArray();
String s = "";
int i = 1;
for (Object obj : doorNames) {
if (i < doorNames.length) {
s = s + obj.toString().toLowerCase();
if(i<doorNames.length){
s = s+ ",";
}
} if (i == doorNames.length && i > 1) {
s = s + " and " + obj.toString().toLowerCase();
}
if (i == doorNames.length && i == 1) {
s = obj.toString().toLowerCase();
}
++i;
}
if (player != null) {
player.say("There are doors " + s);
}
}
package adventure;
import java.awt.*;
/**
* A Player object enables commands to control a certain person: »you». This
* object is displayed graphically as a control panel where the user both can
* control and follow the course of events
*/
public class Player extends Panel {
private Person me;
private PlaceView placeview;
private Commands commands;
private TextArea textarea;
private static final long serialVersionUID = 100L;
/**
* Creates a new instance of Player, in World w, reflecting Person p.
*
* #param w
* The world in which the Player will play in.
* #param p
* The Person associated by Player.
*/
Player(World w, Person p) {
setLayout(new BorderLayout());
setSize(650, 540);
me = p;
p.player = this;
placeview = new PlaceView(me);
commands = new Commands(me);
textarea = new TextArea("", 10, 60, TextArea.SCROLLBARS_VERTICAL_ONLY);
textarea.append("You are in a dungeon. The horrible shrieks of the undead chill your bones.\n");
textarea.setEditable(false);
add("West", placeview);
add("East", commands);
add("South", textarea);
w.addPlayer(this);
}
/**
* Display a string in the players graphical interface.
*
* #param text
* A string to display.
*/
void say(String text) {
textarea.append(text + '\n');
textarea.repaint();
}
/**
* Returns the Place of the Person associated with the Player.
*
* #return The Place of the Person associated with the Player.
*/
public Place currentPlace() {
return me.where;
}
}
Do you understand what I'm trying to do? The code I want to work is
System.out.println("player:"+player);
if(player != null && this.name.equals("Skeleton")){
player.say("A terrifying skeleton warrior appears!");
}
But the player reference of the Person that is a zombie is not instanciated. The only Person who has a Player object instanciated is the Player that is also a Person.
Can you help me? I also posted the full versions of the Person, Player and World classes here
http://pastebin.com/RJCcr2ph (Person)
http://pastebin.com/eYSh8L9Q (Player)
http://pastebin.com/DKvRvEY8 (World)
If I understand your question well, you want to have 2 classes in which each class has a reference to the other. What you need is to create one of them (let it be Foo), create the other class (let it be Boo) and pass a reference of Foo to it via the constructor, and then set a reference of Boo inside Foo class via setter method.
For example:
public static void main(String[] args)
{
Foo f = new Foo();
Boo b = new Boo(f);
f.setBoo(b);
}
class Foo
{
private Boo b;
public Foo()
{
// ...
}
public void setBoo(Boo b)
{
this.b = b;
}
}
class Boo
{
private Foo f;
public Boo(Foo f)
{
this.f = f;
}
}
Now, Foo has a reference of Boo, and Boo has a reference of Foo :)
First , you should instantiate the Person's member 'player' in the constructor .
this.player = new Player(world, this);
Then , change the code from
public void goTo(String place) {
goTo(world.getPlace(place), null);
}
to
public void goTo(String place) {
goTo(world.getPlace(place), this.player);
}