moving shapes with java - java

I am trying to create a java method, move() that will change the location of my object (which is an ellipse). my ellipse has an initial x,y position so I'd like to move it along the Jframe by calling the following method from the JComponent.
public class ShapeAnimation extends Shape {
public void move() {
xVel=(int)(Math.random()*11);
yVel=(int)(Math.random()*11);
x=xVel+x;
y=yVel+y;
if(x>this.x)
xVel=xVel*-1;
if(y>this.y)
yVel=yVel*-1;
}
}

you are using x variable in x=xVel+x; but it is not declared in function, so java assumes it is this.x
so your code looks like this:
this.x=xVel+this.x;
this.y=yVel+this.y;
if(this.x>this.x) // always false
xVel=xVel*-1;
if(this.y>this.y) // always false
yVel=yVel*-1;
you need to change it to:
int newX = xVel+this.x;
int newY = yVel+this.y;
if( (newX<0) || (newX>this.maxX) )
xVel=xVel*-1;
else
this.x = newX;
if( (newY<0) || (newY>this.maxY) )
yVel=yVel*-1;
else
this.y = newY;
maxX and maxY should have maximum values which x and y can have
NOTE - this code do not move object during some iterations, for teaching purposes I suggest you to update it for such cases

Related

Rectangle Class and containsPoint Method

I am trying to understand the Rectangle Class and MyCircle class, specifically the containsPoint methods in each one.
Here is the code:
public class MyRectangle extends GridItem {
private int height;
private int width;
public MyRectangle(int xValue, int yValue, int w, int h) {
x = xValue;
y = yValue;
width = w;
height = h;
}
public double getArea() {
return height * width;
}
public boolean containsPoint(int xValue, int yValue)
{
return xValue >= x &&
xValue <= x + width &&
yValue >= y &&
yValue <= y + height;
}
}
The confusion I'm having is, what does the containsPoint method mean?
How was this current code set up in this particular way, since isn't that supposed to return a boolean and not data types of the int?
Same dilemma for the MyCircle class.
public class MyCircle extends GridItem {
private int radius;
public MyCircle(int xValue, int yValue, int r)
{
x = xValue;
y = yValue;
radius = r;
}
public double getArea() {
return Math.PI * Math.pow(radius, 2);
}
public boolean containsPoint(int xValue, int yValue) {
double dx = x - xValue;
double dy = y - yValue;
double distance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
return distance <= radius;
}
}
What exactly are they meaning by the containsPoint method?
How do you interpret this?
Been stumped for days and this is part of a bigger assignment, but cannot comprehend the containsPoint method so it's affect the development of mySquare class.....
So far I've got this..
public class MySquare extends GridItem
{
private int side;
public MySquare(int xValue, int yValue, int s)
{
x = xValue;
y = yValue;
side = s;
}
#Override
public double getArea()
{
return side*side;
}
#Override
public boolean containsPoint(int xValue, int yValue)
{
return x && y;
}
}
How does one apply the containsPoint method in the Square class?
Thanks!
what does the containsPoint method mean?
The method just checks if the given point (the given x,y coordinates i.e. xValue, yValue) is within the current Square or Rectangle.
How was this current code set up in this particular way, since isn't that supposed to return a boolean and not data types of the int?
The method arguments are int because they indicate the x and y coordinates for the given point.
Been stumped for days and this is part of a bigger assignment, but cannot comprehend the containsPoint method so it's affect the development of mySquare class.....
Your sub-classes such as the Sqaure class is supposed to have a set of attributes such as x, y, width, height which indicates the position and size of the square. Based on this set of attributes, check if any given point (xValue, yValue) is within your current square. The same applies for Rectangle class.
The containsPoint is the method to check if a point is inside a specific rectangle / circle / shapes on 2D plane.
Comparing variables with each other will result in an boolean value.
Each comparison in containsPoint() in MyRectangle yields a boolean value which are then connected via and. This means that it will only return true if every single comparison yields true.
You would need to apply the same principle to MySquare.
Think about how the coordinates of the square compare to the coordinates of a point if the point is inside the square.
Let's consider the containsPoint of Rectangle.
Let's assume you have a rectangle of height 2 and width 3 starting at co-ordinate (1,1). So your rectangle would look like this
(1,3) (4,3)
------------
| |
| |
------------
(1,1) (4,1)
(In the above example) given two points xValue and yValue, containsPoint returns true if
xValue is between 1 and 4 (inclusive) and
yValue is between 1 and 3 (inclusive)
and false otherwise
Thus, containsPoint tells whether a given point lies on/within a shape.
The containsPoint method of a circle also does the same thing (whether a point lies within/on the circle), however the formula is a bit more involved. You can refer to the Euclidean distance for two dimensions to understand it better.
The containsPoint for a Square will be very similar to that of a rectangle except for using width and heigth, you would have only one side.
return xValue >= x &&
xValue <= x + side &&
yValue >= y &&
yValue <= y + side;

