首页 文章

在Javascript中的touchmove上移动画布对象

提问于
浏览
0

我是Web开发的新手,我只使用jQuery编写脚本 . 然而今天,我想提高我的技能,并构建一个可以在智能手机上用作香草JS的网络应用程序的小游戏 .

游戏非常简单:你将手机置于纵向模式并控制一个停留在屏幕底部的角色,并且必须躲避落在他身上的物体 . 角色只能向左或向右移动,因此始终保持在同一个x轴上 . 为了控制他,你的手指必须留在屏幕上 . 一旦你脱掉它,你就输了 . 此外,点击屏幕不会触发移动,而是向左或向右移动手指 .

就目前而言,我只是在尝试 grab touchevents,并且能够在滑动时让角色移动:

document.addEventListener('touchmove',function(e){
e.preventDefault(); //disable scroll

var board = document.getElementById(‘board);
var character = document.getElementById(‘character’);

if (e.targetTouches.length === 1) {
    var touch = e.targetTouches[0];
    board.classList.add(‘moving’);

    character.style.left = touch.pageX + 'px';
}

}, false);

('moving'类用于移动棋盘的背景位置,并在纯CSS中为角色的精灵设置动画 . )

另外,我制作了一个小脚本,将具有随机类的对象放在具有设置间隔的容器中 . 然后,这些对象在css中生成动画,并从屏幕的顶部到底部落下 .

现在,这里有一个棘手的部分:碰撞检测 . 正如我所说的,我是开发人员和vanilla JS的新手,所以我搜索了一下以找出如何检测两个对象何时发生碰撞,而且似乎大多数教程使用画布来做这件事 . 问题是,我从来没有使用它们,他们吓到我了很多 . 更重要的是,我认为这将使我迄今为止所做的事情毫无用处 .

我可以尝试使用画布方式,但在此之前,我想知道是否还有其他方法可以检测两个移动物体是否发生碰撞?

另外,如果在没有画布的情况下没有真正的方法可以做到这一点,我打算使用this tutorial来学习如何构建应用程序 . 然而,这款游戏并非专为触摸屏设备而设计,而且太空船的位置会在某些击键时发生变化(左右):

function update() {
  if (keydown.left) {
    player.x -= 5;
   }

  if (keydown.right) {
    player.x += 5;
  }

  player.x = player.x.clamp(0, CANVAS_WIDTH - player.width);
}

我的问题是:如何使用touchmove而不是按键更新位置?

谢谢大家 .

1 回答

  • 2

    1)想法:'if you stop touching, you loose',只是一个坏主意,放弃它 .
    2)最方便的控制方法是处理任何触摸事件(触摸开始/移动/结束/取消),并使字符在此事件的x坐标上对齐 .
    3)交叉测试只是一个基本的边界框交叉检查 .

    我在这里做了一个非常基本的演示,它使用触摸,还有鼠标来简化测试:

    http://jsbin.com/depo/1/edit?js,output

    这里可以进行大量的优化,但是你会看到触摸调整了船的位置,并且检测到了碰撞,因此它有望引导您找到自己的解决方案

    编辑:我为左侧,顶部添加默认值为0,以防它们未设置 .

    样板代码:

    var collisionDisplay = document.getElementById('collisionDisplay');
    
    // hero ship
    var ship = document.getElementById('ship');
    ship.onload = launchWhenReady ;
    
    //  bad ship
    var shipBad = document.getElementById('shipBad');
    shipBad.onload = launchWhenReady ;
    
    // image loader
    imagesCount = 2 ;
    
    function launchWhenReady() {
      imagesCount --;
      if (imagesCount) return;
      setInterval(animate, 20);
    }
    
    var shipBadY = 0;
    

    触摸事件:

    // listen any touch event
    document.addEventListener('touchstart', handleTouchEvent, true);
    document.addEventListener('touchmove', handleTouchEvent, true);
    document.addEventListener('touchend', handleTouchEvent, true);
    document.addEventListener('touchcancel', handleTouchEvent, true);
    
    // will adjust ship's x to latest touch
    function handleTouchEvent(e) {
        if (e.touches.length === 0 ) return;
        e.preventDefault();
        e.stopPropagation();
        var touch = e.touches[0];
        ship.style.left = (touch.pageX - ship.width / 2) + 'px';
    }
    

    动画 :

    // animation loop
    function animate()  {
        // move ship
        shipBadY += 1;
        shipBad.style.top = Math.ceil(shipBadY) + 'px';
        // test collision
        var isColliding = testCollide(shipBad);
        collisionDisplay.style.display = isColliding ? 'block' : 'none';
    }
    

    碰撞:

    // collision test when the enemy and the ship are images
    function testCollide(enemi) {
        var shipPosX = parseInt(ship.style.left) || 0 ;
        var shipPosY = parseInt(ship.style.top) || 0 ;
        var shipWidth = ship.width ;
        var shipHeight = ship.height;
        var badX = parseInt(enemi.style.left) || 0 ;
        var badY = parseInt(enemi.style.top) || 0 ;
        var badWidth = enemi.width;
        var badHeight = enemi.height;
        return bBoxIntersect(shipPosX, shipPosY, shipWidth, shipHeight,
        badX, badY, badWidth, badHeight);
    }
    

    编辑:如果你没有使用图像:

    // collision test when the enemy and the ship are ** NOT ** images
       function testCollide(o) {
        var characterPosX = parseInt(character.style.left);
        var characterPosY = parseInt(character.style.top);
        var characterWidth = parseInt(character.style.width);
        var characterHeight = parseInt(character.style.height);
    
        var obstacleX = parseInt(o.style.left) || 0 ;
        var obstacleY = parseInt(o.style.top) || 0 ;
        var obstacleWidth = parseInt(o.style.width);
        var obstacleHeight = parseInt(o.style.height);
    
        return boundingBoxIntersect(characterPosX, characterPosY, characterWidth, characterHeight, obstacleX, obstacleY, obstacleWidth, obstacleHeight);
    }
    function bBoxIntersect(x1, y1, w1, h1, x2, y2, w2, h2) {
        return !(x1 + w1 < x2 || x1 > x2 + w2 || y1 + h1 < y2 || y1 > y2 + w2);
    }
    

    鼠标事件:

    // -----------------------------------------------------
    // Handle mouse event for easy testing on Browser
    
    document.addEventListener('mousemove', handleMouseEvent);
    
    function handleMouseEvent(e) {
        ship.style.left = (e.pageX - ship.width / 2) + 'px';
    }
    

相关问题