I have a variable private Point _centralStation which located in class that I called her City.
the user in the main class decides which value will be to the location of the centralStation.
So he put for example:
Point center = new Point(5,5) .
I want to create a method who called MoveCentralStation(int x, int y)
that moves the location from his last value to the new one, but
the new points have to be in the first quarter of the x,y axis.
I mean x cannot be -4 for example.
let's say for the exmaple it was 5,5
and now the user entered -4,5
how can I deal with the x and y new values sepertely?
Thank you
You have to explain yourself a little better. However, this is what I understood.
You have such a class:
class City{
private Point _centralStation;
public City(){
this._centralStation = new Point(5,5);
//the initialization you specified
}
public void moveCentralStation(int new_x, int new_y){
//TODO exactly what you have to implement
}
public Point getCentralStation(){
//since you are not implementing just getters and setters you rather do
return new Point(_centralStation.x,_centralStation.y);
//instead of return _centralStation [this is what we call defensive copies]
}
}
Well, somewhere in the code, a client would call
City c = new City();
c.moveCentralStation(x,y); //given x,y are variables in the client's context
And these are the requirements for the moveCentralStation(int x, int y) operation:
x coordinate shall be positive
y coordinate shall be positive
First of all I suggest you to follow style conventions on the way you code: use capital letters only for the class names. Let's jump into the real problem.
We need to refine the above requirements to make a specific implementation compliant with them. They aren't clear enough. An example of refinining i may suggest is the following:
If x coordinate is less than zero, an IllegalArgumentException shall be thrown
If y coordinate is less than zero, an IllegalArgumentException shall be thrown
And that's very simple to implement:
public void moveCentralStation(int new_x, int new_y){
if(new_x < 0) throw new IllegalArgumentException("x must be positive");
if(new_y < 0) throw new IllegalArgumentException("y must be positive");
_centralStation.x = new_x;
_centralStation.y = new_y;
}
It's a good practice to set private fields only when they are all consistants.
Related
Let's say we have a 2D-boolean Array as a presentation of a maze, the size of the Array is not fixed and random. The walls are depicted as true:
boolean[][] mazeArray = new boolean[width][height];
The exit of the maze is at a fixed Index. How can I check wether the traversion has reached this certain index or not?
My idea was to create an int[ ] to keep track of the position, it gets updated and overwritten with every step:
int[] location = {1,0};
... But I don't understand why my check in the while-loop doesn't work:
while( location[0] != (maze[0].length-1) && location[1] != (maze[1].length-2) ) {
// traversion with pledge algorithm
}
You're making everything so much harder for yourself. Go easier ways.
Use simpler locations handling
Instead of a location[], simlpy use int destinyX and int destinyY. And as your current position, you should use int positionX and int positionY.
If you'd like the OO-stlye more, or maybe wanna keep the gates open for a solution in 3D or n-D, you could introduce a Location class that has X and Y, and all movement and checks could be handled by that class. Then you'd have Location targetLocation = new Location(x,y); and your current position as Location currentPosition = new Location(x,y);. You then could check with if (currentPosition.equals(targetLocation))...; or in your case while(!currentPosition.equals(targetLocation)) {...}
It seems you have misunderstood the array.length function, or you're using it in an awfully inconvenient way.
At the moment you're blindly shooting at the array lengths of maze[]. This is bad for 2 reasons:
array lengths should not have anything to do with positions inside the array (logical paradox), and
because you could never freely move your destination, it would always stick to the right or bottom outsides of the maze
Use the positioning above, this will clear up that problem.
Suggestion: use a byte[][] or enum[][] for maze
At the moment, you only know if you have a wall at a certain location. If you wanna include other elements, like water, treasure, or the target location, wormholes etc, then you should either:
Use a byte[][] and fill it with values
value 0 could be pathways
value 1 could be walls
value 2 could be the exit
value 3 could be the water etc.
Use constants, like static public final int WATER_CODE = 3;
Or, alternatively, create your own enum:
public enum LocationType {PATH, WALL,EXIT,WATER}
and then have maze be like:
LocationType[][] mazeArray = new LocationType[width][height];
and everything is PATH in the beginning, and you can set up WALLS like this:
mazeArray[x][y] = LocationType.WALL;
or water:
mazeArray[x][y] = LocationType.WATER;
Use class or interface for maze[][]
For the sake of Wormhole or extended functionality, you could also use a class instead of an enum:
abstract class LocationType {}
and then implement certain types, like
class Wall extends LocationType {}
or even
class Wormhole extends LocationType {
public Location leadsTo() { /* */ };
}
and
class Treasure extends LocationType {
public int getAmoundOfGoldCoinsFound() { /* */ };
}
If you implement LocationType as an interface, replace 'extends' by 'implements'
The problem with your code is that you check wrong items in your maze array:
maze[0] is the first "line" of your 2d-array
maze[1] is the second "line" of your 2d-array
Proper way of traversing 2d-array is following (I've replaced your location array with separate x and y variables to better visualize the algorithm).
My algorithm enters the 2d mazeArray line by line and then iterates each line's elements.
public class Maze {
public static void main(String[] args) {
int width = 20;
int height = 20;
boolean[][] mazeArray = new boolean[width][height];
int x = 0;
int y = 0;
while (y < mazeArray.length) {
while (x < mazeArray[y].length) {
System.out.println("Traverse at (" + x + ", " + y + ")");
x += 1;
}
x = 0;
y += 1;
}
}
}
I am pretty new in Java. I am developing a Java console application which has a field and a frog jumping around in it, the user decides the size of the field through input in a 2d array, (kind of like a chess board but the difference is that the user decides how big the field should be). For instance the users enter height of field in feet and the width in feet. So far I have managed to do a bit of the class Field and class Position, which takes input from user and puts it on a array (int [][]fieldsize).
Class Controller:
package project;
public class Controller {
public static void main( String[] args ) {
Field field = new Field();
Position position = new Position();
}
}
Class Field:
package project;
import java.util.Scanner;
public class Field{
int y;
int x;
int[][] fieldsize;
public Field() {
Scanner scan = new Scanner(System.in);
System.out
.println("Enter the size of the field in feets(width
and length separated by space, x y):");
x = scan.nextInt();
y = scan.nextInt();
int[][] fieldsize = new int[y][x];
this.fieldsize= fieldsize;
}
public int[][] getFieldSize() {
return fieldsize;
}
}
I have managed to "collect" the fields size from user input into int [][] fieldsize array.
Now I want to ask the user about the starting position for the frog and the heading direction, S(south), N(north), E(east), W(west) and then add the frog to the field. For instance the user types 3 4 E. This should put the frog to position [3] [4] East(Heading). How do I resolve this?
Class Position:
package project;
import java.util.Scanner;
public class Position {
public Position() {
int x;
int y;
String heading;
Scanner scan = new Scanner(System.in);
System.out.println("Enter the starting position and heading for the frog, X Y and N, S, W or E position");
x = scan.nextInt();
y = scan.nextInt();
heading = scan.next();
//How do I put this inputs in the Field(fieldsize)?? So they get into this position in the field??
}
}
It is a bit difficult to describe what I mean, but I hope you guys can help me!
Thanks in advance!
OK. First thing you should consider before starting to code - what is the design. And the question like this usually appears when the code comes before the design.
So the first question should be:
What classes do I need and what every class should do and how would they interact.
An object is a self-contained component that contains properties and
methods needed to make a certain type of data useful. An object’s
properties are what it knows and its methods are what it can do.
For example - What can the object of the class Field do? How would it interact with the Position? And what can I do with the Position?
Then you start to design the classes. You sure don't want to read the user input in a constructor. What if you want to get the input from the file tomorrow and get it from the cloud or by voice the next month? Or even worse - what if there is an input error? What would be the state of the object?
You usually need to provide all the data needed to create the object to the constructor. The constructor shouldn't care where you get it from. You can have a public Field(int x, int y) and call it in your main class after reading the user input (I'm not suggesting that you should have this exact constructor, just an example).
You may want to set the position as a method of the Field (field will contain the position)
field.setPosition(position);
or have a move method of the Position (you can have as much positions as you like on the field)
position.setField(field);
position.moveTo(x,y);
Or you can even get to the conclusion you don't need a Position at all, and it would merely be the Field's property:
field.setCurrentX(x);
field.setCurrentY(y);
The design is really up to you here. Just have the design before you code.
I need help with a lab. My teacher did not tell us anything and he told us to figure it out. So i can use any help I can get. Thank You
Step 1: Is everything good with step one including my distance formula and I am trying to set xx equal to x and yy equal to y so I have not clue how to do that could could you help me with that.
class Point {
private int x;
private int y;
public Point() // (0, 0)
{
x = 0;
y = 0;
}
public Point(int xx, int yy)
{
xx = x;
yy = y;
}
public int getX() // return field values
{
return x;
}
public int getY()
{
return y;
}
// Use the distance formula to find the distance of this point from the origin (0,0)
public double distanceFromOrigin()
{
int d = 0;
d = Math.squrt(Math.pow(xx - x) + (Math.pow(yy - y);
}
Is my distance formula good if not what is wrong and can you help me fix it.
Step 2: I need to find the manhattan distance
// Find the "manhattan" distance between current point and other.
// You can look at http://x...content-available-to-author-only...t.gov/dads//HTML/manhattanDistance.html for help
public double distance(Point other)
{/*write the code for here*/}
I really have no clue how to do step 2 so i can really use a lot of help thank you guys so much
Step 3: After i find the manhattan distance between current point and other. I need to change it to its new values which i have no clue how to get the new value and how to change it. After that i need to shift the point by the translation T which i have no clue how to do that so i need help on that
// Changes the coordinate to new values
public void setLocation(int x, int y)
{/*write the code for here*/}
//Shift the point by the translation T<x+h,y+k>
public void translate(int h, int k)
{/*write the code for here*/}
by the way guys I am just on the basic computer science so I can't use all the fancy stuff so keep it basic and simple
Like torvin said in the comments, that really looks like Java and not Javascript. Those are two different languages, despite the similar names.
Generally looking at your code, there are obvious mistakes, which make me wonder what IDE (integrated development environment) you are using to write code. A proper program that helps you write code will spot those.
Just in your distanceFromOrigin() you are missing:
2 closing bracets
Math.squrt() should be Math.sqrt()
You are not returning a value, despite having set the methods return type to double
You should probably first set up an IDE and do a basic Java tutorial before continuing, honestly.
I've been trying to use my collision detection to stop objects from going through each other. I can't figure out how to do it though.
When objects collide, I've tried reversing the direction of their velocity vector (so it moves away from where it's colliding) but sometimes the objects get stuck inside each other.
I've tried switching their velocities but this just parents objects to each other.
Is there a simple way to limit objects' movement so that they don't go through other objects? I've been using the rectangle intersects for collisions, and I've also tried circle collision detection (using distance between objects).
Ideas?
package objects;
import java.awt.Rectangle;
import custom.utils.Vector;
import sprites.Picture;
import render.Window;
// Super class (game objects)
public class Entity implements GameObject{
private Picture self;
protected Vector position;
protected Vector velocity = new Vector(0,0);
private GameObject[] obj_list = new GameObject[0];
private boolean init = false;
// Takes in a "sprite"
public Entity(Picture i){
self = i;
position = new Vector(i.getXY()[0],i.getXY()[1]);
ObjectUpdater.addObject(this);
}
public Object getIdentity() {
return this;
}
// position handles
public Vector getPosition(){
return position;
}
public void setPosition(double x,double y){
position.setValues(x,y);
self.setXY(position);
}
public void setPosition(){
position.setValues((int)Window.getWinSize()[0]/2,(int)Window.getWinSize()[1]/2);
}
// velocity handles
public void setVelocity(double x,double y){ // Use if you're too lazy to make a vector
velocity.setValues(x, y);
}
public void setVelocity(Vector xy){ // Use if your already have a vector
velocity.setValues(xy.getValues()[0], xy.getValues()[1]);
}
public Vector getVelocity(){
return velocity;
}
// inferface for all game objects (so they all update at the same time)
public boolean checkInit(){
return init;
}
public Rectangle getBounds() {
double[] corner = position.getValues(); // Get the corner for the bounds
int[] size = self.getImageSize(); // Get the size of the image
return new Rectangle((int)Math.round(corner[0]),(int)Math.round(corner[1]),size[0],size[1]); // Make the bound
}
// I check for collisions where, this grabs all the objects and checks for collisions on each.
private void checkCollision(){
if (obj_list.length > 0){
for (GameObject i: obj_list){
if (getBounds().intersects(i.getBounds()) && i != this){
// What happens here?
}
}
}
}
public void updateSelf(){
checkCollision();
position = position.add(velocity);
setPosition(position.getValues()[0],position.getValues()[1]);
init = true;
}
public void pollObjects(GameObject[] o){
obj_list = o;
}
}
Hopefully it's not too difficult to read.
Edit:
So I've been using the rectangle intersection method to calculate the position of an object and to modify velocity. It's working pretty well. The only problem is that some objects push others, but that's so big deal. Collision is pretty much an extra thing for the mini game I'm creating. Thanks a lot of the help.
All that being said, I'd still really appreciate elaboration on mentioned ideas since I'm not totally sure how to implement them into my project.
Without seeing your code, I can only guess what's happening. I suspect that your objects are getting stuck because they overshooting the boundaries of other objects, ending up inside. Make sure that each object's step is not just velocity * delta_time, but that the step size is limited by potential collisions. When there is a collision, calculate the time at which it occurred (which is somewhere in the delta_time) and follow the bounce to determine the final object location. Alternatively, just set the objects to be touching and the velocities changed according to the law of conservation of momentum.
EDIT After seeing your code, I can expand my answer. First, let me clarify some of my terminology that you asked about. Since each call to updateSelf simply adds the velocity vector to the current position, what you have in effect is a unit time increment (delta time is always 1). Put another way, your "velocity" is actually the distance (velocity * delta time) traveled since the last call to updateSelf. I would recommend using an explicit (float) time increment as part of your simulation.
Second, the general problem of tracking collisions among multiple moving objects is very difficult. Whatever time increment is used, it is possible for an object to undergo many collisions in that increment. (Imagine an object squeezed between two other objects. In any given time interval, there is no limit to the number of times the object might bounce back and forth between the two surrounding ones.) Also, an object might (within the resolution of the computations) collide with multiple objects at the same time. The problem is even more complicated if the objects actually change size as they move (as your code suggests they may be doing).
Third, you have a significant source of errors because you are rounding all object positions to integer coordinates. I would recommend representing your objects with floating-point objects (Rectangle2D.Float rather than with Rectangle; Point2D.Float rather than Vector). I would also recommend replacing the position field with a rectangular bounds field that captures both the position and size. That way, you don't have to create a new object at each call to getBounds(). If the object sizes are constant, this would also simplify the bounds updating.
Finally, there's a significant problem with having the collision detection logic inside each object: when object A discovers that it would have hit object B, then it is also the case that object B would have hit object A! However, object B does its own calculations independently of object A. If you update A first, then B might miss the collision, and vice versa. It would be better to move the entire collision detection and object movement logic to a global algorithm and keep each game object relatively simple.
One approach (which I recommend) is to write an "updateGame" method that advances the game state by a given time increment. It would use an auxiliary data structure that records collisions, which might look like this:
public class Collision {
public int objectIndex1; // index of first object involved in collision
public int objectIndex2; // index of second object
public int directionCode; // encoding of the direction of the collision
public float time; // time of collision
}
The overall algorithm advances the game from the current time to a new time defined by a parameter deltaTime. It might be structured something like this:
void updateGame(float deltaTime) {
float step = deltaTime;
do (
Collision hit = findFirstCollision(step);
if (hit != null) {
step = Math.max(hit.time, MIN_STEP);
updateObjects(step);
updateVelocities(hit);
} else {
updateObjects(step);
}
deltaTime -= step;
step = deltaTime;
} while (deltaTime > 0);
}
/**
* Finds the earliest collision that occurs within the given time
* interval. It uses the current position and velocity of the objects
* at the start of the interval. If no collisions occur, returns null.
*/
Collision findFirstCollision(float deltaTime) {
Collision result = null;
for (int i = 0; i < obj_list.length; ++i) {
for (int j = i + 1; j < obj_list.length; ++j) {
Collision hit = findCollision(i, j, deltaTime);
if (hit != null) {
if (result == null || hit.time < result.time) {
result = hit;
}
}
}
}
return result;
}
/**
* Calculate if there is a collision between obj_list[i1] and
* obj_list[i2] within deltaTime, given their current positions
* and velocities. If there is, return a new Collision object
* that records i1, i2, the direction of the hit, and the time
* at which the objects collide. Otherwise, return null.
*/
Collision findCollision(int i1, int i2, float deltaTime) {
// left as an exercise for the reader
}
/**
* Move every object by its velocity * step
*/
void updateObjects(float step) {
for (GameObject obj : obj_list) {
Point2D.Float pos = obj.getPosition();
Point2D.Float velocity = obj.getVelocity();
obj.setPosition(
pos.getX() + step * velocity.getX(),
pos.getY() + step * velocity.getY()
);
}
}
/**
* Update the velocities of the two objects involved in a
* collision. Note that this does not always reverse velocities
* along the direction of collision (one object might be hit
* from behind by a faster object). The algorithm should assume
* that the objects are at the exact position of the collision
* and just update the velocities.
*/
void updateVelocities(Collision collision) {
// TODO - implement some physics simulation
}
The MIN_STEP constant is a minimum time increment to ensure that the game update loop doesn't get stuck updating such small time steps that it doesn't make progress. (With floating point, it's possible that deltaTime -= step; could leave deltaTime unchanged.)
Regarding the physics simulation: the Wikipedia article on Elastic collision provides some nice math for this problem.
I have the following class:
class Position {
private double x,y;
private int id;
private static int count=0; //counts number of times a Position object has been created
public Position (double initX, double initY) {
x=initX;
y=initY;
id=count;
count++;
}
public Position (Position a) {
id=count;
count++;
x=a.x;
y=a.y;
}
I want to now create a Position object in another of my .java files. How would I do so? Wouldnt I just use Position x=new Position; ? Thats not working. Do I have to import the position class into the files? I tried that too, didnt work. Wouldnt let me import. My files are in the default folder.
Here's where I want to use it. Im not even sure Im reading the instructions correctly. Is this what they want from me? To initialize every element of the array to a new position object?
/**
* Returns an array of num positions. Each position is initialized to a random
* (x,y) position.
* if num is less than zero, just return an empty array of length 0.
*
* #param num
* number of positions to create
* #return array of newly minted Points
*/
public int[] randomPos(int[] a) {
int numPositions=Position.getNumPositionsCreated();
int[] posArr=new int[numPositions];
int x,y;
for (int i=0; i<numPositions;i++)
Position rand = new Position(x,y);
//
You would need to invoke the constructor,
Position x = new Position(2.0,2.0);
Since one of your constructor takes two double's as arguments, I used those as an example.
Or, you could create a new Position object by passing in another Position object,
Position otherX = new Position(new Position(2.0,2.0));
// or combining our above example assuming that x is already instantiated
Position otherX = new Position(x);
Also, just in case you are unsure, there is a difference between instantiation and declaration!
Instantiation:
Position posX = new Position(1.0, 4.0);
Now, posX is an instance of a Position object, because we construct our object by invoking the constructor.
Declaration:
Position posX;
Note that the posX variable is declared to be a Position object, but has not yet been instantiated so posX would have a null reference.
Update:
Without actually do the homework for you, because you will not learn that way. I can tell you that what you have so far, and what is listed in the javadoc above do not agree. Also, given by the way the javadoc is written, it is tough to follow, therefore let me try to clean it up for you and leave you to do the rest,
/* Returns an array of n Positions. Each Position is initialized to a random
* (x,y) position.
* if n is less than zero, just return an empty array of length 0.
*
* #param n
* number of Positions to create
* #return array of newly created Positions
*/
Now we can break down that javadoc, so lets pinpoint what we know.
We are passing an argument, n which indicates how big the Positions array should be.
We need to check to see if n is equal to 0, if so we return an empty Position array.
Each Position object would be instantiated with random x and y values.
We know that we need to return an Position array.
This should get you started, I am sure you can figure out the rest.
Position x = new Position(1.0, 2.0);
For example. The way you have it now is missing method arguments.
Position x = new Position(1d,2d);
You need to pass your constructor arguments. Since you defined 2 constructors on your Position class, you must use one of them. Usually not a bad idea to put a do nothing constructor on your class. like
Postion () {}
or in your case
Position () {
Position.static++;
}
since you are counting. Note you should reference static members statically.
Your constructors take arguments, so you have to provide some.
Position p = new Position(1.0, -2.0);
If you want to create one without arguments, you need to a add a zero-argument constructor.
public Position() {
}
which would then be invoked by doing Position p = new Position() (the parenthesis are required when not passing in arguments)
If you don't define any constructors, java automatically creates an implied zero-arg constructor, but once you define a different constructor, you have to explicitly define a zero-arg constructor to have one.
If both of your classes are in the default package you shouldn't need to import anything.
Java already has a Point class. It may be overkill for you but though I'd mention it.
http://download-llnw.oracle.com/javase/6/docs/api/java/awt/geom/Point2D.html
Don't forget the parentheses and arguments to pass into the constructor when you call new, eg:
Position p = new Position(x, y);
Depending upon where the other class is, you may also need to make Position a public class (it appears you are using the default visibility of package-private).
Also note that x and y must be initialized first,