How do I detect if the user touched my Sprites/screen?

Basically, the sprite is spawned at a random time every (1,2 or 3 sec) and infinitely. I want the sprite to disappear once it's touched on the screen. (android touch event)
public void newEnemy(){
Sprite newEnemy=Pools.obtain(Sprite.class);
newEnemy.set(enemy);
newEnemy.setPosition(200, 700);
enemies.add(newEnemy);
}
public void update(){
deltaTime=Gdx.graphics.getDeltaTime();
timer+=1*deltaTime;
timer2+=1*deltaTime;
timer3+=1*deltaTime;
if(timer>=random){
newEnemy(); //spawn a new enemy
timer-=random;
random=rTime.nextInt(3)*1f+1;//create random time if timer>= initial random time;
}
You will need to set up a touch listener. Information on that here
You will then need to check if the touch location is within your sprite bounds.
A common way to do this would be to create a rectangle and check if the touch location is inside of the rectangle like this
Rectangle2D bounds = new Rectangle2D.Float(x, y, width, height);
`if(bounds.contains(`the touch x value`,` the touch y value`){`
//your code to remove the sprite
}
Alternately you could write your own method in sprite, this would be a better decision if all you needed was the contains method. That way, you don't have to import another library. (Note that it doesn't make much of a difference but it's good practice)
public boolean contains(int x, int y) {
return (x > this.x && y > this.y && x < this.x + this.width && y < this.y + this.height);
}

player.getX() returning null

