Beginner: Adding a Teleport Room to World Of Zuul - java

I have a compsci lab in which we must complete the text adventure game "World of Zuul". To do this we had to complete several steps such as creating more rooms, creating an items class, and adding items to rooms. The final step is to add a Teleport room to the game. Here is the text from the project sheet:
Implement a “teleport room” that has an entrance but no exit. The
short description is “in a room with blank walls and no obvious exit”.
When you perform the look command in the teleport room, there is a 75%
chance that you will just stay in the teleport room and see the
description above. There is a 25% chance that you will teleport
randomly into one of the other N rooms and then you will see a
description of that room. You will need to think about re-organizing
the relationship between the Room class and the Game class to make
this happen.
I can't figure out how to do this. Any help is much appreciated.
Room Class:
import java.util.Set;
import java.util.HashMap;
import java.util.HashSet;
/**
* Class Room - a room in an adventure game.
*
* This class is part of the "World of Zuul" application.
* "World of Zuul" is a very simple, text based adventure game.
*
* A "Room" represents one location in the scenery of the game. It is
* connected to other rooms via exits. For each existing exit, the room
* stores a reference to the neighboring room.
*
* #author Michael Kölling and David J. Barnes
* #version 2011.08.08
*/
public class Room
{
private String description;
private HashMap<String, Room> exits; // stores exits of this room.
private HashSet<Item> items;
/**
* Create a room described "description". Initially, it has
* no exits. "description" is something like "a kitchen" or
* "an open court yard".
* #param description The room's description.
*/
public Room(String description)
{
this.description = description;
exits = new HashMap<String, Room>();
items = new HashSet<Item>();
}
/**
* Define an exit from this room.
* #param direction The direction of the exit.
* #param neighbor The room to which the exit leads.
*/
public void setExit(String direction, Room neighbor)
{
exits.put(direction, neighbor);
}
/**
* Add items into a room
* #param item The item which will be added to the room
*/
public void addItem(Item item)
{
items.add(item);
}
/**
* #return The short description of the room
* (the one that was defined in the constructor).
*/
public String getShortDescription()
{
return description;
}
/**
* Return a description of the room in the form:
* You are in the kitchen.
* Exits: north west
* #return A long description of this room
*/
public String getLongDescription()
{
return "You are " + description + ".\n" + getExitString() + "\n" + getItemString();
}
/**
* Return a string describing the room's exits, for example
* "Exits: north west".
* #return Details of the room's exits.
*/
private String getExitString()
{
String returnString = "Exits:";
Set<String> keys = exits.keySet();
for(String exit : keys) {
returnString += " " + exit;
}
return returnString;
}
/**
* Return a string describing the room's items and descriptions, for example
* "Items: Book, (insert description here".
* #return Details of the room's items.
*/
private String getItemString()
{
String itemString = "items: ";
if(items.size() < 1) {
itemString = itemString += "There are no items here.";
}
else {
for(Item item : items) {
itemString+= item.getName() + "; " + item.getDescription() + ". ";
}
}
return itemString;
}
/**
* Return the room that is reached if we go from this room in direction
* "direction". If there is no room in that direction, return null.
* #param direction The exit's direction.
* #return The room in the given direction.
*/
public Room getExit(String direction)
{
return exits.get(direction);
}
}
Game Class:
public class Game
{
private Parser parser;
private Room currentRoom;
/*
* Create the game and initialise its internal map.
*/
public Game()
{
createRooms();
parser = new Parser();
}
/**
* Create all the rooms and link their exits together.
*/
private void createRooms()
{
Room outside, theater, pub, lab, office, labyrinth, teleport_room;
Item book, stick, knife, spoon;
// create the rooms
outside = new Room("outside the main entrance of the university");
theater = new Room("in a lecture theater");
pub = new Room("in the campus pub");
lab = new Room("in a computing lab");
office = new Room("in the computing admin office");
labyrinth = new Room("in the University Labyrinth");
teleport_room = new Room("in a room with blank walls and no obvious exit");
//create the items
book = new Item("Book", "A book containing useless information", 5);
stick = new Item("Stick", "A large stick, can be used for protection", 10);
knife = new Item("Knife", "A dull butter knife", 5);
spoon = new Item("Spoon", "A tablespoon, good for consumption of cereal", 5);
// initialise room exits
outside.setExit("east", theater);
outside.setExit("south", lab);
outside.setExit("west", pub);
outside.setExit("north", labyrinth);
theater.setExit("west", outside);
pub.setExit("east", outside);
pub.setExit("west", labyrinth);
lab.setExit("north", outside);
lab.setExit("east", office);
office.setExit("west", lab);
office.setExit("north", teleport_room);
labyrinth.setExit("south", pub);
labyrinth.setExit("east", outside);
//initialize room items
outside.addItem(book);
labyrinth.addItem(stick);
lab.addItem(knife);
office.addItem(spoon);
currentRoom = outside; // start game outside
}
/**
* Main play routine. Loops until end of play.
*/
public void play()
{
printWelcome();
// Enter the main command loop. Here we repeatedly read commands and
// execute them until the game is over.
boolean finished = false;
while (! finished) {
Command command = parser.getCommand();
finished = processCommand(command);
}
System.out.println("Thank you for playing. Good bye.");
}
/**
* Print out the opening message for the player.
*/
private void printWelcome()
{
System.out.println();
System.out.println("Welcome to the World of Zuul!");
System.out.println("World of Zuul is a new, incredibly boring adventure game.");
System.out.println("Type 'help' if you need help.");
System.out.println();
System.out.println(currentRoom.getLongDescription());
}
/**
* Given a command, process (that is: execute) the command.
* #param command The command to be processed.
* #return true If the command ends the game, false otherwise.
*/
private boolean processCommand(Command command)
{
boolean wantToQuit = false;
if(command.isUnknown()) {
System.out.println("I don't know what you mean...");
return false;
}
String commandWord = command.getCommandWord();
if (commandWord.equals("help")) {
printHelp();
}
else if (commandWord.equals("go")) {
goRoom(command);
}
else if (commandWord.equals("look")) {
System.out.println(currentRoom.getLongDescription());
}
else if (commandWord.equals("quit")) {
wantToQuit = quit(command);
}
// else command not recognised.
return wantToQuit;
}
// implementations of user commands:
/**
* Print out some help information.
* Here we print some stupid, cryptic message and a list of the
* command words.
*/
private void printHelp()
{
System.out.println("You are lost. You are alone. You wander");
System.out.println("around at the university.");
System.out.println();
System.out.println("Your command words are:");
parser.showCommands();
}
/**
* Try to in to one direction. If there is an exit, enter the new
* room, otherwise print an error message.
*/
private void goRoom(Command command)
{
if(!command.hasSecondWord()) {
// if there is no second word, we don't know where to go...
System.out.println("Go where?");
return;
}
String direction = command.getSecondWord();
// Try to leave current room.
Room nextRoom = currentRoom.getExit(direction);
if (nextRoom == null) {
System.out.println("There is no door!");
}
else {
currentRoom = nextRoom;
System.out.println(currentRoom.getLongDescription());
}
}
/**
* "Quit" was entered. Check the rest of the command to see
* whether we really quit the game.
* #return true, if this command quits the game, false otherwise.
*/
private boolean quit(Command command)
{
if(command.hasSecondWord()) {
System.out.println("Quit what?");
return false;
}
else {
return true; // signal that we want to quit
}
}
}

