Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm experimenting with Scene2D to see if it fits fot the game I want to develop. Say I have an Actor with the origin in the center of its TextureRegion.

My setup method contains this code:

float width = WorldUtils.pixelsToMeters(Assets.bullet.getRegionWidth());
float height = WorldUtils.pixelsToMeters(Assets.bullet.getRegionHeight());

setPosition(x, y);
setOrigin(width / 2, height / 2);
setSize(width, height);
setRotation(angle);

Where WorldUtils.pixelsToMeters(float) is just a method to convert pixels to world units (basically 64px = 1 meter).

My draw() method is like this:

@Override
public void draw(SpriteBatch batch, float parentAlpha) {
    batch.setColor(getColor().r, getColor().g, getColor().b, getColor().a);
    batch.draw(Assets.bullet, getX()-getOriginX(), getY()-getOriginY(), getOriginX(), getOriginY(),
               getWidth(), getHeight(), 1, 1, getRotation());
}

This way the actor's position is equal to its center position. This simplifies a lot of stuff like moving the actor to a specific (x, y) in the game world. Otherwise everytime I have to use this actor's position I have to take in account for its screen representation's size... and it doesn't make much sense.

But the way I setup things come at the cost of messing up with event handling. From what I understand Scene2D event handling assumes I'm using (0, 0) as origin of the actor's bounding box. So when I touch/click on my actor during execution it can handle only the ones slightly up-right it real position (obviously).

Is there a way to fix this without touching the library code? I would like to handle certain objects with origin in the center and others with origin in the bottom-left corner.

Maybe I misunderstood how to setup my actor?

share|improve this question
add comment

1 Answer 1

up vote 0 down vote accepted

Answering my own question:

Looking at Actor's code, it seems to be as simple as overriding the default hit() method.

The original code is:

public Actor hit (float x, float y, boolean touchable) {
    if (touchable && this.touchable != Touchable.enabled) return null;
    return x >= 0 && x < width && y >= 0 && y < height ? this : null;
}

While my new code is:

public class NewActor extends Actor {
    @Override
    public Actor hit(float x, float y, boolean touchable) {
        if (touchable && getTouchable() != Touchable.enabled) return null;
        return x >= -getOriginX() && x < (getWidth() - getOriginX())
                && y >= -getOriginY() && y < (getHeight() - getOriginY()) ? this : null;
    }
}

It's worth mentioning that hit()'s x and y are relative to the Actor position, so I just translate the original bounds check by (-getOriginX(), -getOriginY()).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.