Не зацикливание?HTML5 и JavaScript - PullRequest
1 голос
/ 07 октября 2011

Понятия не имею, почему этот код не зацикливается, как следует.Мой разум взорван, и, надеюсь, кто-нибудь может мне помочь.Это моя первая попытка в мире HTML5 и JavaScript и мой первый пост в StackOverflow.Мой фон в Java, поэтому я должен объяснить причуды в моем коде.Кстати, если вы запустите код, холст и шары будут отображаться, просто не двигайтесь.

Во-первых, это HTML5

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>ChainReaction5</title>
    <script type="text/javascript" src="chain_reaction.js"></script>
    </head>

    <body>
    <body onLoad="init();">
    <canvas id="myCanvas" width="500" height="400">
    Your browser dosen't support the HTML5 canvas.</canvas><br />
    </body>
    </html>

Во-вторых, это js

    //gobal vars
    var context;
    var box;
    var balls;

    var defaultBallX=240;
    var defaultBallY=190;
    var defaultBallRad=6;
    var defaultBallV=5;

    var defaultNumBalls=10;

    //box class
    function Box() {
        var boxx=20;
        var boxy=20;
        var boxWidth=460;
        var boxHeight=360;

        this.getX = function() {return boxx;}

        this.getY = function() {return boxy;}

        this.getWidth = function() {return boxWidth;}

        this.getHeight = function() {return boxHeight;}

        this.getBalls = function() {return ball;}

        this.paintMe = function() {
            context.fillStyle = "black";
            context.strokeRect(boxx, boxy, boxWidth, boxHeight);
        }
    }

    /*  Box Class
     *  this class is sloppy but more memory efficent
     */
    function Ball(x, y, radius, vx, vy, color) {
        this.x=x;
        this.y=y;
        this.radius=radius;
        this.vx=vx;
        this.vy=vy;
        this.color=color;   

        this.paintMe = function() {
            context.beginPath();
            context.arc(this.x, this.y, radius, 0, 2*Math.PI, true);
            context.fillStyle = this.color; 
            context.fill();
        }
    }

    Array.prototype.appendBalls = new function(array) {}
    Array.prototype.clearBalls = new function() {}

    Array.prototype.appendBalls = function(array) {
            for (var i = 0; i < array.length; i++) {
                balls.push(array[i]);
            }
        }

    Array.prototype.clearBalls = function() {
            balls = new Array();
        }

    // begin program
    function init() {
        context = document.getElementById("myCanvas").getContext("2d"); 
        box = new Box();
        balls = new Array();
        balls.appendBalls(createBalls(box, defaultNumBalls));
        setInterval(moveBall(balls, box), 100);
    }

    function createBalls(box, numBalls) {
        var locBalls = new Array(numBalls);
        for (var i = 0; i < numBalls; i++) {
            var randx = randp(50, 400)
            var randy = randp(50, 300);
            var randr = Math.random()*defaultBallRad+1;
            var randvx = randv();
            var randvy = randv();
            var randc = randColor();
            locBalls[i] = new Ball(randx, randy, randr, randvx, randvy, randc);
        }
        return locBalls;    

        function randv() {
            var neg = 1;
            if (Math.random()>.5) neg = -neg;
            return Math.random()*defaultBallV*neg;  
        }

        function randp(low, hight) {
            if (low < 0) low = 0;
            var p = -1;
            while (p > hight || p < low) {
                p = Math.random()*hight;
            }
            return p;
        }

        function randColor() {
            var letters = '0123456789ABCDEF'.split('');
            var color = '#';
            for (var i = 0; i < 6; i++ ) {
                color += letters[Math.round(Math.random() * 15)];
            }
            return color;
        }
    }
    function moveBall(balls, box) {
        clear(this.box);
        this.box.paintMe();

        for (var i = 0; i < this.balls.length; i++) {
                moveAndCheck(this.balls[i], this.box);
            }
    }

    function moveAndCheck(b, box) {

        if ((b.x+b.vx+b.radius-1)>(this.box.boxWidth+this.box.boxx) || b.x+b.vx-b.radius<this.box.boxx+1) {
            b.vx = -b.vx;
        }
        if ((b.y+b.vy+b.radius-1)>(this.box.boxHeight+this.box.boxy) || b.y+b.vy-b.radius<this.box.boxy+1) {
            b.vy = -b.vy;
        }

        b.x += b.vx;
        b.y += b.vy;

        b.paintMe();

    }

    function clear(box) {
        context.clearRect(this.box.boxx, this.box.boxy, 
        this.box.boxWidth, this.box.boxHeight);
    }

Ответы [ 2 ]

0 голосов
/ 17 октября 2011

Я хочу поблагодарить людей, которые внесли свой вклад в мой вопрос, и это помогло решить проблему, и выбранный мною ответ был актуальным, но он решил проблему по другой причине.

Неверно:

Помещение кавычек вокруг 'moveBalls (balls, box)' оживляет вещи.

Что действительно решает проблему, так это удаление аргументов и скобок из вызова кфункция шагаЯ обнаружил это при переписывании других частей моего кода, как предложил автор.

Так что для дальнейшего уведомления других людей с подобной проблемой, если вам нужно удалить аргументы и использовать функцию-обертку или глобальные переменные.

0 голосов
/ 07 октября 2011

При первом запуске я получил в консоли Firebug следующее:

бесполезный вызов setInterval (пропущены кавычки вокруг аргумента?) [Break On This Error] setInterval (moveBall (шарики, коробка), 100);

Помещение кавычек вокруг 'moveBalls (шары, коробка)' оживляет вещи.

Между прочим, вы можете использовать наследование прототипов, чтобы сделать вашу функцию немного более эффективной, методы в Box даны для каждого экземпляра. Чтобы они наследовали методы, поместите их в прототип конструктора:

Box.prototype = {

    getX: function() {return this.boxx;},

    getY: function() {return this.boxy;},

    getWidth: function() {return this.boxWidth;},

    getHeight: function() {return this.boxHeight;},

    getBalls: function() {return this.ball;},

    paintMe: function() {
        context.fillStyle = "black";
        context.strokeRect(this.boxx, this.boxy, this.boxWidth, this.boxHeight);
    }
};

Обратите внимание, что в javascript ключевое слово этой функции устанавливается вызовом, а не тем, как вы объявляете функцию (хотя вы можете использовать ES5 bind , но это пока широко не поддерживается).

Некоторые другие советы:

В конструкторе Box вы создаете локальные переменные, но вы действительно хотите назначить их новому экземпляру Box, поэтому используйте this вместо var :

function Box() {
    this.boxx=20;
    this.boxy=20;
    this.boxWidth=460;
    this.boxHeight=360;
}

В функции clearBox вы используете this , когда оно не установлено в вызове, поэтому оно ссылается на window . Просто избавьтесь от этого, вы передаете box в функцию, поэтому обращайтесь к ней напрямую:

function clear(box) {
    context.clearRect(box.boxx, box.boxy, 
    box.boxWidth, box.boxHeight);
}

То же самое относится к функциям moveBall и moveAndCheck , просто избавьтесь от this (я думаю, вам следует изучить, как this обрабатывается в javascript, о нем много статей, он сильно отличается от Java). Теперь шарики будут красиво подпрыгивать внутри коробки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...