You basically have to create a class "TeleporterRoom" that inherits from "Room"
Then you overwrite the method "getExit" in your new Class. This is where you calculate the probability of changing to another room.

Related

How to change the color of a selected word in a specific place, and also change the color of the same word, but in another place in JTextPane?

I am making a text editor, And i want to make it when the user type a article then if the user select a specific word then change it's color the color will be changed and also if the user select the same word but in another place this word's color only will be changed
As indicated in this picture:
because of all of my search results was that i change only a word's color even if it repeated it will be also colored
I am trying in JtextPane, I have searched in "Oracle Java Docs" for the JtextPane methodes but i didn't found anything
It is necessary to use JTextPane.
Just use new FindManager(yourTextPane, Color.RED);.
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import java.awt.Color;
import java.util.ArrayList;
/**
* #author Swimer
*/
public class FindManager {
/**
* Constructor
* #param pane Swing text pane
* #param selection The color to apply to characters similar to selection
*/
public FindManager(JTextPane pane, Color selection) {
Style selected = pane.getStyledDocument().addStyle("selection-text", null);
Style defaultStyle = pane.getStyledDocument().addStyle("default", null);
StyleConstants.setForeground(selected, selection);
pane.addCaretListener(e -> {
Runnable doHighlight = () -> {
try {
String selectedText = pane.getSelectedText();
String text = pane.getStyledDocument().getText(0, pane.getStyledDocument().getLength());
if (selectedText != null && selectedText.length() > 0) {
for (Integer string : getStrings(text, selectedText, pane.getSelectionStart())) {
pane.getStyledDocument().setCharacterAttributes(string, selectedText.length(), selected, true);
}
}else{
pane.getStyledDocument().setCharacterAttributes(0, text.length(), defaultStyle, true);
}
} catch (Exception exception) {
exception.printStackTrace();
}
};
SwingUtilities.invokeLater(doHighlight);
});
}
/**
* Get positions of similar words
* #param text The string to look for
* #param toFind What to look for
* #param ignore What to ignore
* #return List of similar word positions
*/
public static ArrayList<Integer> getStrings(String text, String toFind, int ignore){
ArrayList<Integer> out = new ArrayList<>();
int index = text.indexOf(toFind);
while (index >= 0 && index != ignore) {
out.add(index);
index = text.indexOf(toFind, index+toFind.length());
}
return out;
}
}

Need Help Animating Images in an HBox using JavaFX

