Сенсорные события не работают EaselJS

0

Я разрабатываю игру HTML5 Canvas с помощью EaselJS, и я обнаружил проблему после изменения моего кода. События касания работали до этого изменения, но он больше не работает, и я не помню, что я изменил, но он не был связан с stagemousedown/stagemouseup. Я тестировал игру только на iOS 7.

Кто-нибудь может мне помочь?

Как я уже сказал, я не знаю, где проблема, тогда я поставлю здесь весь код вместо соответствующей части (> 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 opposite side.
            hero.scaleX = 1;
        }
        if (key.down) {
            //hero.yvel+=3; // Commented because there 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 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

Теги:
easeljs

1 ответ

0
Лучший ответ

Я нашел проблему в своем коде. Он не работал из-за event.which == 1 внутри обработчика событий "stagemousedown". Это происходит потому, что, по крайней мере, на 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;
        }
    }
});

Изображение 174551

Ещё вопросы

Сообщество Overcoder
Наверх
Меню