class Bug {
// An ant is represented by the coordinates of its location,
// and the direction it is facing.
Integer x;
Integer y;
Dir dir;
enum Dir { E,W,N,S }
}
Bug(Integer x, Integer y, Dir dir) {
this.x = x;
this.y = y;
this.dir = dir;
}}
class BugWorld {
Integer theBreadth, theHeight;
Board board;
Bug bug;
BugWorld(Integer breadth, Integer height) {
board = new board(breadth, height);
bug = new Bug(breadth/2, height/2, Ant.Direction.Y);
theBreadth = breadth;
theHeight = height;
}
I already have the following:
Status status(Integer x, Integer y) {
return board[x][y];
}
void update(Integer x, Integer y) {
board[x][y].next();
}
This part below is where I'm having some trouble:
/* Take the world of the bug to the next step. */
void step() {
// 1) Get the state at the present bug position.
//I've done the following (next line) so far.
Bug status(Integer x, Integer y); ...?
// 2) Change the 'status' at that position.
.............?
}
It's just combining these that I'm having trouble with.
It's hard to understand what you're trying to do, but I think here's what you want
void step(){
//get the location of the bug
int x = bug.x;
int y = bug.y;
//gets the status of the location of the bug
Status s = status(x,y);
//move the bug, or do something based on the status of the place
//update the status of the location the bug was originally on
update(x,y)
}
Related
I am writing a platform game in Java in which there are various game objects such as platforms, the player, and (eventually) enemies. I describe the position of these game objects with rectangles: x position, y position, width, and height. However, I would also like to add in other variables to describe the position: left, top, right, and bottom. For the last two I know I will need to change them whenever x, y, width, or height gets modified, but as left and top are the same as x and y, I was wondering how I could get them to point to the same value as x and y. I think this can be done in C with the #define function, but sadly this is Java, not C.
How can I get two different variable names to point to the same value in Java such that if one changes, the other changes as well?
Edit: Here is the basics of my GameObject class:
public abstract class GameObject {
protected float x;
protected float y;
protected float right;
protected float bottom;
protected float width;
protected float height;
public float getX() {
return x;
}
public float getY() {
return y;
}
public void setX(float x) {
this.x = x;
right=this.x+width;
}
public void setY(float y) {
this.y = y;
bottom=this.y+height;
}
//A bunch of other getters/setters
//Subclasses must have render (for displaying graphics) and tick (mainly for updating position) functions.
public abstract void render(Graphics g);
public abstract void tick();
}
What I would like to do is add in two more variables:
protected float left = x;
protected float top = y;
and have these refer to the same primitive as x and y (not copy the primitives). This, apparently, does not seem possible. Thanks for your answers!
This can't be done in Java in the sense that you mean it. You can have two object references that point to the same object, but if you have a normal primitive variable, those are always distinct and don't refer to each other. You can make an object to hold a primitive, have two different references to that same object, and a change to the contents of that object through one reference will be reflected in the other, but you cannot have an int x and and int y where writing x = 10 will make y == 10.
If you really need something behaving like a reference to a primitive, you need to create an object holding that primitive value and then share the "holder" object.
However, I don't think this is the best way to tackle your problem.
As I understand your game objects, they can be entirely described with x, y, height and width variable. left, top, right and bottom on the other hand, are values that can derived from the four basic ones.
In fact, it would be possible to have a game object containing only x, y, height and width and to compute the other four values outside of the object whenever they are needed. Such an object could look like this :
public class GameObject {
private int x, y, height, width;
public int getX() { return x; }
public int getY() { return y; }
public int getHeight() { return height; }
public int getWidth() { return width; }
public void setX(int x) { this.x = x; }
public void setY(int y) { this.y = y; }
public void setHeight(int height) { this.height = height; }
public void setwidth(int width) { this.width = width; }
}
Notice that the actual variables are private and only readable through getters. This helps to avoid the use of a variable reference later on.
Now, to have an easy and unique way to access to left, top, right and bottom, while you could add four variables and keep them in sync with the four other variable already present, I think it is not the best way to do it.
I suggest that you just compute them on the fly inside slightly smarter-than-average getters. It would look like that :
public class GameObject {
// getters and setters omitted for brevity
private int x, y, height, width;
public int getLeft() {
return x;
}
public int getRight() {
// assuming x increase toward the right
return x + width;
}
public int getTop() {
return y
}
public int getBottom() {
// assuming y increase toward the bottom
return y + height;
}
}
This will also help if you need to create some special update methods, like moveRight(int delta), scale(double factor) since you will only need to apply changes to the basic variables and not the values that are derived from them.
int/integer is passed by value, not by reference in java.
You can define a new class, For example,
public class Position {
int x;
int y;
}
Let two variables point to the same instance of Position.
In java there are two types of variables.
1.Primitive types
2.Reference types
You need to use reference type variable if you want to refer the same object through different variables.
In your case for gaming application those parameters might change frequently.
So if all the time values, left and top are same as x and y, you can use use one variable to represent the both parameters which saves memory.
e.g : for left and x use one variable.
Or else using java OOP concepts,
you can make those x, y, left, top parameters private and assign getters and setters for those.
public int setX(int x){
this.x =x;
}
public setLeft(int left){
this.left = left;
}
public int setY(int y){
this.y =y;
}
public setTop(int top){
this.top= top;
}
public setXnLeft(int xnleft){
setX(xnleft);
setleft(xnleft);
}
public setYnTop(int yntop){
setY(yntop);
setTop(yntop);
}
This can easily be done by creating a new Class. Java is object-oriented, so, basically, everything is about classes and it's instances. Take a look at an example below:
class GameObject
{
//Instance variables
//(all objects of this class will have their own)
int x;
int y;
int width;
int height;
//Constructor
//(you call a constructor when creating a new object)
GameObject(int x, int y, int width, int height)
{
//Here you are assigning the values received to the instance variables (marked with "this", that represents the current object)
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
//This method will return the ordinate ("y") of the object's top position (assuming the "y axis" points down)
int getTop() {
return (y - height/2);
}
}
After creating the class GameObject, you can create instances (objects) of it. Look below:
GameObject player = new GameObject(0, 0, 50, 50); //creates a new object with coordinates (0,0), width = 50 and height = 50
GameObject enemy1 = new GameObject(30, 50, 100, 100);
//Getting the "x" position of the player and the monster
System.out.println("Player X = " + player.x);
System.out.println("Enemy1 X = " + enemy1.x);
//Get the top position "y"
System.out.println("Player top = " + player.getTop());
//Change player's "y"
player.y = 10;
//Get player's top position again
System.out.println("Player top = " + player.getTop()); //it will have changed, since "y" was changed.
Oracle has a really good lesson about Object-Oriented Programming, you should check it out here. The C language is structured, while Java is Object-Oriented, these are two different paradigms. I hope this was of help. Cheers!
I'm making a game similar to agar.io where a blob goes around and eats dots. I'm making it on my phone and you control the blob with your finger to collect the dots. I noticed that when I collect a single dot some random other dots dissappearing as well. I debugged some and found out that unless you collected the dots in the order that they were added to the array, any dot with a lower array order would be destroyed. Example: if you collected the dot added to the array 7th then dots 0-6 would dissappear, bit if you collected 1 then 2 and so on then no other dots would dissappear randomly. I created another simpler example to explore this problem. Now it's a simple screen with 5 circles. You can pick up and drag and drop any circle. I noticed the same problem where you drag a circle and other circles randomly dissappear even though there is no code to make them dissappear. My code is as follows:
// Drag n' Drop //
Objects[] box;
int objCount = 5;
void setup() {
box = new Objects[objCount];
for (int i = 0; i < objCount; i++){
box[i] = new Objects(random(displayWidth),random(displayHeight),200);
}
}
void draw() {
background(170);
for (Objects boxes : box) {
boxes.display();
boxes.dragging();
}
}
class Objects {
float x, y;
float s;
Objects(float tempX, float tempY, int tempS) {
x = tempX;
y = tempY;
s = tempS;
}
void display() {
ellipse(x, y, s, s);
}
void dragging() {
if (dist(x, y, mouseX, mouseY) < 500) {
x = mouseX;
y = mouseY;
s = 300;
}
}
}
I believe my problem may lie in the loop I use to call the display function of the box object, but I cannot find out any other way to make it work. Any help us very much appreciated. Thank you for your time. PS Im using processing to run this code.
Kelton
Firstly, I'd like to thank you for I have never played with Processing before and you inspired me to download it!
There are quite a few things wrong that I'd like to point out and maybe steer you in the right direction. The main issue lies within your dragging() method you are not actually removing the objects you are just moving them to your mouse position, giving you the illusion they are being removed!
Anyway, as you said you were creating the game Agar.io, I would assume that you yourself should have your own Blob. For the sake of my Java brain I have switched what you called Objects to Blobs.
First off, the setup.
import java.util.*;
public static final int BLOB_COUNT = 10;
List<Blob> blobs = new ArrayList<Blob>();
// this is our blob, the one that displays in the middle of the screen
Blob myBlob = new Blob(mouseX, mouseY, 50);
void setup() {
size(1000, 500);
for (int i = 0; i < BLOB_COUNT; i++){
blobs.add(new Blob(random(displayWidth/2),random(displayHeight/2),50));
}
}
Notice how I am using ArrayLists rather than an array, this will make it easier for you to add and remove from the List.
Next, the draw() so this happens each frame.
void draw() {
background(170);
// refreshes the players blob wherever the cursor is!
myBlob.setX(mouseX);
myBlob.setY(mouseY);
myBlob.display();
// display the other blobs on the screen
for (Blob boxes : blobs) {
boxes.display();
boxes.dragging();
}
}
Notice, we want to update our blob to the current position of the mouse!
Lastly, the Blob class!
class Blob {
float x, y;
float size;
Blob(float tempX, float tempY, int size) {
this.x = tempX;
this.y = tempY;
this.size = size;
}
void display() {
ellipse(x, y, size, size);
}
void dragging() {
if (dist(x, y, mouseX, mouseY) < myBlob.getSize()/2) {
myBlob.setBlobSize(25);
this.x = random(displayWidth/2);
this.y = random(displayHeight/2);
}
}
void setX(float x){
this.x = x;
}
void setY(float y) {
this.y = y;
}
void setBlobSize(float size) {
this.size += size;
}
float getSize() {
return this.size;
}
}
So now, we check in the dragging() method whether the blob is close to our blob, and if it is we want to consume that blob (which increases our mass) and then we want that blob to re-spawn to another location, well that's how most Agar.io games work, but of course this is entirely up to you. There is also much more accurate ways to calculate the area of the blob and determine whether two blobs are within touching distance, but I'll leave the maths to you.
following: I create a ArrayList with an Own Object which keeps two int(x,y)
But I only get 0 instead of the number. I don't see why it does not work.
public class Snake {
public class SnakeBody {
public int x;
public int y;
SnakeBody(int x, int y){
x = this.x;
y = this.y;}
}
protected ArrayList<SnakeBody> SnakeBody = new ArrayList<SnakeBody>();
protected PointF Fruit;
protected boolean GameStarted = false;
//Constructor
public Snake(){}
public void startSnake()
{
if(!GameStarted)
{
GameStarted = true;
SnakeBody.add(new SnakeBody(1,14));
SnakeBody.add(new SnakeBody(2,14));
SnakeBody.add(new SnakeBody(3,14));
int itemcount = SnakeBody.size();
Log.d("Snake.java:Game started: ", "" + itemcount);
for(int i=0; i<itemcount; i++){
Log.d("First Snake created: XY->", "" + SnakeBody.get(i).x + ":" + SnakeBody.get(i).y);
}
}
}
That's what I got then as Log.d Output:
Snake.java:Game started:﹕ 3
First Snake created: XY->﹕ 0:0
First Snake created: XY->﹕ 0:0
First Snake created: XY->﹕ 0:0
You want to change
SnakeBody(int x, int y){
x = this.x;
y = this.y;
}
to
SnakeBody(int x, int y){
this.x = x;
this.y = y;
}
What you are actually doing is assigning values of your class to the received parameter, it will never update the position of SnakeBody
By the way, I think it is a bad practice to name the parameter of your constructor the same as the class variable as if you ommit the this keyword, it is not clear what is assigned to what.
Look at your constructor:
SnakeBody(int x, int y){
x = this.x;
y = this.y;}
That's copying the value from your instance field to the parameter, in both cases. In other words, you're overwriting the useful data (the value that the caller passed in) with the value from the otherwise-uninitialized field (which will always be 0). You want it the other way round:
SnakeBody(int x, int y) {
this.x = x;
this.y = y;
}
Note that this has nothing to do with the ArrayList aspect - you could observe the same thing just by writing:
SnakeBody body = new SnakeBody(1, 2);
System.out.println(body.x); // 0
It's always worth trying to pinpoint exactly where the issue is, trying to remove bits of code one at a time until the behaviour changes.
(It's also a good idea to make all fields private, but that's a slightly different matter.)
I am currently working on a project called Rectangle project in which I am supposed to do the following on Java:
Make the following methods:
setOrigin
area
move
Also make a method that determines if two rectangles intersect and returns a new intersection Rectangle. Test all your methods in the ObjectDemo program for the following rectangles:
A: Origin 0,0: width 10: height 20
B: Origin 5,5: width 15, height 15
C: Origin 20,12: width 10: height 20
What is the area of each? Test if each of them intersect with the other two and what is the intersection area. Move A by 5,5; B by -5,-5: and C by -20, 0. Now give the intersection area of each.
I need to finish this by Monday but I keep getting a ton of errors like unrecognized variables, etc., and I'm not sure how to fix them. Please let me know!
I have three files: Point, RectangleTest, and Rectangle.
Here are their codes:
Point code:
public class Point
{
//Class variables
private int xCoord; //Private (instead of Public) because we are going to use this class in the other file
//We don't want people changing the values unless we let them
private int yCoord; //Variables are not in a function so will maintain their value
//Constructor
Point()
{
xCoord = 0;
yCoord = 0;
}
//Constructor
Point(int startX, int startY)
{
xCoord = startX;
yCoord = startY;
}
public int getX()
{
return xCoord;
}
public int getY()
{
return yCoord;
}
public void setX(int newX)
{
xCoord = newX;
}
public void setY(int newY)
{
yCoord = newY;
}
public void move(int moveX, int moveY)
{
xCoord+=moveX;
yCoord+=moveY;
}
Point(Point p)
{
xCoord = p.getX();
yCoord = p.getY();
}
}
RectangleTest Code:
public class RectangleTest
{
public static void main(String [] args)
{
Rectangle A = new Rectangle(0,0,10,20);
Rectangle B = new Rectangle(5,5,15,15);
Rectangle C = new Rectangle(20,12,10,20);
//Move rectangles
A.moveby(5,10);
B.moveby(-5,-5);
C.moveby(-20,0);
int areaA = A.getarea;
System.out.println("The area of rectangle A is " +areaA);
int areaB = B.getarea;
System.out.println("The area of rectangle B is " +areaB);
int areaC = C.getarea;
System.out.println("The area of rectangle C is " +areaC);
Rectanlge iAB = A.intersect(B);
Rectangle iAC = A.intersect(C);
Rectangle iBC = B.intersect(C);
if(iab != null)
{
System.out.println("The area of intersection rectangle iab = " +iAB.area());
}
if(iac != null)
{
System.out.println("The area of intersection rectangle iac = " +iAC.area());
}
if (ibc != null)
{
System.out.println("The area of intersection area ibc = " +iBC.area());
}
}
}
Rectangle Code:
public class Rectangle
{
Point origin;
int height;
int width;
//Constructor for rectangle object
Public Rectangle(int startX, int startY, int startW, int startH)
{
origin = new Point (startX, startY);
width = startW;
height = startH;
}
//Set origin point for NEW rectangle origins
//FIX
public void setOrigin(int newX, int newY)
{
origin.setX(newX);
origin.setY(newY);
}
public int moveBy(int moveX, int moveY)
{
origin.move(moveX, moveY);
}
public int getArea()
{
int recArea = height*width;
return recArea;
}
public Rectangle intersect(Rectangle testR)
{
int meTRX = origin.getX() + width;
int meTRY = origin.getY() + height;
int testTRX = testR.origin.getX() + width;
int testTRY = testR.origin.getY() + height;
//Boolean to get iTRX
if(meTRX>testTRX)
{
int iTRX = testTRX;
}
else
{
int iTRX = meTRX;
}
//Boolean to get iTRY
if(meTRY>testTRY)
{
int iTRY = testTRY;
}
else
{
int iTRY = meTRY;
}
//Boolean to get iBLX
if(testBLX>meBLX)
{
int iBLX = testBLX;
}
else
{
int iBLX = meBLX;
}
//Boolean to get iBLY
if(testBLY>meBLY)
{
int iBLY = testBLY;
}
else
{
int iBLY = meBLY;
}
//Testing for whether or not there is an intersection rectangle
if(iTRX-iBLX<0 || iTRY-iBLY<0)
{
return null;
}
int iH = iTRY - iBLY;
int iW = iTRX - iBLX;
int intersectArea = iH * iW;
}
}
Please point out any problems! I'm rather new to programming, so I usually make a lot of simple mistakes. Also, I would appreciate if there are no newly introduced commands or anything because my teacher is pretty strict about doing it this way.
Thanks!
P.S. I would appreciate any extra knowledge or info on code improvement (just in general). Thanks!
Couple of Issues:
Java is case sensitive so Public is not same as public in your rectangle class.
When your method doesnt return anything you should use void as return type. So in your method public int moveBy(int moveX, int moveY), you should change it to public void moveBy(int moveX, int moveY)
You need to define variables before using them. So variables like testBLX, meBLX, testBLY, meBLY, iTRX, iTRY, iBLX, iBLY are undefined. I am not sure from where the values will get populated. But you could avoid the compilation error by defining them as int testBLX = 0; and similarly the others.
In your Rectangle class:
In the constructor your wrote Public Rectangle(int startX, int startY, int startW, int startH), but you actually want public Rectangle(int startX, int startY, int startW, int startH). In Java keywords start always with a lower case.
Your method for changing the origin of a rectangle public int moveBy(int moveX, int moveY) has int as a return type, so the compiler wants you to return an integer value. I suppose you did not want to return anything at all so you can change the return type to void.
In your intersect method public Rectangle intersect(Rectangle testR) you declare your variables (iTRX, iTRY, iBLX, iBLY) such as int iTRX = testTRX; only in the scope of your if/else statements which means that after every if/else statement these variables are not available anymore. To learn more about the different scopes of variables: Variable scopes
In your RectangleTest class:
You forgot a part of your task: What is the area of each? Test if each of them intersect with the other two and what is the intersection area.
Some general leads:
The use of more descriptive variable names improves the readability. For example the variable name meTRX does not have any meaning for me as person who did not work on your code or maybe for you if you review your code two months later.
Before you start coding, you could check if Java has built-in classes which you can use. In your case Java provides a Point class in the package java.awt.Point. You do not have to reinvent the wheel.
I would also recommend to read the Java Code Conventions Code Conventions which can bring you and others who read your code on a common denominator in the future.
I want to make a 10x10 grid and put the robot in position (10,1) (bottom left). I want this robot to be able to move forward, turn left/right and to pick up/put objects in a grid. When put in any position, there should be number in a grid which shows how many objects is put in this position, just like this:
..........
...1......
..2.......
....3.....
..........
..........
......9...
.....4....
.........1
..........
We will not see the robot in a grid. I have two classes. Class Robot:
public class Robot {
private Area area;
private Robot rob;
public Robot(Area area){
this.area = area;
rob = new Robot(area);
}
public void Right(){
}
public void Left(){
}
public void Forward(){
}
public void Put(){
}
public void PickUp(){
}
public (?) getPosition(){ // should return robot's position
}
}
Class Area:
private int numberOfObjects;
private Robot robot;
private static final int X = 10;
private static final int Y = 10;
private Object [][] area; // grid
public Area(){ // defines a grid and robot
area = new Area[X][Y];
for(int a=0;a<X;a++){
for(int b=0;b<Y;b++)
area[a][b]=".";
}
numberOfObjects = 0; // grid is initially empty
Area ar = new Area();
robot = new Robot(ar);
}
public void Put(int x,int y){ // put the object to position (x,y)
area[x][y]=numberOfObjects++;
}
public void PickUp(int x,int y){ // pick up the object in position (x,y)
if(area[x][y]!=null){
area[x][y]=numberOfObjects--;
}
}
public void PrintAGrid(){
for(int r=0;r<X;r++){
for(int c=0;c<Y;c++)
System.out.print(area[r][c]+" ");
System.out.println();
}
System.out.println();
}
}
How can I put the robot in position (10,1)? How can I declare and set its orientation (i.e. on the right)? I guess it will be easy to write other methods, so I do not focus on it.
There are several issues with your code.
Why do you have an instance of Robot inside the class Robot? You have not used that instance at all!
private Object [][] area; should be int[][] area. You always save int in this, right?
If I understand your requirements correctly, Your implementation of pick and put is not correct.
Here is a help how you can solve the problems. I had to think several times if Robot should be in Grid or it should be the other way. I ended up with Grid in Robot.
May be Grid could be a singleton.
Here is our Grid
public class Grid {
private int[][] numberOfObjects = new int[10][10];
public void put(int x, int y) {
numberOfObjects[y][x]++;
}
public void pick(int x, int y) {
numberOfObjects[y][x]--;
}
}
You can replace parameters int x, int y with a Point.
And here is the robot
public class Robot {
private static final int NORTH = 0, EAST = 1, SOUTH = 2, WEST = 3;
private int direction;
private int x, y;
private Grid grid;
public Robot(Grid grid) {
this.x = 0;
this.y = 0;
this.grid = grid;
direction = NORTH;
}
public void right() {
direction++;
if (direction == 4) {
direction = 0;
}
}
public void left() {
direction--;
if (direction == -1) {
direction = 3;
}
}
public void forward() {
if (direction == NORTH) {
y--;
} else if (direction == SOUTH) {
y++;
} else if (direction == EAST) {
x++;
} else if (direction == WEST) {
x--;
}
}
public void put() {
grid.put(x, y);
}
public void pick() {
grid.pick(x, y);
}
}
You need to represent the curent location with a variable and initialize it to the 10 1 postion, though your array goes 0-9 and 0-9 so this may be 9,0. to store this position maybe try a Point object that contains a Point x,y.
If someone is interested in a JavaScript version, you can have a look at this repo right here. In general:
The robot must have a facing direction (left, up, right, down).
The are three possible commands: left, right, move.
With that being said, the algorithm is quite straightforward:
totalScore = 0
Foreach i in input
computeCurrentDirection()
if input != MOVE: continue
totalScore += i
return totalScore
There are several sweet-tricks that someone might do to optimize the functions. Take a look at switchDirection.
const directionArray = [Directions.RIGHT, Directions.DOWN, Directions.LEFT, Directions.UP];
const switchDirection = (currDirection, command) => {
if (command === Commands.MOVE) {
return currDirection
}
const currDirectionIndex = directionArray.indexOf(currDirection);
if (command === Commands.RIGHT) {
return directionArray[(currDirectionIndex + 1) % 4];
}
return directionArray[((currDirectionIndex - 1) + 4) % 4];
}
Instead of an exhaustive approach, someone might use an array to help compute the upcoming direction of the robot. This significantly reduces the amount of needed code.
Note this implementation can be easily expanded to accommodate any new requirements needed for project expansion. When faced with such questions, try to architect your codebase in a testable and expandable way, because it's usually the case where reviewers are interested in your coding organizational skills, rather than whether you are able to solve the problem or not.