I'm working on creating a simulation program for a game called Counter-Strike: Global Offensive, and I'm stuck on how I should animate certain images within an HBox. In the game, there are Weapon Cases containing various skins of different rarity. Upon clicking the 'Open' button, the possible items to win should start scrolling through the HBox. Think of it almost like Wheel of Fortune, where it begins fast and gradually slows down until it stops on 1 name, but in this case, instead of names there are items, and instead of a 'wheel', I have a horizontal HBox with images scrolling through. Here is a good example of what I'm trying to make: http://cases.goaggro.com/.
Currently, I have an instance of the ImageView class assigned to each individual weapon image that should be included in the total group of items to be rolled, and an array to hold all of these images. On the GUI, I have the HBox's max width and height set so that any 3 of these images placed inside the HBox from left to right fill its' volume perfectly. My first problem resides here. If I try to do something like
Hbox.getChildren().addAll(itemArray);
it will add the first 3 just fine, but will continue to add images beyond the boundaries of the HBox until reaching the main windows border. Is there any way to add more images into the HBox than the max displayed image count (being 3 due to the current HBox size I have set) while preventing them from exceeding the HBox boundaries and simply being hidden in the back?
The second question is, what would be the best way to go about animating each image inside of my HBox so that it scrolls towards the left but not beyond or outside of the HBox borders? I need the left-most image to slide left off the screen, while the middle image slides to the left position, and a new image slides in from the right to fill the right position, and repeat this at a speed that gradually slows to the point of landing on an item.
Currently, adding this code to the 'Open' button's event handler adds the images in item1, item2, and item3 correctly into the HBox. But if I exceed 3 images (like setting the HBox .addAll() to itemArray instead of the first 3 items individually, for example), it exceeds the HBox border and starts laying them on top of the scene until reaching the main windows border. NOTE: There are a total of 15 instances of the ImageView class (item1-item15) but I shortened the code to only 4, as well as the arrays contents to those 4, since the issue happens regardless when any more than 3 images are placed into the HBox.
public class Controller
{
#FXML
private HBox hBox;
public void openCaseAction(ActionEvent actionEvent)
{
final ImageView item1 = new ImageView(new Image(getClass().getResourceAsStream("../images/image1.png")));
final ImageView item2 = new ImageView(new Image(getClass().getResourceAsStream("../images/image2.png")));
final ImageView item3 = new ImageView(new Image(getClass().getResourceAsStream("../images/image3.png")));
final ImageView item4 = new ImageView(new Image(getClass().getResourceAsStream("../images/image4.png")));
final ImageView[] itemArray ={item1,item2,item3,item4};
hBox.getChildren().addAll(item1,item2,item3);
}
}
You probably want to use a custom layout for this rather than a HBox. Take a look at the Display Shelf example:
Download the Java 8 demos and samples from Oracle.
Extract the sample package.
Run the demo/javafx_samples/Ensemble8.jar program.
Type "Display Shelf" into the program's search bar.
View the Display Shelf example UI and source code.
Copy and modify as you see fit while respecting the original license terms.
It won't be exactly what you are looking for but it will be a much closer starting point than trying to animate items in a HBox.
Oracle DisplayShelf sample code:
/*
* Copyright (c) 2008, 2014, Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
* - Neither the name of Oracle Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package ensemble.samples.graphics2d.displayshelf;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.control.ScrollBar;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Region;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;
/**
* Simple 7 segment LED style digit. It supports the numbers 0 through 9.
*/
/**
* A ui control which displays a browse-able display shelf of images
*/
public class DisplayShelf extends Region {
private final Duration DURATION = Duration.millis(500);
private final Interpolator INTERPOLATOR = Interpolator.EASE_BOTH;
private final double SPACING = 50;
private final double LEFT_OFFSET = -110;
private final double RIGHT_OFFSET = 110;
private final double SCALE_SMALL = 0.7;
private PerspectiveImage[] items;
private Group centered = new Group();
private Group left = new Group();
private Group center = new Group();
private Group right = new Group();
private int centerIndex = 0;
private Timeline timeline;
private ScrollBar scrollBar = new ScrollBar();
private boolean localChange = false;
private Rectangle clip = new Rectangle();
public DisplayShelf(Image[] images) {
// set clip
setClip(clip);
// set ids for styling via CSS
setId("displayshelf");
scrollBar.setId("display-scrollbar");
// create items
items = new PerspectiveImage[images.length];
for (int i = 0; i < images.length; i++) {
final PerspectiveImage item =
items[i] = new PerspectiveImage(images[i]);
final double index = i;
item.setOnMouseClicked((MouseEvent me) -> {
localChange = true;
scrollBar.setValue(index);
localChange = false;
shiftToCenter(item);
});
}
// setup scroll bar
scrollBar.setMax(items.length - 1);
scrollBar.setVisibleAmount(1);
scrollBar.setUnitIncrement(1);
scrollBar.setBlockIncrement(1);
scrollBar.valueProperty().addListener((Observable ov) -> {
if (!localChange) {
shiftToCenter(items[(int) Math.round(scrollBar.getValue())]);
}
});
// create content
centered.getChildren().addAll(left, right, center);
getChildren().addAll(centered, scrollBar);
// listen for keyboard events
setFocusTraversable(true);
setOnKeyPressed((KeyEvent ke) -> {
if (ke.getCode() == KeyCode.LEFT) {
shift(1);
localChange = true;
scrollBar.setValue(centerIndex);
localChange = false;
} else if (ke.getCode() == KeyCode.RIGHT) {
shift(-1);
localChange = true;
scrollBar.setValue(centerIndex);
localChange = false;
}
});
// update
update();
}
#Override
protected void layoutChildren() {
// update clip to our size
clip.setWidth(getWidth());
clip.setHeight(getHeight());
// keep centered centered
centered.setLayoutY((getHeight() - PerspectiveImage.HEIGHT) / 2);
centered.setLayoutX((getWidth() - PerspectiveImage.WIDTH) / 2);
// position scroll bar at bottom
scrollBar.setLayoutX(10);
scrollBar.setLayoutY(getHeight() - 25);
scrollBar.resize(getWidth() - 20, 15);
}
private void update() {
// move items to new homes in groups
left.getChildren().clear();
center.getChildren().clear();
right.getChildren().clear();
for (int i = 0; i < centerIndex; i++) {
left.getChildren().add(items[i]);
}
center.getChildren().add(items[centerIndex]);
for (int i = items.length - 1; i > centerIndex; i--) {
right.getChildren().add(items[i]);
}
// stop old timeline if there is one running
if (timeline != null) {
timeline.stop();
}
// create timeline to animate to new positions
timeline = new Timeline();
// add keyframes for left items
final ObservableList<KeyFrame> keyFrames = timeline.getKeyFrames();
for (int i = 0; i < left.getChildren().size(); i++) {
final PerspectiveImage it = items[i];
double newX = -left.getChildren().size()
* SPACING + SPACING * i + LEFT_OFFSET;
keyFrames.add(new KeyFrame(DURATION,
new KeyValue(it.translateXProperty(), newX, INTERPOLATOR),
new KeyValue(it.scaleXProperty(), SCALE_SMALL, INTERPOLATOR),
new KeyValue(it.scaleYProperty(), SCALE_SMALL, INTERPOLATOR),
new KeyValue(it.angle, 45.0, INTERPOLATOR)));
}
// add keyframe for center item
final PerspectiveImage centerItem = items[centerIndex];
keyFrames.add(new KeyFrame(DURATION,
new KeyValue(centerItem.translateXProperty(), 0, INTERPOLATOR),
new KeyValue(centerItem.scaleXProperty(), 1.0, INTERPOLATOR),
new KeyValue(centerItem.scaleYProperty(), 1.0, INTERPOLATOR),
new KeyValue(centerItem.angle, 90.0, INTERPOLATOR)));
// add keyframes for right items
for (int i = 0; i < right.getChildren().size(); i++) {
final PerspectiveImage it = items[items.length - i - 1];
final double newX = right.getChildren().size()
* SPACING - SPACING * i + RIGHT_OFFSET;
keyFrames.add(new KeyFrame(DURATION,
new KeyValue(it.translateXProperty(), newX, INTERPOLATOR),
new KeyValue(it.scaleXProperty(), SCALE_SMALL, INTERPOLATOR),
new KeyValue(it.scaleYProperty(), SCALE_SMALL, INTERPOLATOR),
new KeyValue(it.angle, 135.0, INTERPOLATOR)));
}
// play animation
timeline.play();
}
private void shiftToCenter(PerspectiveImage item) {
for (int i = 0; i < left.getChildren().size(); i++) {
if (left.getChildren().get(i) == item) {
int shiftAmount = left.getChildren().size() - i;
shift(shiftAmount);
return;
}
}
if (center.getChildren().get(0) == item) {
return;
}
for (int i = 0; i < right.getChildren().size(); i++) {
if (right.getChildren().get(i) == item) {
int shiftAmount = -(right.getChildren().size() - i);
shift(shiftAmount);
return;
}
}
}
public void shift(int shiftAmount) {
if (centerIndex <= 0 && shiftAmount > 0) {
return;
}
if (centerIndex >= items.length - 1 && shiftAmount < 0) {
return;
}
centerIndex -= shiftAmount;
update();
}
}
/*
* Copyright (c) 2008, 2014, Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
* - Neither the name of Oracle Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package ensemble.samples.graphics2d.displayshelf;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.scene.Parent;
import javafx.scene.effect.PerspectiveTransform;
import javafx.scene.effect.Reflection;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
/**
* A Node that displays a image with some 2.5D perspective rotation around the Y
* axis.
*/
public class PerspectiveImage extends Parent {
private static final double REFLECTION_SIZE = 0.25;
public static final double WIDTH = 200;
public static final double HEIGHT = WIDTH + (WIDTH * REFLECTION_SIZE);
private static final double RADIUS_H = WIDTH / 2;
private static final double BACK = WIDTH / 10;
private PerspectiveTransform transform = new PerspectiveTransform();
/**
* Angle Property
*/
public final DoubleProperty angle = new SimpleDoubleProperty(45) {
#Override
protected void invalidated() {
// when angle changes calculate new transform
double lx = (RADIUS_H - Math.sin(Math.toRadians(angle.get())) * RADIUS_H - 1);
double rx = (RADIUS_H + Math.sin(Math.toRadians(angle.get())) * RADIUS_H + 1);
double uly = (-Math.cos(Math.toRadians(angle.get())) * BACK);
double ury = -uly;
transform.setUlx(lx);
transform.setUly(uly);
transform.setUrx(rx);
transform.setUry(ury);
transform.setLrx(rx);
transform.setLry(HEIGHT + uly);
transform.setLlx(lx);
transform.setLly(HEIGHT + ury);
}
};
public final double getAngle() {
return angle.getValue();
}
public final void setAngle(double value) {
angle.setValue(value);
}
public final DoubleProperty angleModel() {
return angle;
}
public PerspectiveImage(Image image) {
ImageView imageView = new ImageView(image);
Reflection reflection = new Reflection();
reflection.setFraction(REFLECTION_SIZE);
imageView.setEffect(reflection);
setEffect(transform);
getChildren().addAll(imageView);
}
}

