Why does it only work as expected the second time?

2

I have this function:

for (var i in chars) {
        chars[i].walk();
        for (var j in chars) {
            if (i != j) {
                collision(chars[i], chars[j]);
                action(chars[i], chars[j]);
            }
        }
    }

Does it work unexpectedly when I first call, only when I call it a second time so it works? (does not work if I call her and then another and then call her again).

chars is an array that holds objects of class Character .

collision works correctly and I tried to remove it and did not change anything.

Function walk :

walk () {
    if (!this.acting && this.walking) {
        switch (this.walking) {
            case "left":
                this.animate(9, 9);
                this.posX -= this.speed;
                break;
            case "right":
                this.animate(11, 9);
                this.posX += this.speed;
                break;
            case "up":
                this.animate(8, 9);
                this.posY -= this.speed;
                break;
            case "down":
                this.animate(10, 9);
                this.posY += this.speed;
                break;
        }
    }
}

The complete files are these:

  • index.html :
  • <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>Undivine</title>
        <link href="css/style.css" rel="stylesheet">
    </head>
    <body>
        <div>
            <canvas height="600" id="canvas" width="800"></canvas>
        </div>
        <script src="js/load.js" onload="loadJS('js/message', 'js/character', 'js/collision', 'js/script')"></script>
    </body>
    </html>
    
  • css/styles.css :
  • @import "https://fonts.googleapis.com/css?family=Alfa+Slab+One";
    * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
    }
    body {
        text-align: center;
    }
    #canvas {
        background-color: #f00;
        cursor: pointer;
        margin-top: 10px;
    }
    
  • js/character.js :
  • class Character {
        constructor (img, posX, posY, visible) {
            //propriedades
            this.acting = null;
            this.height = 64;
            this.img = img;
            this.posX = posX;
            this.posY = posY;
            this.speed = 3;
            this.srcX = 0;
            this.srcY = 10;
            this.step = 0;
            this.visible = visible;
            this.walking = null;
            this.width = 64;
        }
        //metodos
        action () {
            if (this.acting) {
                switch (this.acting) {
                    case "spellcast":
                        var cols = 7;
                        var srcY = 0 + this.srcY % 4;
                        break;
                    case "thrust":
                        var cols = 8;
                        var srcY = 4 + this.srcY % 4;                   
                        break;
                    case "slash":
                        var cols = 6;
                        var srcY = 12 + this.srcY % 4;                  
                        break;
                    case "shoot":
                        var cols = 13;
                        var srcY = 16 + this.srcY % 4;                  
                        break;
                    case "hurt":
                        var cols = 6;
                        var srcY = 20;                  
                        break;
                }
                if (this.animate(srcY, cols)) {
                    var acting = this.acting;
                    this.acting = null;
                    this.step = 0;
                    if (acting != "hurt") {
                        this.srcX = 0;
                    }
                    return acting;
                }
            }
        }
        animate (srcY, cols) {
            if (this.srcY == srcY) {
                this.srcX = Math.floor(this.step / 5) % cols;
                this.step++;
                return this.step == cols * 5 - 1;
            } else {
                this.srcY = srcY;
                this.step = 0;
            }
        }
        bottomEdge () {
            return this.posY + this.height;
        }
        centerX () {
            return this.posX + this.width / 2;
        }
        centerY () {
            return this.posY + this.height / 2;
        }
        cursor (e) {
            return e.offsetX >= this.posX && e.offsetX < this.rightEdge() && e.offsetY >= this.posY && e.offsetY < this.bottomEdge()?true:false;
        }
        direction () {
            switch (this.srcY % 4) {
                case 0:
                    return "up";
                    break;
                case 1:
                    return "left";
                    break;
                case 2:
                    return "down";
                    break;
                case 3:
                    return "right";
                    break;
            }
        }
        draw (cnv, ctx) {
            if (this.visible) { 
                switch (this.posX) {
                    case "center":
                        this.posX = (cnv.width - this.width) / 2;
                        break;
                    case "left":
                        this.posX = 0;
                        break;
                    case "right":
                        this.posX = cnv.width - this.width;
                        break;
                }
                switch (this.posY) {
                    case "middle":
                        this.posY = (cnv.height - this.height) / 2;
                        break;
                    case "top":
                        this.posY = 0;
                        break;
                    case "bottom":
                        this.posY = cnv.height - this.height;
                        break;
                }
                ctx.drawImage(this.img, this.srcX * this.width, this.srcY * this.height, this.width, this.height, this.posX, this.posY, this.width, this.height);
            }
        }
        halfHeight () {
            return this.height / 2;
        }
        halfWidth () {
            return this.width / 2;
        }
        rightEdge () {
            return this.posX + this.width;
        }
        stop (direction) {
            if (this.walking == direction) {
                this.walking = null;
            }
        }
        walk () {
            if (!this.acting && this.walking) {
                switch (this.walking) {
                    case "left":
                        this.animate(9, 9);
                        this.posX -= this.speed;
                        break;
                    case "right":
                        this.animate(11, 9);
                        this.posX += this.speed;
                        break;
                    case "up":
                        this.animate(8, 9);
                        this.posY -= this.speed;
                        break;
                    case "down":
                        this.animate(10, 9);
                        this.posY += this.speed;
                        break;
                }
            }
        }
    }
    
  • js/collision.js :
  • function action (a, b) {
        switch (a.action()) {
            case "shoot":
                shoot(a, b);
                break;
            case "thrust":
            case "slash":
                attack(a, b);
                break;
        }
    }
    function collision (a, b) {
        var x = Math.abs(a.centerX() - b.centerX());
        var y = Math.abs(a.centerY() - b.centerY());
        var width = a.halfWidth() + b.halfWidth();
        var height = a.halfHeight() + b.halfHeight();
        if (x < width && y < height && b.visible) {
            switch (a.direction()) {
                case "up":
                    a.posY += height - y;
                    break;
                case "left":
                    a.posX += width - x;
                    break;
                case "down":
                    a.posY -= height - y;
                    break;
                case "right":
                    a.posX -= width - x;
                    break;
            }
        }
    }
    function shoot (a, b) {
        switch (a.direction()) {
            case "up":
                if (a.centerX() > b.posX && a.centerX() < b.rightEdge() && a.posY > b.posY) {
                    b.visible = false;
                }
                break;
            case "left":
                if (a.centerY() > b.posY && a.centerY() < b.bottomEdge() && a.posX > b.posX) {
                    b.visible = false;
                }
                break;
            case "down":
                if (a.centerX() > b.posX && a.centerX() < b.rightEdge() && a.posY < b.posY) {
                    b.visible = false;
                }
                break;
            case "right":
                if (a.centerY() > b.posY && a.centerY() < b.bottomEdge() && a.posX < b.posX) {
                    b.visible = false;
                }
                break;
        }
    }
    function attack (c, d) {
        var x = Math.abs(c.centerX() - d.centerX());
        alert(x);
        var y = Math.abs(c.centerY() - d.centerY());
        var width = c.halfWidth() + d.halfWidth();
        var height = c.halfHeight() + d.halfHeight();
        switch (c.direction()) {
            case "up":
                if (x <= width && y <= height && c.posY > d.posY) {
                    d.visible = false;
                }
                break;
            case "left":
                if (x <= width && y <= height && c.posX > d.posX) {
                    d.visible = false;
                }
                break;
            case "down":
                if (x <= width && y <= height && c.posY < d.posY) {
                    d.visible = false;
                }
                break;
            case "right":
                if (x <= width && y <= height && c.posX < d.posX) {
                    d.visible = false;
                }
                break;
        }
    }
    
  • js/load.js :
  • //carrega javascript
    function loadJS () {
        for (var i in arguments) {
            document.write("<script src='" + arguments[i] + ".js'></script>");
        }
    }
    //carrega imagens
    function loadImgs () {
        var imgs = new Object();
        for (var i in arguments) {
            var start = arguments[i].lastIndexOf("/") + 1;
            var end = arguments[i].indexOf(".");
            var name = arguments[i].substring(start, end);
            imgs[name] = new Image();
            imgs[name].src = arguments[i];
        }
        return imgs;
    }
    
  • js/message.js :
  • class Message {
        constructor (text, x, y, font, color, visible) {
            //propriedades
            this.text = text;
            this.x = x;
            this.y = y;
            this.font = font;
            this.color = color;
            this.visible = visible;
        }
        //metodos
        fillText (cnv, ctx) {
            if (this.visible) { 
                ctx.font = this.font;
                switch (this.x) {
                    case "center":
                        this.x = (cnv.width - ctx.measureText(this.text).width) / 2;
                        break;
                    case "left":
                        this.x = 0;
                        break;
                    case "right":
                        this.x = cnv.width - ctx.measureText(this.text).width;
                        break;
                }
                switch (this.y) {
                    case "middle":
                        this.y = (cnv.height - parseInt(this.font)) / 2;
                        break;
                    case "top":
                        this.y = 0;
                        break;
                    case "bottom":
                        this.y = cnv.height - parseInt(this.font);
                        break;
                }
                ctx.fillStyle = this.color;
                ctx.fillText(this.text, this.x, this.y, cnv.width);
            }
        }
    }
    
  • js/script.js :
  • //carrega as imagens
    var imgs = loadImgs("img/character/princess.png", "img/character/skeleton.png", "img/character/soldier.png");
    //onload
    onload = function () {
        //variaveis
        var cnv = document.getElementById("canvas");
        var ctx = cnv.getContext("2d");
        ctx.textBaseline = "top";
        var msgs = [];
        var chars = [];
        var status = "start";
        //cria as mensagens
        msgs["title"] = new Message("UNDIVINE", "center", "middle", "80px 'Alfa Slab One'", "#fff", true);
        //cria os personagens
        chars["player"] = new Character(imgs["princess"], "left", "middle", false);
        chars["skeleton"] = new Character(imgs["skeleton"], "center", "middle", false);
        chars["soldier"] = new Character(imgs["soldier"], "right", "middle", false);
        //eventos
        cnv.addEventListener("click", function () {
            if (status == "start") {
                msgs["title"].visible = false;
                for (var i in chars) {
                    chars[i].visible = true;
                }
                status = "play";
            }
        }, false);
        addEventListener("keydown", function (e) {
            if (status == "play") {
                switch (e.keyCode) {
                    case 37:
                        chars["player"].walking = "left";
                        break;
                    case 38:
                        chars["player"].walking = "up";
                        break;
                    case 39:
                        chars["player"].walking = "right";
                        break;
                    case 40:
                        chars["player"].walking = "down";
                        break;
                }
            }
        }, false);
        addEventListener("keyup", function (e) {
            if (status == "play") {
                switch (e.keyCode) {
                    case 37:
                        chars["player"].stop("left");
                        break;
                    case 38:
                        chars["player"].stop("up");
                        break;
                    case 39:
                        chars["player"].stop("right");
                        break;
                    case 40:
                        chars["player"].stop("down");
                        break;
                    case 88:
                        chars["player"].acting = "slash";
                        break;
                }
            }
        }, false);
        //funcoes
        function loop () {
            requestAnimationFrame(loop);
            if (status == "play") {
                update();
            }
            render();
        }
        function update () {
            for (var i in chars) {
                chars[i].walk();
                for (var j in chars) {
                    if (i != j) {
                        collision(chars[i], chars[j]);
                        action(chars[i], chars[j]);
                    }
                }
            }
        }
        function render () {
            //limpa o canvas
            ctx.clearRect(0, 0, cnv.width, cnv.height);
            //desenha os personagens
            for (var i in chars) {
                chars[i].draw(cnv, ctx);
            }
            //escreve as mensagens
            for (var i in msgs) {
                msgs[i].fillText(cnv, ctx);
            }
        }
        //inicia as funcoes
        loop();
    }
    
  • img/character/princess.png :
  • img/character/skeleton.png :
  • img/character/soldier.png :
  • Or,ifyouwanttodownloadeverythingfromGoogleDrive,theURLis link

        
    asked by anonymous 02.08.2017 / 00:30

    0 answers