我是Web开发的新手,我只使用jQuery编写脚本。然而今天,我想提高我的技能,并建立一个可以在智能手机上用作香草JS的网络应用程序的小游戏。
游戏非常简单: 您将手机置于纵向模式并控制一个位于屏幕底部的角色,并且必须躲避落在他身上的物体。角色只能向左或向右移动,因此始终保持在同一个x轴上。为了控制他,你的手指必须留在屏幕上。一旦你脱掉它,你就输了。此外,点击屏幕不会触发移动,而是向左或向右移动手指。
现在,我只是在尝试抓住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而不是按键来更新位置?
提前谢谢大家。
答案 0 :(得分:2)
我在这里做了一个非常基本的演示,它使用触摸,还有鼠标来简化测试:
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';
}