3

I have a HTML5 canvas game that I have written using Craftyjs. I have keyboard interaction working fine using the arrow keys but I'm having problems adding mouse interaction. The sprite does move slightly with the mouse, but not the same way as it does with the arrow keys and when it hits another component it seems to crash. I added a function in to the component to deal with mouse interaction which is not working so it is commented out. Here is the code for my sprite component;

// This is the Angel Character
Crafty.c('Angel', {
    init: function() {
        this.requires('Actor, Fourway, Mouse, Collision, player_sprite, SpriteAnimation')
        .fourway(2)
        .stopOnSolids()
        // This deals with destroying the sins on collision.
        .onHit('Lust', this.killSin)
        .onHit('Greed', this.killSin)
        .onHit('Sloth', this.killSin)
        .onHit('Wrath', this.killSin)
        .onHit('Glutton', this.killSin)
        .onHit('Envy', this.killSin)
        .onHit('Pride', this.killSin)

        // This defines the animations.
        .animate('AngelUp', 0, 0, 2)
        .animate('AngelLeft', 0, 1, 2)
        .animate('AngelRight', 0, 2, 2)
        .animate('AngelDown', 0, 3, 2);

    // This deals with keyboard interaction.
    var animation_speed = 4;
    this.bind('NewDirection', function(data) {
        if (data.x > 0 || data.realX > this._x) {
            this.animate('AngelRight', animation_speed, -1);
        } else if (data.x < 0) {
            this.animate('AngelLeft', animation_speed, -1);
        } else if (data.y > 0) {
            this.animate('AngelDown', animation_speed, -1);
        } else if (data.y < 0) {
            this.animate('AngelUp', animation_speed, -1);
        } else {
            this.stop();
        }
    });

    // This deals with mouse interaction. 
    /*this.bind('NewDirection', function(data) {
        if (data.x > this.x) {
            this.animate('AngelRight', animation_speed, -1);
        } else if (data.x < this.x) {
            this.animate('AngelLeft', animation_speed, -1);
        } else if (data.y > this.y) {
            this.animate('AngelDown', animation_speed, -1);
        } else if (data.y < this.y) {
            this.animate('AngelUp', animation_speed, -1);
        } else {
            this.stop();
        }
    });*/
},

// Registers a stop-movement function to be called when
//  this entity hits an entity with the "Solid" component
stopOnSolids: function() {
    this.onHit('Solid', this.stopMovement);

    return this;
},

// Stops the movement
stopMovement: function() {
    this._speed = 0;
    if (this._movement) {
        this.x -= this._movement.x;
        this.y -= this._movement.y;
    }
},

// Deals with the angel finding a sin.
killSin: function(data) {
    sin = data[0].obj;
    Crafty("Score").each(function () { 
            this.text("Score: " + ++score),
            this.text("Score: " + ++score),
            this.text("Score: " + ++score),
            this.text("Score: " + ++score),
            this.text("Score: " + ++score),
            this.text("Score: " + ++score),
            this.text("Score: " + ++score),
            this.text("Score: " + ++score),
            this.text("Score: " + ++score),
            this.text("Score: " + ++score) });
    Crafty.audio.play('kill');
    sin.kill();
}
});

Here is the code for where the angel is instantiated in the scene. I added a bind function to it to try and make the mouse interaction work but that doesn't work properly.

// This places the angel on the grid.
this.player = Crafty.e('2D, Canvas, Angel, Mouse')
                .at(5, 5)
                .bind('MouseMove', function(e) {
                this.x = e.offsetX || e.layerX;
                this.y = e.offsetY || e.layerY;
                })

Here is a link to the game;

http://users.aber.ac.uk/rig6/achievement_unlocked/index.html

I have tried everything and can't find an example online that helps with this. Please can someone help?

Rich Gray
  • 191
  • 2
  • 11

3 Answers3

3

They best way I have found to bind to mouse/touch using Crafty is to create a Canvas-wide element and then bind to that. Create a Canvas-wide entity that accepts mouse and touch events. Note that Crafty routes mouse and touch through the same logic. This example is binding to move/hover.

Crafty.e("mouseTracking, 2D, Mouse, Touch, Canvas")
          .attr({ w:320, h:480, x:0, y:0 })
          .bind("MouseMove", function(e) 
          {
                console.log("MouseDown:"+ Crafty.mousePos.x +", "+ Crafty.mousePos.y);
                var hero = = Crafty("hero"); //get hero
                hero.x = Crafty.mousePos.x;
                hero.y = Crafty.mousePos.y;

            });                 

Now, entity "hero" will follow the mouse hover and finger touches around the screen. You probably want to bind to "MouseDown" instead and process some logic.

Dan
  • 1,112
  • 11
  • 14
1

You should use the addEvent method to bind callbacks to mouse events on Crafty.stage.elem element.

Crafty.addEvent(this, Crafty.stage.elem, 'mousedown', function(e) {
  console.log('mousedown at (' + e.clientX + ', ' + e.clientY + ')');
});

Crafty.addEvent(this, Crafty.stage.elem, 'mousemove', function(e) {
  var relative = Crafty.DOM.translate(e.clientX, e.clientY);
  console.log('mousemove at (' + relative.x + ', ' + relative.y + ')');
  this.player.x = relative.x;
  this.player.y = relative.y;
}.bind(this));

This method is used internally by the Mouse component, see https://github.com/craftyjs/Crafty/blob/develop/src/controls.js#L324-329

See also https://groups.google.com/d/msg/craftyjs/6IBnhVe_NIE/hK3vPXP9TxsJ

Giovanni Cappellotto
  • 4,597
  • 1
  • 30
  • 33
1

To build on what Dan says here is a example that works well on mobile and my touch screen laptop

<html>
  <head></head>
  <body>
    <div id="game"></div>
    <script type="text/javascript" src="lib/crafty.js"></script>
    <script>
      // When the DOM has loaded

        // Height and Width
        var WIDTH = 500, HEIGHT = 320;
        // Initialize Crafty
        Crafty.init(WIDTH, HEIGHT);
        // Background
        Crafty.background("black");

        Crafty.e("mouseTracking, 2D, Mouse, Touch, Canvas")
          .attr({ w:500, h:320, x:0, y:0 })
          .bind("MouseMove", function(e) 
          {
                console.log("MouseDown:"+ Crafty.mousePos.x +", "+ Crafty.mousePos.y);
                // when you touch on the canvas redraw the player
                player.x = Crafty.mousePos.x;
                player.y = Crafty.mousePos.y;

            });  

        // Create a player entity
        var player = Crafty.e();
        // Add some components to the entity
        player.addComponent("2D, DOM");
        //set where your player starts
        player.attr({
         x : 10,
         y : 10,
         w : 50,
         h : 50
         });

        player.addComponent("Color").color("red");
        //add mouse component for mouse events
    </script>
  </body>
</html>
Robi Sen
  • 162
  • 1
  • 8