Press [enter] to start the game, no error

I am trying to get a function where, when you press enter, you start the game, but it isn't working. There is no error.
I have followed a tutorial.
here is my code:
import greenfoot.*;
/**
* Write a description of class Menu here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class Menu extends World
{
/**
* Constructor for objects of class Menu.
*
*/
public Menu()
{
// Create a new world with 600x400 cells with a cell size of 1x1 pixels.
super(800, 500, 1);
prepare();
}
public void start()
{
{
if(Greenfoot.isKeyDown("ENTER"))
{
MinionWorld MinionWorld= new MinionWorld();
Greenfoot.setWorld(MinionWorld);
}
}
}
/**
* Prepare the world for the start of the program. That is: create the initial
* objects and add them to the world.
*/
private void prepare()
{
Controls controls = new Controls();
addObject(controls, 300, 100);
controls.setLocation(175, 50);
}
}
if(Greenfoot.isKeyDown("ENTER"))
Change this line to
if(Greenfoot.isKeyDown("enter"))
Key name for Enter is "enter" all small-caps.
Your code check if the Enter button is pressed at the moment it is run. You should use a KeyListener to catch the 'Enter' pressed event. If you are not using a GUI you can just use a Scanner and wait for the user to press Enter:
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
This will wait until the user press Enter.
With your actual code now, what's happening is that when you call start(), it's checking ONCE, at the time you called start() if the user pressed enter.
One thing you can do is to put the code of your start method in a while loop, which will make it checking if the user pressed enter all the time, and when the condition is met, you can break the while loop to end the start method.
Here is an example of code:
public void start()
{
while(true){
if(Greenfoot.isKeyDown("ENTER"))
{
MinionWorld MinionWorld= new MinionWorld();
Greenfoot.setWorld(MinionWorld);
break; // Ends the loop
}
}
}

