I'm writing animation program, in which many balls are running around and bouncing.
I made Ball class which represents ball's behaviour.
When I implement ball's collisioin with another ball,
I have to check the all other balls.
So I made this class.
public class Ball{
private static final List<Ball> allBalls;
static{
allBalls = new ArrayList<>();
}
private Ball(){}
public static Ball getNewBall(){
Ball ball = new Ball();
allBalls.add(ball);
return ball;
}
public void collision(){
for(Ball b : allBalls){
//check whether b is colliding with me
//and if colliding, change speed of me and b.
}
}
}
Is this kind of design (to hold all objects in private static list) good or bad ?
What you should have is a BallManager class that will handle that stuff.
public class BallManager {
private static BallManager instance = new BallManager();
private BallManager(){}
public static BallManager getInstance() {
return instance;
}
public List<Ball> ballsInPlay = new ArrayList<>();
public void createBall(int x, int y) {}
public void checkCollisions() {
// loop ball list and check collisions
// perform cleanup based on collisions
}
private void ballCleanup(){}
}
public class Ball{
public Ball(){}
public void collision(Ball other){}
}
NOTE: Changed from static class to singleton. Also, fixed the compilation error by adding () after checkCollisions method
Create Singleton BallManager using enum.
enum singleton are best to use.
Improving the previous answer.
public enum BallManager {
INSTANCE;
public List<Ball> ballsInPlay = new ArrayList<>();
public void createBall(int x, int y) {}
public void checkCollisions() {
// loop ball list and check collisions
// perform cleanup based on collisions
}
private void ballCleanup(){}
}
public class Ball{
public Ball(){}
public void collision(Ball other){}
}
Related
I have one super class, which called game that. It looks like this:
import java.util.ArrayList;
public class Game {
private ArrayList<Enemy> enemies = new ArrayList<Enemy>();
private ArrayList<Tower> towers = new ArrayList<Tower>();
private int corridorLength;
private int currentPosition = 0;
public Game(int corridorLength){
this.corridorLength = corridorLength;
}
public void addTower(int damage,int timeStep){
this.towers.add(new Tower(damage,timeStep)); // Add tower with
current position corrdor length
}
public void addEnemy(int health, int speed){
this.enemies.add(new Enemy(health,speed));
}
public void advance(){
this.currentPosition = this.currentPosition + 1;
if(this.currentPosition == this.corridorLength){
System.out.println("Game Over");
}
}
public void printDamage(){
System.out.println(this.towers.get(this.currentPosition));
}
}
The main focus is on the public void addTower(int, int)
So, I have a subclass called Tower:
public class Tower extends Game {
public Tower(int damage, int timeStep){
super.addTower(damage,timeStep);
}
public void getDamage(){
super.printDamage();
}
}
And subclass of the Tower subclass called Catapult:
public class Catapult extends Tower {
public Catapult(){
super(5,3);
}
}
I am new to Java and can't see what am I doing wrong here. Why do I need a default constructor for the Tower in the Game?
You need to explicitly declare default constructor in Game class.
public Game (){}
Since, Object instantiation chained to Object class during that, it will call its super class constructor. You have explicitly declared arg-constructor in Game, so default constructor won't be added automatically.
I got the object wolfOne of the Class Wolf, and I need to access to its variable mAlive in another Class, how may I don it?
Wolf wolfOne;
//Wolf Class
public class Wolf extends Card {
public Wolf(){
mCharacter = "Wolf";
}
public void savage(Card card) {
card.mAlive = false;
}
}
//Card Class
public class Card {
//Names
public String mCharacter;
//Status
public static boolean mAlive;
public static boolean mDefended;
public static boolean mOwled;
public static boolean mLastSavaged;
public static boolean mLastLynched;
//Constructor
public Card() {
// Do Card specific stuff.
}
}
Remove static from all of your Class variables - make them instance variables instead. Then provide typical getters/setters for each, allowing clients of the class to retrieve or mutate the value:
public class Wolf extends Card {
public Wolf(){
setMCharacter("Wolf");
}
public void savage(Card card) {
card.setMAlive(false);
}
}
public class Card {
//Names
private String mCharacter;
//Status
private boolean mAlive;
private boolean mDefended;
private static boolean mOwled;
private static boolean mLastSavaged;
private static boolean mLastLynched;
public String getMCharacter(){}
return mCharacter;
}
public void setMCharacter(String value){
this.mCharacter = value;
}
public boolean getMAlive(){
return mAlive;
}
public void setMAlive(boolean alive){
this.mAlive = alive
}
//....So on and so forth
}
static has a special meaning in Java. It doesn't mean that the variable or method is inheritable; it means that there is only one of it that belongs to the class, not the instance.
To inherit from a super class, all that is required is that it not private and the inheriting classes will get it. The following example shows this relationship.
import java.util.*;
import java.lang.*;
import java.io.*;
class A
{
public String name;
public boolean isAlive;
public A()
{
name = "A";
isAlive = true;
}
}
class B extends A
{
public B()
{
name = "B";
isAlive = false;
}
}
public class Main
{
public static void main (String[] args)
{
A a = new A();
A b1 = new B();
B b2 = new B();
b2.name = "B2";
b2.isAlive = true;
System.out.println(a.name);
System.out.println(a.isAlive);
System.out.println(b1.name);
System.out.println(b1.isAlive);
System.out.println(b2.name);
System.out.println(b2.isAlive);
}
}
And gives this output:
A
true
B
false
B2
true
This can be run here.
In the card class make the fields private not public, in oo this is called encapsulation or data hiding (look it up). Then simply add a getMAlive method that returns the mAlive value and a setMAlive method which will set it. Now in your wolf class to set mAlive you can with setMAlive(boolean). For external objects you will need to have a reference to your wolf/card and call wolfName.getMAlive()
For card...
private boolean mAlive;
public boolean getMAlive(){
return mAlive;
}
public void setMAlive(boolean value){
mAlive = value;
}
For wolf...
public void savage(){
setMAlive(false);
}
For other classes to get mAlive...
wolfName.getMAlive()
You may consider making your mAlive (and other fields in Card) protected. Protected fields can only be seen by those classes that extend them e.g. wolf. So in wolfs savage method you could do...
public void savage(){
mAlive = false;
}
But to set mAlive from other classes you would still need a setter in Card so yeah
I hope this helps :) good luck
I got a very easy question here, but don't know in what direction to search...
I built a class that extends another class with an uninstantiated object. How do I make sure I dont forget to instantiate the object in the subclass? Here's what I mean:
public class Hitbox{
....
}
public class Enemy{
protected Hitbox hbox; // edit: changed to protected
}
public class AngryLady extends Enemy{
hbox = new Hitbox(10, 20); // Must not forget this!
}
One way would be to always check if (hbox!=null) before using thishandle, but that feels silly. There has to be an easier way like with abstract classes, where already the compiler gives an error when a method from the abstract class has not been implemented.
Just initialize your variable in the constructor of the parent class:
public abstract class Enemy{
protected Hitbox hbox;
public Enemy(int a, int b) {
hbox = new Hitbox(a, b);
}
}
public class AngryLady extends Enemy {
public AngryLady(int a, int b) {
super(a, b);
}
}
If you need a different HitBox instance per subclass of Enemy, use Factory method pattern. This is a very simple example:
public enum HitboxType {
ANGRY
}
public final class HitboxFactory {
private HitboxFactory() {
}
public static Hitbox createHitbox(HitboxType hitboxType) {
switch(hitboxType) {
case HitboxType.ANGRY:
return new AngryHitbox();
case <another_case>:
return <respective hitbox>
}
//in case of invalid parameter
return null;
}
}
And it would be better using dependency injection:
public abstract class Enemy{
protected Hitbox hbox;
public Enemy(Hitbox hitbox) {
hbox = hitbox;
}
}
public class AngryLady extends Enemy {
public AngryLady(Hitbox hitbox)) {
super(hitbox);
}
}
//...
AngryLady angryLady = new AngryLady(HitboxFactory.createHitbox(HitboxType.ANGRY));
//...
Another tip in case you don't want to have null Hitboxes is to create an empty Hitbox:
public class EmptyHitbox extends Hitbox {
public EmptyHitbox() {
super(0,0); //or whatever arguments it needs
}
}
And in the factory method:
public static Hitbox createHitbox(HitboxType hitboxType) {
switch(hitboxType) {
/* ... */
}
//in case of invalid parameter
return new EmptyHitbox();
}
First it should be protected since subclass doesn't have access to private fields.
public class Enemy{
protected Hitbox hbox;
}
To make sure you don't forget, you should really initiate the object where you are declaring it - the parent class.
public class Enemy{
//if you just don't want/need to define a constructor explicitly and you know a b ahead.
int a = 0;
int b = 0;
protected Hitbox hbox = new Hitbox(a, b);
}
In this case, you can always use hbox in the subclass without worrying about it.
Since the hbox field is inherited from the parent class, it should be initialized at the parent class:
public class Enemy {
private final static int DEFAULT_H = 10;
private final static int DEFAULT_W = 10;
// default initialization
private HitBox hbox = new HitBox(DEFAULT_W,DEFAULT_H);
public HitBox getHBox() {
return hbox;
}
}
Unless hbox must be initialized differently for each subclass, in which case you should use chained constructors to initialize the HitBox.
public class Enemy {
private final HitBox hbox;
public Enemy(HitBox hbox) {
this.hbox= hbox;
}
public HitBox getHBox() {
return this.hbox;
}
}
public class AngryLady extends Enemy{
public AngryLady() {
super(new HitBox(10, 20));
}
}
This example assume Enemy is not an abstract class.
I've DynamicObject, Player, Enemy classes
public class DynamicObject {
protected static float speed;
}
public class Player extends DynamicObject {
/*some code*/
Player.speed = 100;
}
public class Enemy extends DynamicObject {
/*some code*/
Enemy.speed = 50;
}
And always speed value is overridden. Of course I can create new speed variable in Player and Enemy, but then the existing DynamicObject class is pointless. I want to have different speed values on each class. All objects of current class will have the same speed. How I should make it in correct way?
The speed variable should not be static. Otherwise it won't be bound to any of the instances of the DynamicObject class, nor any of it's subclasses instances.
If you want to have a different speed value for each of the subclasses, you can do:
public class DynamicObject {
protected float speed;
public DynamicObject(float speed) {
this.speed = speed;
}
public float getSpeed() {
return this.speed;
}
}
public class Player extends DynamicObject {
/*some code*/
public Player(float speed) {
super(speed);
}
}
public class Enemy extends DynamicObject {
/*some code*/
public Enemy(float speed) {
super(speed);
}
}
If every DynamicObject has a speed, and the speed is the same for every instance of, for example, Player, then you should have
public abstract int getSpeed();
in DynamicObject, and
#Override
public int getSpeed() {
return 100;
}
in Player.
If you need to have access to the constant speed returned for evry instance of Player without instantiateing a Player, just use
public static final int CONSTANT_PLAYER_SPEED = 100;
#Override
public int getSpeed() {
return 100;
}
and use Player.CONSTANT_PLAYER_SPEED to access the speed of all players.
Remove the static from that variable, if a variable is static, it's belong to the class, not to instances.
And making a static variable protected doesn't make any scene, since, inheritance and static are totally different.
protected float speed;
You could also have an abstract method, which would mean that you would always have to override it in your sub classes.
public abstract class Dynamic {
protected float speed;
abstract void setSpeed();
}
public class Player extends Dynamic{
#Override
void setSpeed() {
this.speed=50;
}
}
I have a class called ContentStream... the problem is that the inner class AddRectancle suppose to get the info of the getter of the class GraphicBeginn...I thought the class ContentStream can reach the getter at least as the getter is public ... plse tell me how to
public class ContentStreamExt extends ContentStreamProcessor
{
private Matrix graphicalMatrix;
public ContentStreamProcessorExt(ExtListener extListener)
{
super(extListener);
}
private void enhanceAdditional()
{
GraphicBeginn beginnGraphic = new GraphicBeginn();
super.register("a", beginnGraphic);
super.register("b", new AddRectangle(beginnGraphic));
}
private static class AddRectangle(GrapicBeginn beginn)
{
// should get the info of uUx and uUy
}
private static class GraphicBeginn implements ContentOperator
{
private float uUx;
private float uUy;
public float getuUx()
{
return this.uUx;
}
public float getuUy()
{
return this.uUy;
}
..... // the input for uUx and uuy will be created in a method
}
The code you gave has a number of problems, it doesn't compile correctly as another poster has noted. It also appears you are providing a method signature while also declaring a class called "AddRectange". Is this a class or a method? You need to decide which, it can't be both. Here is an example that I think illustrates what you're trying to do in a general sense:
public class SampleClass {
public SampleClass() {
}
private void sampleClassMethod() {
A a = new A();
a.acceptB(new B());
}
private class A {
public void acceptB(B bObject) {
System.out.println(bObject.memberVar1);
}
}
private class B {
private int memberVar1 = 5;
}
}
If i understand your question correctly, The add rectangle class should be passed an instance of graphic begin on which it can invoke the public getters. This wiring can be done by the content stream class.
By the way the following is syntactically invalid
private static class AddRectangle(GrapicBeginn beginn)