Showing posts with label touch. Show all posts
Showing posts with label touch. Show all posts

Monday, January 18, 2016

A Phaser Game With Mouse/Touch Input

I'm back from Texas and have mostly recovered from the events of last week. I still have a bit of a cold, but I'm not letting it stop me from getting a simple game ready for inclusion in a comic this week. This game will use mouse/touch input instead of the keyboard like my last one did, so I had to figure out how to use sprite dragging in Phaser.


Like most things have been with Phaser so far, it took a few tries to get it all correct but in the end it all seems really simple. It revolves around enabling input on individual Sprites, enabling drag, and then optionally listening for drag-related events.

Here is the complete source code for a Sprite-dragging demo:

var init = function() {

    var game = new Phaser.Game(width, height, Phaser.CANVAS, "gameArea", {
        preload : preload,
        create : create
    });

    function selectFrog(sprite, pointer) {
        console.log("selected");
        sprite.frame = 1; // frog in the air
    }

    function releaseFrog(sprite, pointer) {
        console.log("released");
        sprite.frame = 0; // frog sitting
    }

    function preload() {
        this.load.spritesheet('frog', 'assets/sprites/frog.png', 79, 60);
    }

    function create() {

        this.stage.backgroundColor = "#999999";

        var frog = this.add.sprite(50, 50, "frog", 0);
        frog.inputEnabled = true;
        frog.input.enableDrag(true);
        frog.events.onDragStart.add(selectFrog, this);
        frog.events.onDragStop.add(releaseFrog, this);

    }

};

window.onload = function() {
    init();
};

The selectFrog and releaseFrog functions are the event handlers for the drag start and drag stop events. In this example, all they do is log something to the console and change the frame of the sprite. In my upcoming game, I do more in here such as tween animations and game logic.

When I make the frog sprite in the create function of my example, setting inputEnabled to true is the first step. Without this, you can't do anything with input to the individual sprite. Once that is done, you can set the specific input behaviors. The very next line, frog.input.enableDrag(true), turns on drag-ability. The single parameter passed to the function sets whether or not the Sprite should re-center itself to the cursor upon being drug. I passed true, which will cause the center of the sprite to jump to the position of the cursor when the drag starts. If this isn't what you want, you can also say false and drag from any part of the sprite - not just center.

When dragging is enabled, the sprite will fire off events for drags starting and stopping. I added the selectFrog and releaseFrog functions as event handlers using the onDragStart and onDragStop fields of the sprite's events field. Note the parameters that get passed to these event handlers when they fire. The first is the sprite object that was the subject of the drag and the second is the Pointer object. There's lots of information on the Pointer object about the state of the pointer if you want any of that to matter in your game.

If you've tried the code above and are using a mouse, you might be disappointed that the cursor changes to that text-select I-beam cursor thing while you drag the frog. If you'd like it to stay as the default cursor while you drag, no problem! You can simply override the cursor style in the create function. Just add this line:

this.game.canvas.style.cursor = "default";

Now the cursor will always be the default pointer regardless of what you are clicking or dragging in the game. If you'd like the cursor to turn into the click-here hand whenever it's over the frog (dragging or not), there's also the useHandCursor field on the input object. If you add this line to the create function instead...

frog.input.useHandCursor = true;

...it will turn the cursor into the hand when you mouse-over the frog. I didn't care for that personally, but it might be useful in certain situations.

Now that you've read all this, you probably want to see this sprite-dragging in action. Sorry, but the game I was making is not actually in today's comic. You have to wait until later in the week. Click the image or link below for today's comic.

Amphibian.com comic for 18 January 2016

Friday, August 21, 2015

Using Touch with Phaser

My goal for Amphibian.com was to develop it as a mobile-first webcomic. That's why it reads vertically and uses SVGs for graphics that stretch and shrink to any size. A year's worth of client browser stats, however, informs me that mobile users are still in the minority on the site. Nonetheless, I still want to make sure everything on there works on phones and tablets.

That includes my 404-page frog soccer game.

Up until now, I've been developing it as a way to learn how to use Phaser for game development and have been focused on the basics. It was more common to take input from the keyboard in the examples so that's all I've been doing. But today I found it was very easy to add touch controls - at least in my game.

There are two places where the keyboard is used in my game.
  1. Hit the space bar to start playing
  2. The arrow keys move the frog
Starting the game with either the spacebar or a tap (or mouse click) was simple:

function update() {

    // ... other update stuff ...

    if (mode === WAIT_MODE && (spacebar.isDown || game.input.activePointer.isDown)) {
        mode = PLAY_MODE;
    }

    // ... other update stuff ...

}

In Phaser, game.input.activePointer normalizes input from the touchscreen and the mouse, and its isDown property is an easy way to check if any button has been clicked or the screen has been touched in any way. If you wanted to get more specific with mouse input, there are other properties that represent the individual buttons. With touch input, you have the option of reading location data from multiple pointers as a way of supporting multitouch, but none of that was necessary for my game. I just want to know that you've touched or clicked to start the play.

The other type of input, from the arrow keys, seemed like it might be more difficult to reproduce with touch input. Not at all! I was impressed with how simple it was to direct the frog based on touching the screen.

function update() {

    // ... other update stuff ...

    if (mode === PLAY_MODE) {

        if (game.input.activePointer.isDown) {
            game.physics.arcade.moveToPointer(frog, 180);
        }

    }

    // ... other update stuff ...

}

Basically, the code above just checks to see if the user is touching the screen or holding down a mouse button. If they are, the frog is directed towards wherever the pointer is located. For mouse input, that's the cursor location. For touch input, it's the location of your finger. Couldn't be easier!

With just these few lines of code I was able to touch-enable my game. I'm still struggling with the canvas size and page navigation on mobile, but it is playable. Give it a try: http://amphibian.com/404/. Don't forget that you can see the complete source code on GitHub!

After playing a few rounds, make sure you read today's comic as well.