extensive symbol/method/variable confusion

I am working on a project that creates a simple text-based adventure game. It's a little complicated, but basically there are about eight rooms in the game, each with a certain item. You can only move in certain directions depending on the room, and the goal is to get to the last room. I have a class called Item, a class called Room, and then the main Game class.
Anyway, I'm having some trouble with my checkForItem and drop methods at this point. I have to check my itemsHeld ArrayList for a certain item, but whenever I type in "item" it says it can't find the symbol item. Similar issues arise with my drop method. Any suggestions? Here is the (very lengthy) code.
import java.util.ArrayList;
public class Game
{
private ArrayList<Item> itemsHeld = new ArrayList<Item>();
private Room planetHarvest;
private Room planetReach;
private Room alphaHalo;
private Room newMombasa;
private Room deltaHalo;
private Room voi;
private Room theArk;
private Room forerunnerShieldWorld;
private Item DMR;
private Item Launcher;
private Item Shotgun;
private Item Health;
private Item Key;
private Room currentLocation;
private String msg;
public Game(){
createRooms();
ArrayList<Item> itemsHeld = new ArrayList<Item>(0);
currentLocation = planetHarvest;
}
private void createRooms(){
DMR = new Item("DMR", "The Designated Marksman Rifle fires a medium-range shot that defeats one enemy at a time.",
10, false);
Launcher = new Item("Launcher", "The rocket launcher fires a long-range rocket that defeats two enemies at a time.",
30, false);
Shotgun = new Item("Shotgun", "The shotgun fires a short-range buckshot blast that defeats one enemy at a time.",
10, false);
Health = new Item("Health", "The health pack heals you if you've been attacked.", 10, true);
Key = new Item("Key", "The Key is the secret to saving the galaxy.", 10000, false);
planetHarvest = new Room("a farming colony at the edge of human-controlled space. Though usually quiet, it has now been disturbed by an invasion from extraterrestrials who call themselves the Covenant. The Covenant will not let you escape without a fight.", DMR);
planetReach = new Room("twenty-seven years in the future. The Covenant has invaded every human colony world and bombarded each one with plasma, reducing the surface to molten glass. Planet Reach is the only human colony that remains. The aliens know their campaign to exterminate humanity is almost over and they show it in their ferocity on the battlefield.", Launcher);
alphaHalo = new Room("a strange, alien, planet-sized ring following your escape from the doomed planet Reach. The inside of the mysterious non-Covenant hoop structure has continents, oceans, ecosystems, breathable atmosphere – and two relentless foes. The Covenant has arrived; so has the Flood, a terrifying alien parasite that will eat both you and the Covenant. On top of that, you learn that this Halo is not just a habitat but also a weapon that will destroy all life in the galaxy if you don’t stop it.", Key);
newMombasa = new Room("an African city on Earth, humanity's last safe haven in the universe. A Covenant invasion force has landed. You’ll need to fend them off and follow them to wherever they’re headed next.", Health);
deltaHalo = new Room("where the Covenant and the Flood are already waiting. The same rules from Alpha Halo apply here, but now you learn that there are a total of eleven Halos and that the only way to stop them all is to shut them down from a structure outside the galaxy called the Ark. Meanwhile, the Covenant is still attacking Earth.", Key);
voi = new Room("The Flood has arrived and is infecting humans and aliens; meanwhile, the Covenant is in civil war and some of the aliens are helping you. Following your escape from Delta Halo, all of the Halos in the galaxy have been put on standby, so if you don’t find the Ark soon then it’s the end of life as we know it.", Shotgun);
theArk = new Room("a massive installation many times bigger than even a Halo. Shutting down the Ark will mean saving the galaxy. However, most of the Covenant and the Flood are still after you. Finish the fight.", Key);
forerunnerShieldWorld = new Room("an artificial planet made by a super-advanced alien civilization that disappeared 100,000 years ago – the makers of the Halos and the Ark. The war against the Covenant is finally over, the Flood has been defeated, and the galaxy is safe. The mysteries of the Forerunners, however, are just beginning to be unraveled.");
planetHarvest.addNeighbor("Slipspace Forward", planetReach);
planetReach.addNeighbor("Slipspace Out", alphaHalo);
alphaHalo.addNeighbor("Slipspace Back", planetReach);
alphaHalo.addNeighbor("Slipspace Forward", newMombasa);
newMombasa.addNeighbor("Slipspace Out", deltaHalo);
newMombasa.addNeighbor("Forward", voi);
deltaHalo.addNeighbor("Slipspace Back", newMombasa);
voi.addNeighbor("Slipspace Out", theArk);
voi.addNeighbor("Back", newMombasa);
theArk.addNeighbor("Slipspace Unknown", forerunnerShieldWorld);
}
private void setWelcomeMessage(){
msg = "You are John-117, an augmented soldier fighting for Earth and its colonies in the year 2552. You battle the Covenant, an alien religious alliance, and the Flood, an alien parasite that infects both humans and Covenant and turns them into zombies. Your battles take you to planetary colonies like Harvest and Reach, ancient alien ring-worlds called Halos, futuristic cities in Africa, and the Halos’ control station called the Ark, located outside the galaxy. The goal of the game is to defeat all enemies and make it to the safety of the Forerunner Shield World.";
}
public String getMessage(){
return msg;
}
public void help(){
msg = "Every place you enter is crawling with Covenent and/or Flood. You'll have to neutralize them before they neutralize you. As a Reclaimer, you're the only one who can use Keys on a Halo or Ark. Some places involve more than one mission.";
}
public void look(){
msg = currentLocation.getLongDescription();
}
public void move (String direction){
Room nextRoom = currentLocation.getNeighbor(direction);
if (nextRoom == null){
msg = "You can't go there.";
}else{
currentLocation = nextRoom;
msg = currentLocation.getLongDescription();
}
}
public void list(){
if(itemsHeld != null){
msg += itemsHeld;
}else{
msg = "You are not holding anything.";
}
}
public boolean gameOver(){
if(currentLocation == forerunnerShieldWorld){
msg = "You defeated the Covenant and survived the war. You won!";
}
return false;
}
public void pickup(){
if(currentLocation.hasItem()){
if(currentLocation.getItem().getWeight() < 50){
msg = "You are now holding the" + currentLocation.getItem().getName();
itemsHeld.add(currentLocation.getItem());
currentLocation.removeItem();
}else{
msg = "This item is too heavy to pick up.";
}
}else{
msg = "There is no item to pick up.";
}
}
private Item checkForItem (String name){
if(itemsHeld.contains(name)){
return ();
}else{
return null;
}
}
public void drop (String item){
if(itemsHeld.contains(item)){
itemsHeld.remove(item);
currentLocation.addItem;
}
}
}
Item is the type in this case. Not the variable name, which is what you want. You have several variables of type Item, but no variables named item.
Also, you have no field named itemsHeld. In your constructor you create a local variable with that name, but a variable by that name on the class is not defined.
Add
private ArrayList<Item> itemsHeld
to your field declarations, and in the constructor do
itemsHeld = new ArrayList<Item>(0);
to initialize it.
Or just do
private List<Item> itemsHeld = new ArrayList<Item>(0);
in your field declarations...
if(!PlayerLocation.hasItem()){
msg = "The player does not have that Item";
}
if(PlayerLocation.hasItem()){
for(Item lookfor: ItemsHeld){
String result = lookfor.getName();
if(result.contains(PlayerLocation.getItem().getName())){
msg = "The room already has an item " +
PlayerLocation.getItem().getName() +
".";
}
}
}
else {
for(Item lookfor: ItemsHeld){
String result = lookfor.getName();
if(result.contains(name)){
dropped = lookfor;
ItemsHeld.remove(lookfor);
PlayerLocation.addItem(dropped);
msg = "the player has successfully" +
"dropped the item in the room";
}
}
}
Idk if we have the same java teacher, but I was googling around
and browsing the interwebs for some answers and came accross your question.
Mine method works for droping the item; however, I'm degubbing my code for if the array list is empty, and has no items for it.

Problem with maze solving backtracking algorithm with setting visited rooms

i seek if somebody could help me out with my room searching algorithm
I'm trying to implement a backtracking algorhitm for maze solving. I'm stuck in the place where i should memorize the rooms which i have already visited.
The maze is made up from rooms and each room has 4 sides - north, east, south and west. Each room is linked to next room by making a door to desired side, i.e room1.createNorth(roomName) which creates a new room up north and a new room has southern door to link back to the first as you can see in my Room class.
Here is my chopped room class, which represents each room in a maze. I removed south, west and east directions which are identical to my methods which deal with northern side.
public class Room {
private String name;
private Room north;
private Room east;
private Room west;
private Room south;
private boolean isExit = false;
private Maze maze;
/**
* #return name room
*/
public String getName() {
return this.name;
}
/**
* Sets room name
*
* #param name
*/
public void setName(String name) {
this.name = name;
}
/**
* Gets northern room if any
*
* #return pointer to northern room if any, otherwise <code>null</code>
*/
public Room getNorth() {
return this.north;
}
/**
* Sets the door to the next room to the north in that room and in the other
* room sets southern door as connecting back to that room
*
* #param otherRoom
*/
public void setNorth(Room otherRoom) {
this.north = otherRoom;
otherRoom.south = this;
}
/**
* creates a new room to the north and connects back to this room
*
* #param name
* of the room
* #return created room
*/
public Room createNorth(String name) {
Room otherRoom = null;
// create new room in that direction ONLY if there is no room yet
if (this.getNorth() == null) { // get northern direction, if it's null,
// then it's okay to create there
otherRoom = new Room(); // create!
this.setNorth(otherRoom); // set the door
otherRoom.setName(name); // set the name
} else { // there is a room in that direction, so don't create a new
// room and drop a warning
System.out.println("There is already a room in northern direction");
}
return otherRoom;
}
/**
* Asdf
*
* #return maze
*/
public Maze getMaze() {
return this.maze;
}
/**
* Set maze
*
* #param maze
*/
public void setMaze(Maze maze) {
this.maze = maze;
}
/**
* #param roomName path to this room must be found
*/
public void findPathTo(String roomName) {
Room soughtRoom = this.getMaze().getEntry();
while (!(soughtRoom.getName().equalsIgnoreCase(roomName))) {
// here should be also a method such as setRoomAsVisited()
if (this.getWest() != null) {
soughtRoom = this.getWest();
this.getMaze().getPaths().push(soughtRoom);
}
else if (this.getNorth() != null) {
soughtRoom = this.getNorth();
this.getMaze().getPaths().push(soughtRoom);
}
else if (this.getEast() != null) {
soughtRoom = this.getEast();
this.getMaze().getPaths().push(soughtRoom);
}
else if (this.getSouth() != null) {
soughtRoom = this.getSouth();
this.getMaze().getPaths().push(soughtRoom);
}
else {
if (this.getMaze().getPaths().isEmpty()) {
break; // no more path for backtracking, exit (no solution found)
}
// dead end, go back!
soughtRoom = this.getMaze().getPaths().pop();
}
System.out.println(this.getMaze().getPaths().toString());
}
}
#Override
public String toString() {
return "Room name is " + this.getName();
}
}
Maze looks like this: http://i.stack.imgur.com/2KePs.jpg where S is the start point
My Maze class
public class Maze {
Room room;
/**
* helper collection path stack for findPathTo() method
*/
private Stack<Room> paths = new Stack<Room>();
/**
* #return path for exit
*/
public Stack<Room> getPaths() {
return this.paths;
}
/**
* Singleton method for first room in the maze which is entry room
*
* #return room if no room is created then creates new, otherwise returns
* already created room
*/
public Room getEntry() {
if (this.room == null) {
this.room = new Room();
return this.room;
}
return this.room;
}
}
Here is my main class
public class Main {
public static void main(String[] args) {
Maze maze = new Maze();
maze.getEntry().setName("A4"); // set first room's name A4
// labyrinth creation
maze.getEntry().createEast("B4").createNorth("B3").createWest("A3");
maze.getEntry().getEast().getNorth().createNorth("B2").createWest("A2")
.createNorth("A1");
maze.getEntry().getEast().getNorth().getNorth().createNorth("B1");
maze.getEntry().getEast().getNorth().getNorth().createEast("C2")
.createNorth("C1").createEast("D1");
maze.getEntry().getEast().createEast("C4").createEast("D4");
maze.getEntry().getEast().getEast().createNorth("C3").createEast("D3")
.createNorth("D2").setExit(true);
System.out.println("=====Test findPathTo method======");
maze.getEntry().setMaze(maze); // set maze instance to our entrance room
maze.getEntry().findPathTo("B4");
System.out.println("=====End of testing findPathTo method======");
}
}
The problem is in my findPathTo(roomName) method, which finds the route to the room.
If i enter the room D4 then my algorithm moves only once to east to "B4" room from "A4" and there it just loops infinitely and the stack just grows with room "B4" only. Why doesn't it move ahead for example to next room "B3" or "C4" ?
EDIT: here is the working code
public void findPathTo(String roomName) {
Room soughtRoom = this.getMaze().getEntry();
while (!(soughtRoom.getName().equalsIgnoreCase(roomName))) {
if (soughtRoom.getWest() != null && soughtRoom.getWest().isVisited != true) {
this.getMaze().getPaths().push(soughtRoom);
soughtRoom = soughtRoom.getWest();
soughtRoom.isVisited = true;
}
else if (soughtRoom.getNorth() != null && soughtRoom.getNorth().isVisited != true) {
this.getMaze().getPaths().push(soughtRoom);
soughtRoom = soughtRoom.getNorth();
soughtRoom.isVisited = true;
}
else if (soughtRoom.getEast() != null && soughtRoom.getEast().isVisited != true) {
this.getMaze().getPaths().push(soughtRoom);
soughtRoom = soughtRoom.getEast();
soughtRoom.isVisited = true;
}
else if (soughtRoom.getSouth() != null && soughtRoom.getSouth().isVisited != true) {
this.getMaze().getPaths().push(soughtRoom);
soughtRoom = soughtRoom.getSouth();
soughtRoom.isVisited = true;
}
else {
if (this.getMaze().getPaths().isEmpty()) {
System.out.println("No solutions found :(");
break; // no more path for backtracking, exit (no solution found)
}
// dead end, go back!
soughtRoom = this.getMaze().getPaths().pop();
}
System.out.println("Path rooms: " + this.getMaze().getPaths().toString());
}
}
There are several ways of doing this.
One would be to keep a "isVisited" boolean flag in each room object that you set/unset as your tracking and backtracking proceeds. This means taht you can only single-thread-search your maze (this may or may not matter).
Another would be to keep a list of visited rooms that you compare to (advantage here is that it should be relatively easy to just "push" a new room onto the list and have it popped automatically if you use the call-stack to pass this list).
You could also use a per-search hashtable of room to an isVisible, this allows for (possibly) faster lookups than searching a list, allows for multi-threading (as in "more than one thread can search the maze", not "more than one thread can participate in the same search").
There's also probably a few things I haven't thought of, but all three of these should be pretty straight-forward to implement.
A quick and highly unoptimized approach:
For each visited room, store the possible directions (make an enum Direction and a Set<Direction> for example) and remove the one you came from as well as the direction you took from the previous room. Thus, moving from A4 to B4 you'd remove EAST from A4 and WEST from B4. If you have to track back, just unwind the stack until you find a room with an unvisited direction (the list of possible directions is not empty) and try the next one. If the stack becomes empty at this point, you tried all possibilities without finding the target room.
As I said this is highly unoptimized, but it should work.
Some comments:
Your code is missing some functions you are using. There is no getPaths() method in your maze class. If you post code online, try to make sure it is easily compilable and testable. In your case I would have to guess, that getPaths() returns some kind of stack on which you try to store possible paths to be explored, but there is no way to be sure, what it actually does.
Also try to simplify the code before posting. Your maze is rather complicated and one would have to draw it, to see if your constructed maze matches the one on the picture. Try if you can reproduce the problem with a much simpler maze (2 or 3 rooms maybe). Also simplifying will often give you many hints as to where the problem might be. While you are simplifying there will be a point at which the problem will suddenly disappear. This tells you a lot about the actual bug.
Some Ideas on what might be wrong with your Code:
At each direction you set soughtRoom to the one in that direction. I am assuming soughtRoom is the room your search is currently at. Then you push that room on the stack. However for a backtracking you need to store at each branch all the information that brings you back to a previous state. If you first set the current room and then push it, the information from the previous state is lost. Try it the other way round and see what happens.

Categories

Resources