how can I use the constructor from another class in java to make an object through a method in separate class. For example below is a constructor in a player class
public class Player extends Entity {
public Player(int maxEnergy, int x, int y) {
this.maxEnergy = maxEnergy;
this.energy = maxEnergy;
carryingGhost = false;
xPos = x;
yPos = y;
}
Which I want to use and create objects (player) through a method called
private Player createPlayer() {
and the above method is in separate class as
public class GameEngine {
**The method must return a Player object that represents the player in the
game. it must set the maxEnergy for the player, and the
X and Y positions corresponding to a tile position in the current level.
I have tried to initialize player within method with parameters and
without parameters as**
Player player = new Player(int maxEnergy, int x, int y);
this.player.getEnergy();
this.player.getMaxEnergy();
this.player.setPosition(x, y);
return player;
}
But it give errors.Any help will be appreciated.I am quite close to assume its not possible to have created objects like this.
below I share the complete game engine which is working with other classes as well .
import java.awt.Point;
import java.util.ArrayList;
import java.util.Random;
public enum TileType {
WALL, FLOOR1, FLOOR2, BANK, BREACH, DOOR;
}
public static final int LEVEL_WIDTH = 35;
public static final int LEVEL_HEIGHT = 18;
private Random rng = new Random();
private int levelNumber = 1; //current level
private int turnNumber = 1;
private GameGUI gui;
private TileType[][] level;
private ArrayList<Point> spawnLocations;
private Player player;
private Ghost[] ghosts;
public GameEngine(GameGUI gui) {
this.gui = gui;
}
private TileType[][] generateLevel() {
//YOUR CODE HERE
return null; //change this to return the 2D arrayof TileType
//values that you create above
}
private ArrayList<Point> getSpawns() {
ArrayList<Point> s = new ArrayList<Point>();
// YOUR CODE HERE
return s;
}
private Ghost[] addGhosts() {
//YOUR CODE HERE
return null; //change this to return an array of ghost objects
}
**/**
* Creates a Player object in the game. The method instantiates
* the Player class and assigns values for the energy and position.
* The first version of this method should use fixed a fixed position
for the player to start, by setting fixed X and Y values when calling
the constructor in the Player class. The second version of this method
should use the spawns ArrayLis to select a suitable location to spawn
the player and removes the Point from the spawns ArrayList. This will
prevent the Player from being added to the game inside a wall, bank or
breach for example.
#return A Player object representing the player in the game
*/**
private Player createPlayer() {
//YOUR CODE HERE
return null; //change this to return a Player object
}
public void movePlayerLeft() {
}
public void movePlayerRight() {
}
public void movePlayerUp() {
}
public void movePlayerDown() {
}
private void hitGhost(Ghost g) {
}
private void moveGhosts() {
}
private void moveGhost(Ghost g) {
}
private void cleanDefeatedGhosts() {
}
private void nextLevel() {
}
private void placePlayer() {
}
public void doTurn() {
cleanDefeatedGhosts();
moveGhosts();
gui.updateDisplay(level, player, ghosts);
}
public void startGame() {
level = generateLevel();
spawnLocations = getSpawns();
ghosts = addGhosts();
player = createPlayer();
gui.updateDisplay(level, player, ghosts);
}
}
I have used below method and its not showing error so far.
private Player createPlayer() {
int energy=player.getEnergy();
int maxEnergy=player.getMaxEnergy();
int xPos=player.xPos;
int yPos=player.yPos;
return new Player(maxEnergy,xPos,yPos);
}
The following should do it:
private Player createPlayer() {
int defaultMaxEnergy = 10; // Whatever value it should have
int initialX = 1; // Whatever value it should have
int initialY = 1; // Whatever value it should have
return new Player(defaultMaxEnergy, initialX, initialY);
}
Since the values are not in your descriptions I just selected a random number but you can pick whatever integers you want and that makes sense.
Does something like this work for your case?
public class GameEngine {
private Player createPlayer() {
return new Player(1,2,3);
}
}
Add a default no-args constructor in the player class. Once you create a constructor with Arg, java will not auto provide default one.
You have already declared Player
private Player player;
So you must not try to reinitialize using same variable name, rather
private Player createPlayer() {
Player newPlayer = new Player();
// set the different props of the Player obj
return newPlayer ;
}
What is the error which you are facing ? Can you share that ?
I'm putting together a game in Java. Basically, you need to avoid oncoming game objects. I want to recreate these objects once they have left the screen.
I'm trying to adhere to design patterns, I currently have a GameObject Factory that is responsible for creating the game worlds' objects. All of these objects are derived from an abstract GameObject. I was considering creating a Recreatable interface that exposed a recreate method, that recreate method then expects a GameObject Factory which in turn returns another random version of that game object.
Like this
public class Ghost extends GameObject implements Recreatable, Movable {
private int x;
private int y;
private int dx;
private int dy;
public Ghost(int x, int y) {
this.x = x;
this.y = y;
dx = 3;
dy = 5;
}
public void move() {
// move logic ...
}
public GameObject recreate(GameObjectFactory gameObjectFactory) {
return gameObjectFactory.getInstance("ghost");
}
}
I could then just check if it's an instance of re-creatable and if so add that recreated object to my list of moving game objects instead of doing a switch case/if else block of all the possible game objects.
This is an example of how it would look with the recreate method
public class GameSurfaceView extends SurfaceView implements Runnable {
private ArrayList<Movable> movables;
private GameObjectFactory gameObjectFactory;
public GameSurfaceView(Context context) {
super(context);
gameObjectFactory = new GameObjectFactory(this);
}
#Override
public void run() {
while (isRunning) {
if (!myHolder.getSurface().isValid())
continue;
ListIterator<Movable> movableListIterator = movables.listIterator();
while (movableListIterator.hasNext()) {
Movable movable = movableListIterator.next();
movable.move(canvas);
if (movable.hasPassedScreen()) {
if (movable instanceof Recreatable) {
Recreatable recreatable = (Recreatable) movable;
movableListIterator.set(recreatable.recreate(gameObjectFactory));
}
}
}
myHolder.unlockCanvasAndPost(canvas);
}
}
}
The if/else would look more like this for the run method
while (movableListIterator.hasNext()) {
Movable movable = movableListIterator.next();
movable.move(canvas);
if (movable.hasPassedScreen()) {
if (movable instanceof GhostObject) {
movableListIterator.set(gameObjectFactory.getInstance("ghost"));
} else if (movable instanceof WitchObject) {
movableListIterator.set(gameObjectFactory.getInstance("witch"));
} else if (movable instanceof VampireObject) {
movableListIterator.set(gameObjectFactory.getInstance("vampire"));
} else if (movable instanceof ZombieObject) {
movableListIterator.set(gameObjectFactory.getInstance("zombie"));
}
}
}
Is this a bad way of going about it?
I have two classes BouncingBall and another one called ElasticBall. Both classes extends BallImpl which implements an interface called Ball.
public interface Ball {
int DEFAULT_RADIUS = 50;
int radius();
Point center();
void update();
}
public class BouncingBall extends BallImpl {
public static final int MOVEMENT_SPEED = 12;
static final int DOWN = 1;
static final int UP = -1;
private int direction;
BouncingBall(int x, int y, int direction) {
super(x, y);
this.direction = direction;
}
#Override
public void update() {
direction = reverseDirectionIfNecessary();
y = move();
}
private int reverseDirectionIfNecessary() {
if (movingTooHigh() || movingTooLow()) {
return switchDirection();
}
return this.direction;
}
private boolean movingTooLow() {
return y + radius >= BallWorld.BOX_HEIGHT && movingDown();
}
private boolean movingTooHigh() {
return y - radius <= 0 && movingUp();
}
private int switchDirection() {
return movingDown() ? UP : DOWN;
}
private int move() {
return y + (MOVEMENT_SPEED * direction);
}
private boolean movingDown() {
return direction == DOWN;
}
private boolean movingUp() {
return direction == UP;
}
}
public class ElasticBall extends BallImpl {
public static final int GROWTH_RATE = 2;
static final int GROW = 1;
static final int SHRINK = -1;
private int growthDirection;
ElasticBall(int x, int y, int radius, int growthDirection) {
super(x, y, radius);
this.growthDirection = growthDirection;
}
#Override
public void update() {
growthDirection = reverseGrowthDirectionIfNecessary();
radius = next();
}
private int reverseGrowthDirectionIfNecessary() {
if (growingTooBig() || shrinkingTooSmall()) {
return switchDirection();
}
return this.growthDirection;
}
private boolean shrinkingTooSmall() {
return radius <= 0 && shrinking();
}
private boolean growingTooBig() {
return radius >= Ball.DEFAULT_RADIUS && growing();
}
private int switchDirection() {
return growing() ? SHRINK : GROW;
}
private int next() {
return radius + (GROWTH_RATE * growthDirection);
}
private boolean shrinking() {
return growthDirection == SHRINK;
}
private boolean growing() {
return growthDirection == GROW;
}
}
I need to create a BouncingElasticBall which combines the behavior of the BouncingBall and the ElasticBall classes. I have poor knowledge in OOP, and I know Java does not allow multiple inheritance, so how can I solve this problem?
Thanks in advance.
One way you could approach this is to not extend BallImpl, but make sort-of plugins. Like this:
public class BallImpl implements Ball {
List<BallBehavior> behaviors = ...
#Override
public void update() {
behaviors.forEach(behavior -> behavior.update(this));
}
...
}
public interface BallBehavior {
void update(BallImpl ballImpl);
}
And then, just write your elastic and bouncing logic as behaviors.
Once you diverge hierarchies there's no way to merge them in java.
It's a design matter: if you know that ElasticBall and BouncingBall may be combined together, you should create two interfaces Elastic and Bouncing, both extending interface Ball, with common methods valid for both.
Then the common method implementations may be set into a common abstract class, let's say AbstractBall. At this point you can finally detail your three implementations:
ElasticBall extends AbstractBall implements Elastic
BouncingBall extendis AbstractBall implements Bouncing
ElasticBouncingBall extends AbstractBall implements Elastic, Bouncing
In this way you'll be able to control what to do in each method, reuse code for common stuff (in the abstract class).
You can use interfaces that allows multiple inheritance. Make the interface for each ballElasticBall and BouncingBall and implement both of them in BouncingElasticBall.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
i have 4 classes (Core, GameMain, Spriter, Character)
- GameMain extends core (core >> GameMain)
- Character extends Spriter (Spriter >> Character)
I get a NullPointerException if i call the - b.get...() - Methods without overriding them in Character (they are originally inside Spriter, i call them from GameMain through Character).
i make objects of Character inside Core and put it in an ArrayList
public abstract class Core {
ArrayList<Character> mon = new ArrayList<Character>();
void gameloop(){
while(running){
//some code
while(mon.size() < 2){
mon.add(new Character(blk_1,5,1));// Character(Spriter, Long, Long){}
}
draw(g);
}
}
}
then inside GameMain i call a Method that is originally inside Spriter but i call it through Character.
public class GameMain extends Core{
public void draw(Graphics2D g){
for(Character b : mon){ //mon is the ArrayList<Character>
if(test.getCoordY() <= b.getCoordY() - (b.getHeight()/2)){ //<<<< NullPointerException caused by these two Methods , test is a Spriter class
g.drawImage(chChange(), Math.round(test.getX()), Math.round(test.getY()), test.getWidth(), (test.getHeight()), null);
g.drawImage(b.getImage(), Math.round(b.getX()), Math.round(b.getY()), null);
}else {
g.drawImage(b.getImage(), Math.round(b.getX()), Math.round(b.getY()), null);
g.drawImage(chChange(), Math.round(test.getX()), Math.round(test.getY()), null);
}
}
}
}
Here is the Spriter's Method, unless i override it i will get the error.
public class Spriter {
Spriter(Image i){
this.i = i;
scenes = new ArrayList();
}
Spriter(){
scenes = new ArrayList();
start();
}
public int getHeight(){
return i.getHeight(null);
}
public float getCoordY(){
float cy;
cy = y + i.getHeight(null); //<<<< NullPointerException happens here, Image i;
return cy;
}
public void setX(float x){
this.x = x;
}
public void setY(float y){
this.y = y;
}
// other similar Methods but no problem with them
//-------------------------------------- Animation Part ----------------------------------------------
public synchronized void addScene(Image i,long t){
total_t+=t;
scenes.add(new oneScene(i, total_t));
}
//start animation
public synchronized void start(){
mov_time = 0;
scn_indx = 0;
}
// get current scene
public synchronized Image getAnimeImage(){
if(scenes.size()==0){
return null;
}else{
return getScene(scn_indx).pic;
}
}
//get the scene
private oneScene getScene(int x){
return (oneScene)scenes.get(x);
}
private class oneScene{
Image pic;
long endTime;
public oneScene(Image pic, long endTime){
this.pic = pic;
this.endTime = endTime;
}
}
}
it would work if i do this :
public class Character extends Spriter{
public Character(Spriter s, long health, long power) {
this.s = s;
this.health = health;
this.power = power;
s.setX(randomY());
s.setY(randomY());
}
public float getCoordY(){
return s.getCoordY();
}
public float getHeight(){
return s.getgetHeight();
}
//some other methods for health and power
}
but can it work if i do this (it is already givinng the error but how to avoid it) :
public class Character extends Spriter{
public Character(Spriter s, long health, long power) {
this.s = s;
this.health = health;
this.power = power;
s.setX(randomY()); //setting x for the dynamiclly generated Character Object
s.setY(randomY()); // same for y
}
//some methods for power and health
}
as setting x,y for test (its a sprite and working very good)
public class GameMain extends Core{
public void init(){
test.setX(500); test.setY(488);
}
public void draw(Graphics2D g){
//the above code
}
}
i dont see the point of overriding them if they will be exactly the same.
Your problem is that when you create a Character, you're calling the no-arg constructor of Spriter, instead of the one with an Image argument. That means that your image is never getting set; which is why you have the null pointer exception.
You should probably add an Image to the constructor arguments of Character, and pass this along to the superclass constructor, like this.
public Character(Spriter s, long health, long power, Image img) {
super(img);
// and so on.
#ElliottFrisch - I apologise if that is what you were trying to say with your answer. I don't mean to duplicate; I just wasn't quite sure whether that is what you meant. In any case, this is definitely the problem.
I believe your problem is that your class Character is-a Spriter and has-a Spriter (and probably shouldn't "have-a" Spriter but I can't tell because you didn't post all of your code). You never initialized the super instance of your Character.
public class Character extends Spriter{
public Character(Spriter s, long health, long power) {
// super(health, power); // <-- Speculation, no constructors shown in your code.
this.s = s;
this.health = health;
this.power = power;
super.setX(randomY()); //<-- set the super value
super.setY(randomY()); //<-- again.
// s.setX() // <-- not sure, why do you have s?
}
I have no idea what immutable class should look like but am pretty sure this one is. Am I right? If I'm not please specify what should be added/removed.
import java.io.Serializable;
public class Triangle implements IShape, Serializable {
private static final long serialVersionUID = 0x100;
private Point[] points;
public Triangle(Point a, Point b, Point c) {
this.points = new Point[]{a, b, c};
}
#Override
public Point[] getPoints() {
return this.points;
}
#Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (this == obj) return true;
if (getClass() != obj.getClass()) return false;
Point[] trianglePoints = ((Triangle) obj).getPoints();
for (int i = 0; i < points.length; i++){
if (!points[i].equals(trianglePoints[i])) return false;
}
return true;
}
}
Will this do the trick?
#Override
public Point[] getPoints() {
Point[] copyPoint = {
new Point(points[0]),
new Point(points[1]),
new Point(points[2]),};
return copyPoint;
}
Point class:
import java.io.Serializable;
public class Point implements Serializable {
private static final long serialVersionUID = 0x100;
public int x;
public int y;
public int z;
public Point(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public Point(Point that) {
this.x = that.x;
this.y = that.y;
this.z = that.z;
}
public boolean equals(Object obj) {
// assume this is a typical, safe .equals implementation
// that compares the coordinates in this instance to the
// other instance
return true;
}
}
No, you can change what's in the Points array. If you want to make it immutable, have the getter hand out a copy of the Points array, not the original.
try this:
Triangle triangle = new Triangle(a, b, c);
triangle.getPoints()[1] = null;
System.out.println(Arrays.toString(triangle.getPoints()));
Also Point needs to be immutable (as Nikita Rybak points out). For how to copy arrays see how to copy an array in Java.
No, it's not. You expose the Point[] and a caller could modify its contents. Also, your class is not final, so someone could subvert it by subclassing it.
No, it's definitely mutable.
Not only do you expose the actual Point[] array, you don't defensive-copy (Bloch 2nd ed., Item 39) the Point objects themselves when taking them in via the constructor.
The Point[] array could have items
removed or added to it, so it's
mutable.
You could pass in Points a,
b, and c, then call setX() or setY()
on them to change their data after
construction.
Close. For one thing, an immutable class should make it's fields final, but that's not a requirement.
However, you are exposing an array through the getter, and that is not immutable. Make a defensive copy using Arrays.copyOf(array, length):
#Override
public Point[] getPoints() {
return Arrays.copyOf(this.points,this.points.length);
}
Here's what I'd do to make this class immutable, with the help of Guava. I see from the #Override in the code you posted that IShape seems to require a Point[] from the getPoints() method, but I'm ignoring that for the sake of example since the use of object arrays is a rather poor idea, especially if you want immutability (since they cannot be immutable and all).
public final class Triangle implements IShape, Serializable {
private final ImmutableList<Point> points;
public Triangle(Point a, Point b, Point c) {
this.points = ImmutableList.of(a, b, c);
}
public ImmutableList<Point> getPoints() {
return this.points;
}
// ...
}
Point should also be more like:
public final class Point implements Serializable {
/*
* Could use public final here really, but I prefer
* consistent use of methods.
*/
private final int x;
private final int y;
private final int z;
public Point(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
// getters, etc.
}
In order to be an immutable class, it is not enough that your methods promise not to change the object. In addition to having all fields be private and the methods not allow changing, you must also guarantee that the subclasses have the same promise of immutability. This includes making the class itself final, and ensuring that no references to the fields are ever returned.
A short, but excellent treatment of this can be found in this article:
http://www.javaranch.com/journal/2003/04/immutable.htm
Not only do you need to provide an immutable copy of the internalised array, you also need to make sure that the Point object is immutable.
Consider the following use of the Point class in the standard Java API:
Point a = new Point(1,1);
Point b = new Point(1,1);
Point c = new Point(1,1);
Triangle triangle = new Triangle(a, b, c);
System.out.println(Arrays.toString(triangle.getPoints()));
c.setLocation(99,99);
System.out.println(Arrays.toString(triangle.getPoints()));
It is not immutable because ...
Triangle t1 = new Triangle(new Point(0,0), new Point(0, 10), new Point(10, 10));
Triangle t2 = t1;
System.out.println( t1.getPoints()[0] ); // -> 0
t2.getPoints()[0].x = 10;
System.out.println( t1.getPoints()[0] ); // -> 10
Thus the class is not immutable because you can change the state of an instance (internal Point[] exposed) and this also changes the state of a reference to the same instance.
To make it a true immutable class, you would need methods to separately get X and Y from each point, for example:
public int getPointX(int point) { return points[point].x; }
public int getPointY(int point) { return points[point].y; }
or
public Point getPoint(int point) { return new Point(points[point]); }
or return a copy of the points like you suggested in your edit.
In addition to what others have already noted, you should:
Make your Triangle class final to prevent the creation of mutable Triangles by subclasses.
Declare all the fields final, to catch accidental modification of fields by the class itself.
In "Effective Java," Joshua Bloch provides a list of rules for immutable classes in general, in Item 15: Minimize Mutability.
1) Make members private and final - so
private Point[] points; //should be
private final Point[] points;
2) Make class final so it cannot be sub-classed
3) Exclusive access to mutable members (array) - meaning return copy of and not the reference to mutable members
For the best treatment of this subject refer to Joshua Bloch, Effective Java- item 15
This could be a better Point implementation.
import java.io.Serializable;
public final class Point implements Serializable {
private static final long serialVersionUID = 0x100;
private final int x;
private final int y;
private final int z;
public Point(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public Point(Point that) {
this(that.x, that.y, that.z );
}
public boolean equals(Object obj) {
// assume this is a typical, safe .equals implementation
// that compares the coordinates in this instance to the
// other instance
return true;
}
}
Other than exposing the array (as getters are wont to do) and not being final, being serialisable is "problematic".
As a very nasty man, when deserialising, I can get another reference to the internal array. The obvious fix for this is:
private void readObject(
ObjectInputStream in
) throws ClassNotFoundException, IOException {
ObjectInputStream.GetField fields = in.readFields();
this.points = ((Point[])(fields.get("point", null)).clone();
}
That still leaves the problem of points not being final and exposing the object without points initialised (or worse, but a bit thoeretical, partially initialised). What you really want is a "serial proxy", which you can find out about on the internets...
Note: If you implement equals you should also implement hashCode, probably toString and possible Comparable.
Point itself doesn't have to be immutable for Triangle to be immutable. You just have to do a lot of defensive copies so that nobody has a reference to the Point objects stored in the Triangle.
Also, shouldn't triangle a-b-c equal triange b-c-a (and 4 other permutations)
A immutable class example with mutable field:
public final class ImmutabilityTest {
private final int i;
private final C c1;
ImmutabilityTest(int i, C c1){
this.i = i;
this.c1 = c1;
}
public int getI() {
return i;
}
public C getC1() {
return (C)c1.clone();//If return c1 simply without calling clone then contract of immutable object will break down
}
#Override
public String toString() {
return "ImmutabilityTest [i=" + i + ", c1=" + c1 + "]";
}
public static void main(String[] args) {
ImmutabilityTest i1 = new ImmutabilityTest(10, new C(new D("before")));
System.out.println(i1);
i1.getC1().getD1().name = "changed";
System.out.println(i1);
}
}
class C implements Cloneable{
D d1;
public C(D d1) {
super();
this.d1 = d1;
}
public D getD1() {
return d1;
}
public void setD1(D d1) {
this.d1 = d1;
}
#Override
public String toString() {
return "C [d1=" + d1 + "]";
}
public C clone(){
C c = null;
try {
c = (C) super.clone();
c.setD1(c.getD1().clone());// here deep cloning is handled if it is commented it will become shallow cloning
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return c;
}
}
class D implements Cloneable{
String name;
public D(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "D [name=" + name + "]";
}
public D clone(){
D d = null;
try {
d = (D) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return d;
}
}