2014-05-22 59 views
0

我正在使用EaselJS开发HTML5 Canvas游戏,并且在更改我的代码后发现了一个问题。触摸事件在这个变化之前就已经开始工作了,但它不再工作了,我不记得我已经改变了什么,但它与stagemousedown/stagemouseup事件无关。我只在iOS 7上测试过游戏。触摸事件无法使用EaselJS

有人可以帮助我吗?

正如我所说的,我不知道问题出在哪里然后我会在这里把整个代码,而不是相关的部分只有(> 400线)的。我强烈建议您看看[小提琴] [1]。

这里是我的代码:

function init() { 

    var objectsCollideAt = { 
     it: [], // If it is collideable, it'll be in this array. 
     top: [], 
     left: [], 
     right: [], 
     bottom: [] 
    }, 
    key = { 
     up: false, // W, arrow up or spacebar 
     left: false, // A or arrow left 
     right: false, // D or arrow right 
     down: false, // S or arrow down 
     holdingUp: false 
    }, 
    mouse = { 
     x: 0, 
     y: 0 
    }, 
    touch = { 
     tollerance: 50 // Object "margins" when using touch or mouse 
    }, 
    collisionSystem = { 
     /* This variable is responsible for deactivating the 
     * edge-to-edge collision detection forEach when a 
     * side-to-side collision happened, to get better 
     * performance. Can cause extremely rare bugs. 
     */ 
     //sideCollided: false // Commented because it was causing a critical bug. 
    }; 

    var stage = new createjs.Stage("canvas"); 

    createjs.Touch.enable(stage); 

    var Graphic = function (src, blockWidth, blockHeight) { 
     src = src.split(","); 
     return { 
      createBlockAt: function (x, y, blockGroupWidth, blockGroupHeight, clsdir, alpha) { 
       for (var blockY = 0; blockY < blockGroupHeight/blockHeight; blockY++) { 
        for (var blockX = 0; blockX < blockGroupWidth/blockWidth; blockX++) { 

         var obj = new createjs.Bitmap(src[Math.floor(Math.random() * src.length)]); 

         obj.width = blockWidth; 
         obj.height = blockHeight; 
         if (typeof alpha !== 'undefined') { 
          obj.alpha = alpha; // While debugging this can be used to check if a block was made over another block. 
         } 

         obj.x = Math.round(x + (blockWidth * blockX)); 
         obj.y = Math.round(y + (blockHeight * blockY)); 

         if (clsdir != "none") { 
          objectsCollideAt.it.push(obj); 
         } 
         if (typeof clsdir !== "undefined") { 
          clsdir.split(" "); 
          if (clsdir.indexOf("top") >= 0 && blockY == 0) { 
           objectsCollideAt.top.push(obj); 
          } 
          if (clsdir.indexOf("left") >= 0 && blockX == 0) { 
           objectsCollideAt.left.push(obj); 
          } 
          if (clsdir.indexOf("right") >= 0 && blockX == (blockGroupWidth/blockWidth - 1)) { // blockGroupWidth/width results in the horizontal number of blocks 
           objectsCollideAt.right.push(obj); 
          } 
          if (clsdir.indexOf("bottom") >= 0 && blockY == (blockGroupHeight/blockHeight - 1)) { // blockGroupHeight/height results in the vertical number of blocks. 
           objectsCollideAt.bottom.push(obj); 
          } 
         } else { 
          if (blockY == 0) { 
           objectsCollideAt.top.push(obj); 
          } 
         } 

         obj2container.addChild(obj); 
        } 
       } 
      } 
     } 
    } 
    var dirt = Graphic("http://i.imgur.com/zF6Lhfl.png", 40, 40); 
    var rock = Graphic("http://i.imgur.com/QgxGfJs.png", 40, 40); 
    var grass = Graphic("http://i.imgur.com/5SkIyyM.png, http://i.imgur.com/CT6yf5q.png, http://i.imgur.com/gTwOePB.png", 40, 40); 
    var shadow = Graphic("http://i.imgur.com/50I5K1F.png", 40, 40); 
    var shadow2 = Graphic("http://i.imgur.com/dR9195w.png", 40, 40); 

    var obj2container = new createjs.Container(); 
    // Note that the hero will respawn in the middle of each object if he die. 
    // dirt.createBlockAt(X, Y, W, H); 
    dirt.createBlockAt(0, 40, 40 * 3, 40 * 9); 
    rock.createBlockAt(40 * 4, 40 * 3, 40 * 3, 40); 
    dirt.createBlockAt(40 * 3, 40 * 5, 40 * 4, 40 * 5); 
    rock.createBlockAt(40 * 12, 40 * 6, 40, 40); 
    shadow.createBlockAt(40 * 5 - 20, 40 * 8 - 2, 40, 40, "none", 0.5); 
    shadow.createBlockAt(40 * 4, 40 * 9 - 2, 40, 40, "none", 0.5); 
    rock.createBlockAt(40 * 5 - 20, 40 * 7, 40, 40); 
    rock.createBlockAt(40 * 4, 40 * 8, 40, 40); 
    shadow2.createBlockAt(0, 40 * 9, 40 * 7, 40, "none", 0.5); 
    dirt.createBlockAt(0, 40 * 10, 40 * 14, $(window).height() - (40 * 10)); // Use $(window).height() instead of stage.canvas.height here. stage.canvas.height wasn't set yet. // This will be unnecessary after implementing camera movement. 
    grass.createBlockAt(0, 40 * 1 - 20, 40 * 3, 20, "none"); 
    grass.createBlockAt(40 * 3, 40 * 5 - 20, 40 * 4, 20, "none"); 
    grass.createBlockAt(0, 40 * 10 - 20, 40 * 14, 20, "none"); 

    obj2container.cache(0, 0, $(window).width(), $(window).height()); 
    stage.addChild(obj2container); 

    var data = { 
     images: ["http://i.imgur.com/RjVQ6e1.png"], 
     frames: { 
      width: 30, 
      height: 40 
     }, 
     animations: { 
      stand: 0, 
      run: [1, 2, "runloop", 0.15], 
      runloop: [3, 7, true, 0.15], 
      jump: 11, 
      fall: 12, 
      stopfalling: [13, 15, "stand", 0.25] 
     } 
    }; 
    var spriteSheet = new createjs.SpriteSheet(data); 
    var hero = new createjs.Sprite(spriteSheet, "stand"); 
    hero.offset = 4 + 1; // "+1" is important, change the first number only. 
    hero.regX = hero.offset + 2; 
    hero.regY = hero.offset; 
    hero.width = 30 - (hero.offset * 2) - 10; 
    hero.height = 40 - (hero.offset * 2); 
    hero.xvel = hero.yvel = 0; // Number of pixels the hero will move/8. 

    if (localStorage.x && localStorage.y && localStorage.xpast && localStorage.ypast) { // Was localStorage declared? 
     hero.x = Number(localStorage.x); 
     hero.y = Number(localStorage.y); 
     hero.xpast = Number(localStorage.xpast); 
     hero.ypast = Number(localStorage.ypast); 
    } else { 
     hero.x = hero.xpast = 40; // Very first X. 
     hero.y = hero.ypast = 0; // Very first Y. 
    } 

    hero.jumping = true; 
    hero.airtime = 0; 
    hero.animation = "stand"; 
    stage.addChild(hero); 


    if (typeof Storage === undefined) { 
     alert("Your browser doesn't support saving the game. All changes will be discarted when you leave the page."); 
    } 

    document.addEventListener("keydown", function (evt) { 
     if (evt.keyCode == 87 || evt.keyCode == 38 || evt.keyCode == 32) { // up 
      if (!key.holdingUp && !hero.jumping) { // Check if hero isn't jumping and if user isn't holding the key. 
       key.up = true; 
      } 
     } 
     if (evt.keyCode == 65 || evt.keyCode == 37) { // left 
      key.left = true; 
     } 
     if (evt.keyCode == 68 || evt.keyCode == 39) { // right 
      key.right = true; 
     } 
     if (evt.keyCode == 83 || evt.keyCode == 40) { // down 
      key.down = true; 
     } 
    }); 

    document.addEventListener("keyup", function (evt) { 
     if (evt.keyCode == 87 || evt.keyCode == 38 || evt.keyCode == 32) { // up 
      key.up = false; 
      key.holdingUp = false; 
     } 
     if (evt.keyCode == 65 || evt.keyCode == 37) { // left 
      key.left = false; 
     } 
     if (evt.keyCode == 68 || evt.keyCode == 39) { // right 
      key.right = false; 
     } 
     if (evt.keyCode == 83 || evt.keyCode == 40) { // down 
      key.down = false; 
     } 
    }); 

    stage.on("stagemousedown", function (e) { 
     if (event.which === 1) { 
      mouse.x = e.stageX, 
      mouse.y = e.stageY; 

      if (mouse.x > hero.x + hero.width + touch.tollerance) { 
       key.right = true; 
      } 
      if (mouse.x < hero.x - touch.tollerance) { 
       key.left = true; 
      } 
      if (mouse.x > hero.x - touch.tollerance && mouse.x < hero.x + hero.width + touch.tollerance && mouse.y > hero.y - touch.tollerance && mouse.y < hero.y + hero.height + touch.tollerance) { 
       key.up = true; 
      } 
     } 
    }); 


    stage.on("stagemouseup", function() { 
     setTimeout(function() { 
      key.up = false; 
      key.right = false; 
      key.left = false; 
      key.holdingUp = false; 
     }, 1000/60); // Wait for one tick loop. 
    }); 

    // Collision handler: 

    function collisionHandler(obj1, obj2array) { // MASTERPIECE! 

     // Side-to-side collision handler: 
     objectsCollideAt.top.forEach(function (obj2) { 
      // Top side: 
      if (obj1.ypast + obj1.height < obj2.y && obj1.y + obj1.height >= obj2.y && 
      // Checks if past position X was correct: 
      obj1.xpast + obj1.width >= obj2.x && obj1.xpast <= obj2.x + obj2.width) { 
       hero.yvel = 0; 
       hero.jumping = false; 
       if (hero.airtime > 30) { 
        // hero.xpast and hero.ypast must be set to the same position so it will not cause a collision. 
        hero.x = hero.xpast = Number(localStorage.x); 
        hero.y = hero.ypast = Number(localStorage.y); 
       } else { 
        obj1.y = obj2.y - obj1.height - 1; 
        if (typeof Storage !== undefined && !hero.jumping && hero.y == hero.ypast) { // Checks for localStorage support. 
         localStorage.x = obj2.x + ((obj2.width/2) - (obj1.width/2)); 
         localStorage.y = hero.y; 
         localStorage.xpast = hero.xpast; 
         localStorage.ypast = hero.ypast; 
         //Debugging: 
         //console.log("Stored "+Number(hero.x)+" as "+Number(localStorage.x)+"."); 
        } 
       } 
       hero.airtime = 0; 
      } 
     }); 

     objectsCollideAt.left.forEach(function (obj2) { 
      // Left side: 
      if (obj1.xpast + obj1.width < obj2.x && obj1.x + obj1.width >= obj2.x && 
      // Checks if past position Y was correct: 
      obj1.ypast + obj1.height >= obj2.y && obj1.ypast <= obj2.y + obj2.height) { 
       hero.xvel = 0; 
       obj1.x = obj2.x - obj1.width - 1; 
      } 
     }); 

     objectsCollideAt.right.forEach(function (obj2) { 
      // Right side: 
      if (obj1.xpast > obj2.x + obj2.width && obj1.x <= obj2.x + obj2.width && 
      // Checks if past position Y was correct: 
      obj1.ypast + obj1.height >= obj2.y && obj1.ypast <= obj2.y + obj2.height) { 
       hero.xvel = 0; 
       obj1.x = obj2.x + obj2.width + 1; 
      } 
     }); 

     objectsCollideAt.bottom.forEach(function (obj2) { 
      // Bottom side: 
      if (obj1.ypast > obj2.y + obj2.height && obj1.y <= obj2.y + obj2.height && 
      // Checks if past position X was correct: 
      obj1.xpast + obj1.width >= obj2.x && obj1.xpast <= obj2.x + obj2.width) { 
       hero.yvel = 0; 
       obj1.y = obj2.y + obj2.height + 1; 
      } 
     }); 

     /* 
       Now that every side-to-side collision change was made, 
       the edge-to-edge collision handler will not detect 
       blocked collisions. 
       */ 
     // Edge-to-edge collision handler: 

     objectsCollideAt.left.forEach(function (obj2) { 
      // Top left edge: 
      if (obj1.ypast + obj1.height < obj2.y && obj1.xpast + obj1.width < obj2.x && obj1.y + obj1.height >= obj2.y && obj1.x + obj1.width >= obj2.x) { 
       hero.xvel = 0; 
       obj1.y = obj2.y - obj1.height - 1; 
       obj1.x = obj2.x - obj1.width - 1; 
      } 
      // Bottom left edge: 
      if (obj1.ypast > obj2.y + obj2.height && obj1.xpast + obj1.width < obj2.x && obj1.y <= obj2.y + obj2.height && obj1.x + obj1.width >= obj2.x) { 
       hero.yvel = hero.xvel = 0; 
       obj1.y = obj2.y + obj2.height + 1; 
       obj1.x = obj2.x - obj1.width - 1; 
      } 
     }); 

     objectsCollideAt.right.forEach(function (obj2) { 
      // Top right edge: 
      if (obj1.ypast + obj1.height < obj2.y && obj1.xpast > obj2.x + obj2.width && obj1.y + obj1.height >= obj2.y && obj1.x <= obj2.x + obj2.width) { 
       hero.xvel = 0; 
       obj1.y = obj2.y - obj1.height - 1; 
       obj1.x = obj2.x + obj2.width + 1; 
      } 

      // Bottom right edge: 
      if (obj1.ypast > obj2.y + obj2.height && obj1.xpast > obj2.x + obj2.width && obj1.y <= obj2.y + obj2.height && obj1.x <= obj2.x + obj2.width) { 
       hero.yvel = hero.xvel = 0; 
       obj1.y = obj2.y + obj2.height + 1; 
       obj1.x = obj2.x + obj2.width + 1; 
      } 
     }); 
    } 

    function changeAnimation(obj1, frameOrAnimation) { 
     if (obj1.animation != frameOrAnimation) { 
      obj1.animation = frameOrAnimation; 
      obj1.gotoAndPlay(frameOrAnimation); 
     } 
    } 

    // Tick: 

    createjs.Ticker.on("tick", tick); 
    createjs.Ticker.setFPS(60); 

    function tick(event) { 

     if (key.up && !hero.jumping && !key.holdingUp && Math.abs(hero.ypast - hero.y) < 6) { // Distance between last frame and actual frame y must be less than 6px. 

      // KNOWN BUG: SOMETIMES THE JUMP HEIGHT DOUBLE! [IMPORTANT] 
      // Diagnostic: None. 
      // Reproduction: This bug normally occur during lags and was amplified after implementing time-based logic. 
      // Solution: Unknown. 

      hero.yvel -= 145; // How much speed the jump will produce. Please avoid changing this number — Speeds over 200 can kill the hero. 
      hero.jumping = true; 
      key.holdingUp = true; // Prevent jumping multiple times while holding the key. 
     } else { 
      if (hero.yvel < 0) { 
       hero.yvel += 3; 
      } 
     } 
     if (key.left && !key.right) { 
      hero.xvel -= (!hero.jumping) ? 3 : 2; 
      hero.regX = hero.offset + 12; // Need review. 
      hero.scaleX = -1; 
     } 
     if (key.right && !key.left) { 
      hero.xvel += (!hero.jumping) ? 3 : 2; 
      hero.regX = hero.offset + 2; // "+2" is due to the head's opposite side. 
      hero.scaleX = 1; 
     } 
     if (key.down) { 
      //hero.yvel+=3; // Commented because there's no need for pushing the hero down. If uncommented: // Need review. 
     } 

     hero.xvel = (hero.xvel > 0) ? Math.min(hero.xvel, 50) : Math.max(hero.xvel, -50); 
     //hero.yvel = (hero.yvel > 0)?Math.min(hero.yvel, 125):Math.max(hero.yvel, -125); // No need for this, there's gravity already. 


     if (hero.jumping == true) { 
      if (hero.yvel < 50) { 
       changeAnimation(hero, "jump"); 
      } else { 
       changeAnimation(hero, "fall"); 
      } 
     } 

     if (hero.ypast != hero.y && hero.yvel > 0) { 
      hero.airtime++; 
      changeAnimation(hero, "fall"); 
     } 
     if (hero.airtime > 100) { 
      // hero.xpast and hero.ypast must be set to the same position so it will not cause a collision. 
      hero.x = hero.xpast = 0; 
      hero.y = hero.ypast = 0; 
     } 
     if (!key.left && !key.right) { 
      if (!hero.jumping) { 

       if (hero.animation == "fall" || hero.animation == "stopfalling") { 
        changeAnimation(hero, "stopfalling"); 
       } else { 
        changeAnimation(hero, "stand"); 
       } 

       if (hero.xvel != 0) { 
        hero.xvel += (hero.xvel < 0) ? 5 : -5; 
       } 
      } else { 
       if (hero.xvel != 0) { 
        hero.xvel += (hero.xvel < 0) ? 2 : -2; 
       } 
      } 
      if (Math.abs(hero.xvel) < 3) { 
       hero.xvel = 0; 
      } 
     } else { 
      if (!hero.jumping && hero.xvel != 0) { // Not jumping, pressing left or right 
       changeAnimation(hero, "run"); 
      } 
     } 

     setTimeout(function() { 
      hero.yvel += 7; 
     }, 250); 

     hero.xpast = hero.x; 
     hero.ypast = hero.y; 
     hero.x += Math.round(event.delta/1000 * (hero.xvel * 6)); 
     hero.y += Math.round(event.delta/1000 * (hero.yvel * 6)); 

     collisionHandler(hero, objectsCollideAt.it); 

     stage.update(); 
    } 

    // Canvas resizing: 
    var resizeCanvas = function() { 
     stage.canvas.width = window.innerWidth; 
     stage.canvas.height = window.innerHeight; 
    } 
    resizeCanvas(); 
    $(window).on('resize', resizeCanvas); 
} 