I've got a function that grabs the players X co-ords and then returns them, but its returning null for some reason I can't quite figure out. (Hence why I'm here).
The exact error I get is as follows:
java.lang.NullPointerException
at dev.colors.level.Level.getXOffset(Level.java:78)
All i do is call this, this is line 78:
if(player.getX() <= half_width){
This line come from this method:
public int getXOffset(){
int offset_x = 0;
//the first thing we are going to need is the half-width of the screen, to calculate if the player is in the middle of our screen
int half_width = (int) (Game.WINDOW_WIDTH/Game.SCALE/2);
//next up is the maximum offset, this is the most right side of the map, minus half of the screen offcourse
int maxX = (int) (map.getWidth()*32)-half_width;
//now we have 3 cases here
if(player.getX() <= half_width){
//the player is between the most left side of the map, which is zero and half a screen size which is 0+half_screen
offset_x = 0;
}else if(player.getX() > maxX){
//the player is between the maximum point of scrolling and the maximum width of the map
//the reason why we substract half the screen again is because we need to set our offset to the topleft position of our screen
offset_x = maxX-half_width;
}else{
//the player is in between the 2 spots, so we set the offset to the player, minus the half-width of the screen
offset_x = (int) (player.getX()-half_width);
}
return offset_x;
}
The getX method is here:
public abstract class LevelObject {
protected float x;
public LevelObject(float x, float y) {
System.out.println(x);
this.x = x;
this.y = y;
public float getX() {
System.out.println(this.x);
return x;
}
}
We declare LevelObject by creating a Player object:
player = new Player(128, 64);
Which then hands the two variables delcared there through the Player.java class, and then through the Character.java class:
public class Player extends Character {
public Player(float x, float y) throws SlickException {
super(x, y);
}
Character.java:
public abstract class Character extends LevelObject {
public Character(float x, float y) throws SlickException {
super(x, y);
}
}
Everything goes through properly up until we call getX (in the LevelObject class, even when I use the System.out to print "this.x" from LevelObject before we call getX it returns the correct variable, "128.0" as declared by the Player object.
To make things weirder, if i put some printlines inside the getX method, they don't show up in the console. It's as if it doesn't even run the method.
This doesn't make any sense to me, and I'm very very lost.
Apparently, the player variable is null.
The getXOffset() does not initialize a player variable, so I guess it must be a class field or something, which must be initialized in a different method.
Perhaps you need to add the this keyword to player initialization code (make it look like this.player = new Player(128, 64);) ?
Either way, your player variable is not initialized properly and that is the reason for that exception.

Java - Edit instance variables without a method

I am quite new to Java, and I am constantly looking for ways to improve my code. But I don't seem to get this, if it is even possible to do.
Let's say I have this code (I edited out the irrelevant parts, so the code might seem weird):
public class NewBody {
public static int distanceScale = 5;
public int x, y;
public float xMeter = x * distanceScale;
public float yMeter = y * distanceScale;
public NewBody(int x, int y){
this.x = x;
this.y = y;
}
public void pixToMeter(){
this.xMeter = distanceScale * this.x;
}
If I don't call pixToMeter() and just try to use "instance.xMeter" directly, it just returns the vaulue 0, even though I've already set the x variable in the constructor.
So my question is: Is there a way to properly set variables without calling a method to do it? It seems highly unneccessary since I am not even passing a parameter to it.
Sorry for my poor english, I hope you understand what I am trying to say.
The initialisation of xMeter is done when x is still zero.
This is what actually happens:
public NewBody(int x, int y) {
// All fields are zeroed: 0, null, 0.0.
super(); // Object constructor, as Object is the parent class.
// Those fields that are initialized:
xMeter = this.x * distanceScale; // 0.0f * 5
yMeter = this.y * distanceScale;
// The rest of the constructor:
this.x = x;
this.y = y;
}
For a depending value:
public final void setX(int x) {
this.x = x;
xMeter = this.x * distanceScale;
}
And to apply the DRY principle (Don't Repeat Yourself): one could drop the initialisation of xMeter and call setX(x) in the constructor instead.
When called in the constructor it is important to make setX final, that is: not overridable.
The source of the problem is here:
public float xMeter = x * distanceScale;
The issue is that you're initializing this instance variable outside the constructor. As a result, since x is initialized to 0, the result of your multiplication is also 0.
If you need xMeter and yMeter initialized to a value based on x or y, simply declare them as you did the other fields:
public int xMeter;
And initialize their values in the constructor:
public newBody(int x, int y){
// initialize x and y ...
this.xMeter = x * distanceScale;
As others have mentioned, when the xMeter is initialized, the constructor is not called yet and x is still 0, so the value of xMeter is 0 as well.
To change that, you must update xMeter's value once x is initialized in the constructor, like so:
public NewBody(int x, int y){
this.x = x;
this.y = y;
// update x and y meter
xMeter = x * distanceScale;
yMeter = y * distanceScale;
}
However, you mentioned how you want xMeter to update every time x is changed as well. As it stands with your current code, that will not happen. However, a suggestion of mine would be to create a method to change the value of x (and y as well) and in those methods, also update the values of xMeter and yMeter. That way, whenever you want to change x, call the methods and it will update your other values too.
Try adding these methods and changing your constructor to this:
// called setter methods
public void setX(int x) {
this.x = x;
this.xMeter = x * distanceScale;
}
public void setY(int y) {
this.y = y;
this.yMeter = y * distanceScale;
}
// constructor
public NewBody(int x, int y){
setX(x);
setY(y);
}

Changing an abstract variable

Alright so I have an abstract class. Like the following.
public abstract class GameObject {
// VARIABLES //
protected float x = 0;
protected float y = 0;
}
*I actually have more to it than this but this is all that is needed.
What I am wanting to do is change x and y for all the classes extended off GameObject.
So if I did something like
x += 1;
y += 1;
Then every class that extends GameObject has the variables x and y = 1.
How would I go about doing this?
You can't do that as they currently are. They are instance variables, meaning that each instance of GameObject gets its own copy of the variables. If they are static variables, then all instances would share them.
I recommend to use two new variables in the class that renders the game, e.g. viewX and viewY, which you add to an object's x and y before drawing it. By modifying these two variables you can shift around all objects without modifying much data, e.g. like this:
float viewX = 0, viewY = 0;
void render() {
for (GameObject o : gameObjects)
draw(o.image, o.x + viewX, o.y + viewY);
}
void setCamera(float x, float y) {
viewX = x;
viewY = y;
}

Categories

Resources