HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Ball Entity for a Entity/Component/System Soccer Game

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
soccerballsystemgameforcomponententity

Problem

Here is a code snippet of a class that I be interested to refactor. I was in doubt on how to proceed with the process of instantiation. The original ask was here. After think about it and heard some opinions I end up refactoring and splitting the instantiation in several constructors, one public and all others private. what do you think of this approach?

I take this opportunity to ask you to evaluate other aspects of the code.

```
public class BallEntity extends UserEntity {
public static final float SCALE_FACTOR = 0.78f;
public static final String BALL = "ball";
private Body ballBody;
private Camera camera;
private Sprite ball;
private Fixture ballFixture;

public BallEntity(TextureAtlas atlas, RubeSceneHelper rubeSceneHelper, Camera camera) {
this(ScaledSprite.createUsingHeight(new Sprite(atlas.findRegion(BALL)), SCALE_FACTOR), rubeSceneHelper);
this.camera = camera;
}

private BallEntity(ScaledSprite scaledSprite, RubeSceneHelper rubeSceneHelper) {
this(scaledSprite.getSprite(), rubeSceneHelper.getBody(BALL), rubeSceneHelper);
}

private BallEntity(Sprite sprite, Body ballBody, RubeSceneHelper rubeSceneHelper) {
this(rubeSceneHelper.getFixture(ballBody, BALL));
this.ball = sprite;
this.ballBody = ballBody;
}

private BallEntity(Fixture ballFixture) {
this.ballFixture = ballFixture;
}

@Override
public Array getComponents() {
Array components = new Array();
components.add(PositionComponent.newInstance());
components.add(CameraFollowerComponent.newInstance(camera));
components.add(SpriteComponent.newInstance(ball));
components.add(BodyComponent.newInstance(ballBody));
components.add(BallContextComponent.newInstance());
return components;
}

@Override
public void init(Entity entity) {
BodyComponent bodyComponent = entity.getComponent(BodyComponent.class);
bodyCom

Solution

Looking at the class from the outside, this is how it gets created:

public BallEntity(TextureAtlas atlas, RubeSceneHelper rubeSceneHelper, Camera camera)


How the class actually gets created requires jumping between a sequence of private constructors... that isn't needed at all.

public BallEntity(TextureAtlas atlas, RubeSceneHelper rubeSceneHelper, Camera camera) {
    this.camera = camera;
    this.ballFixture = rubeSceneHelper.getFixture(ballBody, "ball");

    Sprite sprite = new Sprite(atlas.findRegion(BALL))
    this.ball = ScaledSprite.createUsingHeight(sprite, SCALE_FACTOR).getSprite();
    this.ballBody = rubeSceneHelper.getBody("ball");
}


Here I've introduced an intermediate Sprite object variable, only because all those chained calls wouldn't look right.

Isn't it easier to follow? :)

This seems pretty verbose:

public Array getComponents() {
    Array components = new Array();
    components.add(PositionComponent.newInstance());
    components.add(CameraFollowerComponent.newInstance(camera));
    components.add(SpriteComponent.newInstance(ball));
    components.add(BodyComponent.newInstance(ballBody));
    components.add(BallContextComponent.newInstance());
    return components;
}


I'm more into C#, but I'm pretty sure (make it 51%) you could do this instead (assuming Array is intended to work like a T[]):

public Component[] getComponents() {
    return new Component[] {
        PositionComponent.newInstance(),
        CameraFollowerComponent.newInstance(camera),
        SpriteComponent.newInstance(ball),
        BodyComponent.newInstance(ballBody),
        BallContextComponent.newInstance()
    };
}

Code Snippets

public BallEntity(TextureAtlas atlas, RubeSceneHelper rubeSceneHelper, Camera camera)
public BallEntity(TextureAtlas atlas, RubeSceneHelper rubeSceneHelper, Camera camera) {
    this.camera = camera;
    this.ballFixture = rubeSceneHelper.getFixture(ballBody, "ball");

    Sprite sprite = new Sprite(atlas.findRegion(BALL))
    this.ball = ScaledSprite.createUsingHeight(sprite, SCALE_FACTOR).getSprite();
    this.ballBody = rubeSceneHelper.getBody("ball");
}
public Array<Component> getComponents() {
    Array<Component> components = new Array<Component>();
    components.add(PositionComponent.newInstance());
    components.add(CameraFollowerComponent.newInstance(camera));
    components.add(SpriteComponent.newInstance(ball));
    components.add(BodyComponent.newInstance(ballBody));
    components.add(BallContextComponent.newInstance());
    return components;
}
public Component[] getComponents() {
    return new Component[] {
        PositionComponent.newInstance(),
        CameraFollowerComponent.newInstance(camera),
        SpriteComponent.newInstance(ball),
        BodyComponent.newInstance(ballBody),
        BallContextComponent.newInstance()
    };
}

Context

StackExchange Code Review Q#94589, answer score: 4

Revisions (0)

No revisions yet.