我正在创建一个简单的2d游戏,希望使用多点触控。
现在,游戏仅适用于单点触摸。可以在X轴上移动,也可以在用户用手指向上滑动时跳转。
问题是用户想同时移动和跳跃(向上滑动)。
有人可以指导我如何编写它来支持多点触控吗?(如果可能,我更喜欢纯JavaScript)
游戏控件大约在JS代码中间(很抱歉,没有可引用的行)。可以在我的评论中找到((新对象和滑动控件的控件)
/*********** UTILITIES ***********/
// Selector
function id(arg){
return document.getElementById(arg);
}
// Dirty error handling
function stoperror(){
return true;
} window.onerror = stoperror;
/*********** ONLOAD INITIALIZATION ***********/
window.onload = function(){
var canvas = id("canvas");
var c = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight-5;
/*********** GAME OBJECTS ***********/
function Obj(x, y, width, height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = "#354458";
// Jumping
this.jumping = false;
this.grounded = true;
// Active flag + orgin x, y and current x, y axis
this.active = false;
this.originX = 0;
this.currentX = 0;
this.originY = 0;
this.currentY = 0;
// HP BAR
this.score_color = "green";
this.score_width = 40;
this.score_height = 10;
// Jump method
this.jump = function(){
if(this.jumping === false){
this.jumping = true;
this.grounded = false;
this.y -= 80 * 0.9;
}
};
// Draw HEALTH BAR
this.score = function(){
c.beginPath();
c.rect(this.x, this.y - 13, this.score_width, this.score_height);
c.fillStyle = this.score_color;
c.fill();
};
// Draw object method
this.draw = function(){
c.beginPath();
c.rect(this.x, this.y, this.width, this.height);
c.fillStyle = this.color;
c.strokeStyle = "#000";
c.fill();
c.stroke();
};
// Update method - call draw with some basic logic
this.update = function(){
// Boundaries
if(this.x + this.width > canvas.width) this.x = canvas.width - this.width; // Right
if(this.x < 0) this.x = 0; // Left
if(this.y + this.height > canvas.height) this.y = canvas.height - this.height; // Bottom
if(this.y < 0) this.y = 0; // Top
// If jumping then not grounded
if(this.jumping === false) this.grounded = true;
if(this.jumping === true) this.grounded = false;
// If grounded on the bottom
if (this.y >= (canvas.height - this.height)){ // Bottom
this.y = (canvas.height - this.height);
// If grounded on the floor, jumping = false and grounded = true
this.jumping = false; this.grounded = true;
}
// If not grounded, gravity
if(this.grounded === false) this.y += 1.5;
// Prevent HP BAR being greater than player width
if(this.score_width >= 40) this.score_width = 40;
// Call draw method
this.draw();
// Call HP BAR method
this.score();
};
}
// Obstacles array
var _obstacles = [];
// Game colors
var gameColors = ["#5E412F", "#DA4624", "#6E9ECF", "#75EB00", "#FF85CB", "#FF432E", "#354458", "#542733", "#EB65A0", "#982395", "#260126", " #59323C", " #F2EEB3", "#8C6954", "#ED1C24", "#20457C", "#160A47", "#F05A28", "#3A0256", "#591E23", "#73503C", "#0C98CF", "#775BA3", "#493621", "#82683B", "#F76835", "#999900", "#000000", "#D75C37", "#CC0063"];
// Obstacle class
function Obstacle(x, width, height, speed){
this.x = x;
this.height = height;
this.y = canvas.height - this.height/2 - 1;
this.width = width;
//this.height = height;
this.speed = speed;
this.color = gameColors[Math.floor(Math.random() * gameColors.length)]; // Index random color
this.draw = function(){
c.beginPath();
c.strokeStyle = "black";
c.lineWidth = 0.5;
c.fillStyle = this.color;
c.rect(this.x, this.y, this.width, this.height);
c.fill();
c.stroke();
};
this.update = function(){
this.x -= this.speed;
this.draw();
};
}
/*-----------COLLISION DETECTION-----------*/
function collision(a,b){
return a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.y + a.height > b.y;
}
function collision2(a,b){
return mouse.x < b.x + b.width &&
mouse.x > b.x &&
mouse.y < b.y + b.height &&
mouse.y > b.y;
}
function collision3(a,b){
return touch.x < b.x + b.width &&
touch.x > b.x &&
touch.y < b.y + b.height &&
touch.y > b.y;
}
/*********** new OBJECT ***********/
var obj = new Obj(/*x = */canvas.width/2, /*y = */(canvas.height - 40 ), /*width = */40, /*height = */40);
var obj2 = new Obj(/*x = */canvas.width/2, /*y = */canvas.height/2, /*width = */42, /*height = */42);
// Draw Obstacle (called in game loop with currentTime and lastTime)
function drawObstacle(){
for (var _ = 0; _ < 1; _++){ //x, y, width, height, speed
var obst = new Obstacle(/*x = */canvas.width + 50, /*width = */ Math.floor((Math.random() * 20) + 8), /*height = */ Math.floor((Math.random() * 10) + 6), /*speed = */ Math.floor(Math.random() * 3.5) + 1);
_obstacles.push(obst);
}
}drawObstacle();
/*********** CONTROLS for new OBJECT ***********/
// Grab - on mousedown or touchstart set active = true
// And origin + current x, y values = e.clientX,Y values
function grab(e){
obj.active = true;
obj.originX = obj.currentX = e.clientX || e.touches[0].clientX;
obj.originY = obj.currentY = e.clientY || e.touches[0].clientY;
}
document.addEventListener("mousedown", grab);
document.addEventListener("touchstart", grab);
// Move - on mouse/touch move and only when active === true (already grabbed)
// Set current X, Y values to e.clientX, Y || e.touches[0].clientX, Y
function move(e){
if (obj.active){
obj.currentX = e.clientX || e.touches[0].clientX;
obj.currentY = e.clientY || e.touches[0].clientY;
}
}
document.addEventListener("mousemove", move);
document.addEventListener("touchmove", move);
// Release - on release set active to false and cancel
function release(e){
obj.active = false;
}
document.addEventListener("mouseup", release);
document.addEventListener("touchend", release);
/*********** PC CONTROLS ***********/
document.addEventListener("keydown", spaceJump, false);
function spaceJump(e){
if(e.keyCode == 32){
obj.jump();
}
}
/*********** SWIPE CONTROLS ***********/
// Listeners
document.addEventListener("touchstart", handleTouchStart, false);
document.addEventListener("touchmove", handleTouchMove, false);
// x and y values
var xDown = null, yDown = null;
// Get first touch
//function getTouches(evt) {
// return evt.touches || evt.originalEvent.touches;
//}
// Touch starts
function handleTouchStart(evt) {
//var firstTouch = getTouches(evt)[0];
xDown = evt.touches[0].clientX;
yDown = evt.touches[0].clientY;
}
// Handle touch move
function handleTouchMove(evt) {
if (!xDown || !yDown) {
return;
}
var xUp = evt.touches[0].clientX;
var yUp = evt.touches[0].clientY;
var xDiff = xDown - xUp;
var yDiff = yDown - yUp;
if (Math.abs(xDiff) > Math.abs(yDiff)) {
if (xDiff > 0) {
// Left
}
else {
// Right
}
}
else {
if (yDiff > 0) {
// Up = jump with my hero player
obj.jump();
}
else {
// Down
}
}
// Reset values
xDown = null; yDown = null;
}
document.addEventListener('touchmove', testTouch);
function testTouch(event){
for (var i = 0; i < event.targetTouches; i++) {
var touch = event.targetTouches[i];
console.log('touched ' + touch.identifier);
}
}
/*
___________________________________________________________________________________________________________________________________
*/
// Time handling
var lastTime = 0;
var lastTime2 = 0;
/*********** G A M E L O O P ***********/
function GAMELOOP(currentTime){
// Main animation
window.requestAnimationFrame(GAMELOOP);
// Begin
c.beginPath();
// Clear canvas
c.clearRect(0, 0, canvas.width, canvas.height);
/*********** UPDATE OBJECTS ***********/
// Update _player
obj.update();
//obj2.update();
// If active && NOT on the ground then slow movement speed
if (obj.active && !obj.grounded){
obj.x = obj.x - (obj.originX - obj.currentX) / (canvas.width/6);
//console.log(obj.grounded, movSpeed);
//obj.y = obj.y - (obj.originY - obj.currentY) / movSpeed;
}
// If active && on the ground then fast movement speed
if (obj.active && obj.grounded){
obj.x = obj.x - (obj.originX - obj.currentX) / (canvas.width/10);
//console.log(obj.grounded, movSpeed, canvas.width/10);
//obj.y = obj.y - (obj.originY - obj.currentY) / movSpeed;
}
// Collision test
if(collision(obj, obj2)){
//console.log(1);
}
// Obstacles update
for(var k = _obstacles.length - 1; k >= 0; k--){
_obstacles[k].update();
// If obstacle goes out of display, splice it
if(_obstacles[k].x + _obstacles[k].width < 0){
_obstacles.splice(k, 1);
}
}
// Draw obstacles every n secs
if(currentTime >= lastTime + 3000){
lastTime = currentTime;
drawObstacle();
}
// Collision between hero player and obstacles
for(var j = _obstacles.length - 1; j >= 0; j--){
if(collision(obj, _obstacles[j])){
// If collision - delete obstacle and decrease HP
_obstacles.splice(j, 1);
obj.score_width -= 10;
}
}
// If dead
if(obj.score_width <= 0){
// alert("You DED!");
obj.score_width = 40;
}
} // End of GAMELOOP function
// Run GAMELOOP in loop
// Main animation
GAMELOOP();
}; // End of onload function
body {
padding: 0;
margin: 0;
overflow: hidden;
}
.bg {
position: absolute;
left:0px;
bottom: 0px;
width: 100%;
height: 5px;
background: #8B4513;
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<canvas id="canvas"></canvas>
<div class="bg"></div>
</body>
</html>