Tappable Game Objects

61 views
Skip to first unread message

vecima

unread,
Mar 16, 2014, 2:37:32 PM3/16/14
to replica-island-...@googlegroups.com
Hello everyone.  I needed to make GameObjects "tappable" (that is, tapping on their location on the screen causes some action).
I didn't see anything immediately available in the RI codebase, so I made this simple component.  It works by taking the parent object, converting it's world coordinates into screen space coordinates, and looking for a "touch" in that region.

TappableComponent.java:

/**
 * Provides an interface for tapping a GameObject on the screen. Tapping the
 * object will register a "true" value on the provided channel.
 */
public class TappableComponent extends GameComponent
{
    private ChannelSystem.Channel mChannel;
    private ChannelSystem.ChannelBooleanValue mChannelValue;

    public TappableComponent()
    {
            super();
            this.setPhase(ComponentPhases.THINK.ordinal());
            this.mChannelValue = new ChannelSystem.ChannelBooleanValue();
    }

    @Override
    public void reset()
    {
            this.mChannel = null;
            this.mChannelValue.value = false;
    }

    @Override
    public void update(float timeDelta, BaseObject parent)
    {
            InputSystem inputSystem = sSystemRegistry.inputSystem;
            final CameraSystem camera = sSystemRegistry.cameraSystem;
            ContextParameters context = sSystemRegistry.contextParameters;
            float cameraOriginX = 0.0f;
            float cameraOriginY = 0.0f;
            if (camera != null)
            {
                    camera.getFocusPositionX();
                    cameraOriginX = camera.getFocusPositionX() - (context.gameWidth / 2.0f);
                    cameraOriginY = camera.getFocusPositionY() - (context.gameHeight / 2.0f);
            }
            final InputTouchScreen inputTouchScreen = inputSystem.getTouchScreen();
            GameObject parentObject = (GameObject) parent;
            float parentCameraXOffset =  parentObject.getPosition().x - cameraOriginX;
            float parentCameraYOffset =  parentObject.getPosition().y - cameraOriginY;
             final InputXY inputXY =  inputTouchScreen.findPointerInRegion(parentCameraXOffset,  parentCameraYOffset, parentObject.width, parentObject.height);
            if (inputXY != null)
            {
                    this.mChannelValue.value = true;
            }
            else
            {
                    this.mChannelValue.value = false;
            }
            if (this.mChannel != null)
            {
                    this.mChannel.value = mChannelValue;
            }
    }

    public void setChannel(ChannelSystem.Channel channel)
    {
            this.mChannel = channel;
    }
}

To use the component just allocate a TappableComponent (be sure to set it up with a pool), register a channel with the ChannelSystem and set it via the setChannel method.  When the GameObject is tapped, the channel you registered will have the value "true" on it.  when you release, the value "false" will be on the channel.  You can have another component define what behavior to execute when the object is tapped, by simply having that component set up to read from the same channel.  You could also change the "boolean" behavior of the component to set the "last touched time" if you wanted to.

I've gotten so much help on this group that I wanted to share something, so I hope this helps somebody!
Feel free to comment with improvements to this design ;)

Leo Cedric

unread,
Jun 25, 2014, 10:33:03 AM6/25/14
to replica-island-...@googlegroups.com
HI vecima ,

Thank you for sharing, your component, iam looking forward to test and hopefully adapt it...

i came accross your post , while looking at how to "handle double tap" on the screen "dpad" of RI.

can you please shade some light there ?

regards

vecima

unread,
Jun 26, 2014, 11:38:24 PM6/26/14
to replica-island-...@googlegroups.com
Hi Leo Cedric,

I'm glad my contribution can be of help.
I haven't implemented double tap myself, but I'd imagine you could do it by keepting track of time tapped on a channel and if tapped again while the time has not run out, activate the double tap logic.

hopefully I'm explaining that well enough.


--
You received this message because you are subscribed to the Google Groups "ReplicaIsland Coding Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to replica-island-coding...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Leo Cedric

unread,
Jul 2, 2014, 5:29:40 AM7/2/14
to replica-island-...@googlegroups.com
Hi Vecima
found a solution.
it will allow the player to react to a "double tap" on the "dpad" (onscreen directional pad button)

>> on PlayerComponent.java , i have added a few fields and modify the "move" method so that it looks like this

public class PlayerComponent extends GameComponent {
    .....
    .....

    private float mInitialDownTime = 0.0f ; //
    private boolean mInitialDownFlag = true ;
    private boolean mLockPress = false ;

    ....
    ....

   protected void move(float time, float timeDelta, GameObject parentObject) {
       VectorPool pool = sSystemRegistry.vectorPool;
        InputGameInterface input = sSystemRegistry.inputGameInterface;
        .....
        .....
        final InputXY dpad = input.getDirectionalPad();
        final InputButton jumpButton = input.getJumpButton()

                 if(dpad.getPressed()){ // initial down
                    if(!mLockPress){
                       mInitialDownTime = time ;
                       mInitialDownFlag = true ;
                    } 
                 }else{
               
                    if(mInitialDownFlag){
                    mLockPress = true ;
                }
            }


            if(mLockPress){ // we only have 0.5s to execute the double tap
                if(time > mInitialDownTime + 0.1f && time < mInitialDownTime + 0.6f ){
                    if(dpad.getPressed()){

                        // Handle double tap here !!!
                    }
            }
               
               
             if(time > mInitialDownTime + 1 ){ // unlock one second later after lock
                    mLockPress = false ;
             }
          .....
          .....
          ......
               
        }
    

regards
To unsubscribe from this group and stop receiving emails from it, send an email to replica-island-coding-community+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages