Мультитач в javascript (2d игра) - PullRequest
0 голосов
/ 28 февраля 2019

Я создаю простую 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>
...