// Image preloading (Primitive!): 

function loadImgs(src, callback) { 
    var sprite = new Image(); 
    sprite.onload = callback; 
    sprite.src = src; 
} 
loadImgs("http://i.imgur.com/RjVQ6e1.png", function() { // Hero Sprite 
    loadImgs("http://i.imgur.com/zF6Lhfl.png", function() { // Dirt 
     loadImgs("http://i.imgur.com/gTwOePB.png", function() { // Grass 3 
      loadImgs("http://i.imgur.com/CT6yf5q.png", function() { // Grass 2 
       loadImgs("http://i.imgur.com/5SkIyyM.png", function() { // Grass 
        loadImgs("http://i.imgur.com/QgxGfJs.png", function() { // Rock 
         loadImgs("http://i.imgur.com/50I5K1F.png", function() { // Shadow 
          loadImgs("http://i.imgur.com/dR9195w.png", function() { // Shadow2 
           init(); 
          }); 
         }); 
        }); 
       }); 
      }); 
     }); 
    }); 
}); 

JSFiddle

回答

0

我发现在我的代码的问题。由于"stagemousedown"事件处理程序中的event.which == 1条件,它不起作用。这是因为,至少在iOS上,event.which等于0

这是我的最后stagemousedown事件处理程序:

stage.on("stagemousedown", function (e) { 
    if (event.which < 2) { 
     mouse.x = e.stageX, 
     mouse.y = e.stageY; 

     if (mouse.x > hero.x + hero.width + touch.tollerance) { 
      key.right = true; 
     } 
     if (mouse.x < hero.x - touch.tollerance) { 
      key.left = true; 
     } 
     if (mouse.x > hero.x - touch.tollerance && mouse.x < hero.x + hero.width + touch.tollerance && mouse.y > hero.y - touch.tollerance && mouse.y < hero.y + hero.height + touch.tollerance) { 
      key.up = true; 
     } 
    } 
}); 

JSFiddle