Wish I could say that I'm new, but alas I'm just extremely rusty. I'm trying to make a few simple programs to get back into the basics I learned a couple of years ago. At the moment I have two separate classes: Entity and Game. I have made a player entity object and I would like to access it's x and y parameters in different methods, and eventually different classes as well.
My first instinct was to just use 'player.x' but unfortunately that only works within the same class and only with void methods. If I try using that anywhere else I keep getting a 'NullPointerException' error on the lines where I try to reference any parameter from player. Any advice on how to reference the x and y positions without that error being thrown, or even to just know why its only being thrown in non void methods (as ideally I want to use them in a calculation in a float method) would be greatly appreciated.
This is my entity class:
public class Entity {
public float x; //x position
public float y; //y position
public Entity(float x, float y){
this.x = x;
this.y = y;
}
//entity methods
}
This is my game class:
public class Game{
public static Entity player;
public static float posX = 2f;
public static float posY = 2f;
public Game(){
player = new Entity(posX, posY);
}
public static float test(){
float newX = player.x - 2f; //I would get the error here for example
return newX;
}
//Game methods
}
Thanks!
EDIT
Changed the Game class as suggested, still getting the same error.
public class Game {
public Entity player;
public float posX = 2f;
public float posY = 2f;
public float y = test();
public Game() {
player = new Entity(posX, posY);
}
public float test() {
float newX = player.x - 2f; //I would get the error here for example
return newX;
}
public void print() {
System.out.println(y);
}
public static void main(String[] args) {
Game game = new Game();
game.print();
}
}
Reason is simple. You are creating the player object in constructor. But using it in static method. So, your constructor is never called.
Try to make your method non-static
EDIT
You can do it two ways,
1 : make your test() method non-static and everything will work as charm.
public float test(){
float newX = player.x -2f;
return newX
}
and make your Entity player non-static.
2 : make your fields static and try to initialize them, before calling the test() method.
public class Entity {
public static float x; //x position
public static float y; //y position
public Entity(float x, float y){
this.x = x;
this.y = y;
}
//entity methods
public static void initialize(float tx, float ty){
x = tx;
y = ty;
}
public static float test(){
float newX = Player.x - 2f;
return newX;
}
Ofcourse, second one is not a great solution. But a workaround.
Related
Hi I am trying to write this piece of code about physics but have a problem.
In fact two problems:
1.the formula for gravitation its throwing a error about using the field .class
2.I want to declare the types of individual variables in a element
I think its clearer if I show the source code:
public class Main
{
public static void main(String[] args) {
}
abstract class Gravitation{
public abstract int Gravitation(int mass[],int dist,int force);
}
class PhySyst{
public int mass;
public int wt;
public float smallG = 9.8f;
//this is the posible value of charge
enum Charge{Positive,Negative,PositiveCoulumb,NegativeCoulumb,IsNegative,IsPositive};
}
class Earth extends Gravitation{
//stores acceleration due to gravity
public float smallG = 9.8f;
//the raduis of earth is needed in the physics formula for distance
public float GravityPressure = 6.67f;
public float raduisofEarth = 6371f;
//this finds the gravation using newtons principles
public int Gravitation(int mass[],int dist,int force)
{
force = (GravityPressure * mass[])/(dist * dist);
return force;
}
}
}
the error is this:
Main.java:32: error: '.class' expected
force = (GravityPressure * mass[])/(dist * dist);
^
1 error
Thanks for reading :)
Couple of Fixes here:
Constants should be static final (#constant).
Gm1m2/r2, formula so rather than array you should pass 2 input params (m1 and m2).
As multiplication is operation for number not array (mass[]).
Enum should be defined in public class or in static class.
As the force can be float, so change the return type to float from current int.
#JsonIgnoreProperties(ignoreUnknown = true)
class Category {
abstract class Gravitation {
public abstract float getGravitationalForce(int mass1, int mass2, int dist);
}
//this is the possible value of charge
enum Charge {
Positive, Negative, PositiveCoulumb, NegativeCoulumb, IsNegative, IsPositive
};
class PhySyst {
public int mass;
public int wt;
public float smallG = 9.8f;
}
class Earth extends Gravitation {
//stores acceleration due to gravity
public static final float SMALL_G = 9.8f; #constant
//the radius of earth is needed in the physics formula for distance
public static final float GRAVITATIONAL_PRESSURE = 6.67f; #constant
public static final float RADIUS_OF_EARTH = 6371f; #constant
//this finds the gravitation using newtons principles
public float getGravitationalForce(int mass1, int mass2, int dist) {
return (GRAVITATIONAL_PRESSURE * mass1 * mass2) / (dist * dist);
}
}
}
My singleton class:
public class XandY {
private double x, y;
private static XandY xy;
//Constructor sets an x and y location
private XandY() {
x = 210.0;
y = 100.0;
}
public static XandY getXandY() {
if (xy == null)
xy = new XandY();
return xy;
}
public void updateXandY() {
x += 10;
y += 5;
}
}
Other class that changes singleton values and tries to reinitialize. My question is if I call changeXandY a few times then want to call resetXandY how do I make it reset back to the original x and y?
public class GameWorld {
private List<GameObject> objects;
public void initialize() {
objects = new ArrayList<GameObject>();
objects.add(XandY.getXandY());
...add other objects that are not singletons
}
public void changeXandY {
for (int i=0; i<gameObject.size(); i++) {
if (gameObject.get(i) instanceof XandY)
((XandY)gameObject.get(i)).updateXandY();
}
public void resetXandY {
initialize();
}
}
For this use case, you could simply store them as default values. Such as
private double x, y;
private static XandY xy;
private static final double default_x = 210.0;
private static final double default_y = 100.0;
That way when you reset, just:
public void resetXandY {
this.x = default_x;
this.y = default_y;
}
That being said, you may want to change your default constructor to look the same way.
If you can make the XandY reference protected, you can use a static initializer in an anonymous subclass:
// I need to reset the singleton!
new XandY(){
{ xy = null; }
};
But really, if you need to be able to (re)initialize the singleton, you should put a method to that effect into its signature. Obscure solutions are, at best, still obscure...
Create a resetXandY() method to set default value:
public class XandY {
private double x, y;
private static XandY xy;
//Constructor sets an x and y location
private XandY() {
x = 210.0;
y = 100.0;
}
//reset x=0 and y=0
public void resetXandY() {
x = 0;
y = 0;
}
public static XandY getXandY() {
if (xy == null)
xy = new XandY();
return xy;
}
public void updateXandY() {
x += 10;
y += 5;
}
}
Lets say I have two classes. Pair:
public class Pair<X, Y> {
public X x;
public Y y;
public Pair(X x , Y y) {
this.x = x;
this.y = y;
}
}
and the class Triple:
public class Triple<X, Y, Z> {
public X x;
public Y y;
public Z z;
public Triple(X x , Y y, Z z) {
this.x = x;
this.y = y;
this.z = z;
}
}
And I want to create a class Test without changing the class header (can't do Test<X, Y, Z>):
public class Test {
...
}
In this class should be a method, that takes a list of Triples and should return a Map with the x-value of the triple as a key and the y and z-values of the triple as the value of the map.
How can I do this without changing the class header?
You can do it. You need to make the method generic rather than the class it's in.
class Test {
static <X, Y, Z> Map<X, Pair<Y, Z>> makeMap(List<Triple<X, Y, Z>> triples) {
// your implementation
}
}
The method could be static or non-static. In either case, the generic parameters <X, Y, Z> appear immediately before the return type.
From your description, here an implementation:
public static <X, Y, Z> Map<X, Pair<Y, Z>> makeMap(List<Triple<X, Y, Z>> arg) {
return arg.stream().collect(Collectors.toMap(e -> e.x, e -> new Pair<>(e.y, e.z)));
}
I am trying to master the fundamentals of Java and OOP. From my understanding, if I have an object Circle that is instantiated with the variable radius, and passes that to a double x, should methods of the Object be able to access these?
package classes;
public class Circle {
Circle(double radius) {
double x = radius;
}
double area() {
return x * x * 3.1415; // x can't be resolved to a variable
}
}
x is only available within the scope of the Circle constructor. Declare it at class level so it can be accessed by the area method
public class Circle {
private double x;
Circle(double radius) {
this.x = radius;
}
...
}
Here you have a scope problem. When you declare x inside the constructor, you are telling that it will only be accessible inside it.
You may want to declare it outside:
public class Circle {
double x;
Circle(double radius) {
x = radius;
}
...
}
After defined at class level use 'this' for readiblity.
public class Circle {
private double x =0.0;
Circle(double radius) {
this.x = radius;
}
double area() {
return this.x * this.x * 3.1415; // x can't be resolved to a variable
}
}
In your example, the double x is limited in scope to the constructor. If you move it out to the object level, it will work as you expect.
public class Circle {
private double x;
Circle(double radius) {
this.x = radius;
}
double area() {
return x * x * 3.1415;
}
}
Try this code :
public class Circle {
private double x =0.0;
Circle(double radius) {
this.x = radius;
}
double area() {
return this.x * this.x * Math.PI;
}
}
I have the class GameObject:
public class GameObject{
private Coordinate coordinates;
public GameObject(){
coordinates = new Coordinate();
}
public void setCoordinates(int x, int y){
coordinates.x = x;
coordinates.y = y;
}
//More methods here
}
public class Coordinate{
public int x, y;
public Coordinate(){
}
public Coordinate(int x, int y){
this.x = x;
this.y = y;
}
public void setCoordinate(int x, int y){
this.x = x;
this.y = y;
}
And two classes Champion and Spell:
public class Spell extends GameObject{
//Some methods
}
public class Champion extends GameObject{
//Some methods
public Spell fireBall = new Spell();
}
And in my main class:
Champion character = new Champion();
If I call character.setCoordinates(200, 300); (just random numbers), the character goes to these exact coordinates. But the Spell fireBall also goes to (200, 300). So the coordinates in Spell are overriden by the setCoordinates(int x, int y) call to character. How is this possible?
TL;DR - Two classes from GameObject, Spell extends GameObject and Champion extends GameObject, override eachother coordinates. Why?
For full source code:
GameObject.java
Spell.java
Champion.java
Coordinate.java
Looking at your code in gitHub you have 2 methods:
//Set the coordinates for this GameObject
public void setCoordinates(int x, int y){
this.coordinates.x = x;
this.coordinates.y = y;
}
public void setCoordinates(Coordinate coordinates){
this.coordinates = coordinates;
}
If you ever use the 2nd one, then you are sharing the same instance of Coordinates so changing one will change the other
The solution is to copy the values instead
public void setCoordinates(Coordinate coordinates){
this.coordinates.x = coordinates.x;
this.coordinates.y = coordinates.y;
}
In the class Spell you set the coordinates:
this.startCoordinates = startCoordinates;
setCoordinates(this.startCoordinates);
Subsequently this code
if (getCoordinates().x - startCoordinates.x < range) {
is equivalent to
if (getCoordinates().x - getCoordinates().x < range) {
because getCoordinates() references the same object as startCoordinates does.
Your setter method just sets the reference, but it does not copy the object.