【问题标题】:KineticJS get shape object under the mouse positionKineticJS 获取鼠标位置下的形状对象
【发布时间】:2013-08-27 18:05:23
【问题描述】:

我正在尝试使用 KineticJS 编写一个小游戏。光标是瞄准具,我想用一些键盘键作为触发器来发射不同的“子弹”以获得不同的效果,但我没有找到使用 JS 事件的方法。

stage = new Kinetic.Stage
  container: 'container'
  width: window.innerWidth
  height: window.innerHeight

shape_layer = new Kinetic.Layer()

circle = new Kinetic.Circle
  x: stage.getWidth() / 2
  y: stage.getHeight() / 2
  radius: 100
  fill: 'red'
  stroke: 'white'
  strokeWidth: 20

circle.on 'click', (e) ->
  console.log 'You get one point!'

shape_layer.add circle
stage.add shape_layer

$(document).on 'keydown', (e) ->
  if e.keyCode == 90
    mouse_p = stage.getMousePosition()
    x = mouse_p.x
    y = mouse_p.y
    evt = document.createEvent 'MouseEvents'
    evt.initMouseEvent 'mouseup'
    , true
    , true
    , window
    , null
    , 0
    , 0
    , x
    , y
    shape_layer.fire 'click', evt, true

事件实际上是被触发的,但它是在图层上,而不是在圆圈上。所以我开始思考是否可以使用鼠标位置获取形状并直接在其上触发点击事件?

【问题讨论】:

    标签: javascript events webgl kineticjs


    【解决方案1】:

    为什么不通过 KineticJS 处理鼠标事件呢?

    layer.on('click', function(evt) {
      // get the shape that was clicked on
      var shape = evt.targetNode;
      alert('you clicked on \"' + shape.getName() + '\"');
    });
    

    事件委托:http://www.html5canvastutorials.com/kineticjs/html5-canvas-get-event-shape-with-kineticjs/

    事件:http://www.html5canvastutorials.com/kineticjs/html5-canvas-path-mouseover/

    更新:

    我误解了你的问题,所以我很抱歉。

    您希望在按下某个键(keydown 事件)时访问 targetNode。以下是我的做法:

    首先你需要设置一个透明矩形背景和舞台的宽度和高度,以便图层可以检测到鼠标事件(在这种情况下我们需要mousemove)。

        var bg = new Kinetic.Rect({
            x: 0,
            y: 0,
            width: stage.getWidth(),
            height: stage.getHeight(),
            id: 'bg'
        });
    

    然后,每当鼠标在舞台内移动但不在目标上时,我都会设置一个空的Kinetic.Shape。因此,target 始终等于empty,除非鼠标悬停在我们的透明背景之外的节点上。 scoreText 只是在舞台上打印你的分数。

        var empty = new Kinetic.Shape({
            id: 'empty'
        });
        var target = empty;
        var score = 0;
    
        var scoreText = new Kinetic.Text({
            text: 'Score: '+score,
            x: 10,
            y: 10,
            fill: '#000',
            fontSize: 20,
            id: 'score'
        });
    

    在 KineticJS 中使用 mousemove 事件:

        layer.on('mousemove', function (e) {
            var mousePos = stage.getMousePosition();
            var x = mousePos.x;
            var y = mousePos.y;
            var node = e.targetNode;
            var nodeID = node.getId();
            if (nodeID !== 'bg') {
                target = node;
            } else {
                target = empty;
            }
        });
    

    然后使用 jQuery keydown 事件:

        $(document).keydown(function(e) {
            if (e.keyCode == 90) {
                var id = target.getId();
                if (id == 'empty' || id == 'score') {
                    alert('MISS');
                } else {
                    var targetID = target.getId();
                    var targetName = target.getName();
                    alert('ID: ' + targetID + ' NAME: ' + targetName + ' You get one point!');
                    target.destroy();
                    target = empty;
                    score++;
                    updateScore(scoreText, score);
                    randomCircle();
                }
            }
        });
    

    最后,为了制作游戏……randomCircle()updateScore() 函数:

        function updateScore(text, score) {
            text.setText('Score: ' + score);
            //layer.draw(); //normally we would have to layer.draw() here, but I called it in randomCircle() instead to save the amount of draw() calls necessary
        }
    
        function randomCircle() {
            var circle = new Kinetic.Circle({
                x: Math.floor((Math.random() * 578)),
                y: Math.floor((Math.random() * 200)),
                radius: 70,
                fill: 'red',
                stroke: 'black',
                strokeWidth: 4,
                id: 'someTarget',
                name: 'targets'
            });
            layer.add(circle);
            layer.draw();
        }
    

    jsfiddle(不要忘记点击 javascript 窗格才能使用 keydown 事件!)

    【讨论】:

    • 是的,图层现在响应。但似乎 KineticJS 引擎没有捕捉到这个事件并添加了 targetNode 属性。
    • 它应该可以工作,就像教程中的示例一样。您还在文档上使用 keydown 功能吗?如果是这样,我建议删除它并在 KineticJS 中移动函数
    • 不清楚您的建议。我的意图是在 KineticJS 之外手动并主动触发一个事件,因此应该有一个 keydown 函数,并从头开始编写一个鼠标事件。本教程没有做同样的事情。它只是监听图层上的点击事件,并等待用户点击。
    • 对不起,我看错了你的问题。更新了我上面的答案 + jsfiddle。让我知道这是否解决了您的问题或您有任何疑问。
    猜你喜欢
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    • 2014-06-23
    • 2012-07-06
    • 2012-10-02
    • 2013-03-31
    • 2018-10-04
    • 1970-01-01
    相关资源
    最近更新 更多