Игра узлов и пикселей

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

Основные вещи об игре: Цель состоит в том, чтобы собрать как можно больше белых узлов до того, как ваш курсор перемещается на 5000 пикселей. Большие фиолетовые узлы замедляют вас, но все равно подсчитывают пиксели в обычном режиме. Красные узлы добавляют 1000 пикселей к счетчику расстояния, зеленые вычитают 1000 пикселей.

http://codepen.io/sketchcrush/pen/rOyvya

 $(document).ready(function () {
  
//CREATES NEW COLLECTABLE NODES
    (function makeDiv() {
        var divsize = ((Math.random() * 100) + 50).toFixed();
        var colors = Array('FFF');
        var color = '#' + colors[Math.floor(Math.random() * colors.length)];
        $newdiv = $('<div/>').css({
            'filter': 'blur(100px)',
                'width': '40px',
                'height': '40px',
                'border-radius': '100%',
                'z-index': '-1',
                'filter': 'blur(2px)',
                '-webkit-filter': 'blur(2px)',
                'background-color': color
        });

        var posx = (Math.random() * ($(document).width() - divsize)).toFixed();
        var posy = (Math.random() * ($(document).height() - divsize)).toFixed();


        $newdiv.css({
            'position': 'absolute',
                'left': posx + 'px',
                'top': posy + 'px',
                'display': 'none'
        }).appendTo('#track').fadeIn(200).attr('id', 'node');

 //DETECTS COLLITION WITH COLLECTABLE NODES
        function collision_node($cursor, $node) {
            var x1 = $cursor.offset().left;
            var y1 = $cursor.offset().top;
            var h1 = $cursor.outerHeight(true);
            var w1 = $cursor.outerWidth(true);
            var b1 = y1 + h1;
            var r1 = x1 + w1;
            var x2 = $node.offset().left;
            var y2 = $node.offset().top;
            var h2 = $node.outerHeight(true);
            var w2 = $node.outerWidth(true);
            var b2 = y2 + h2;
            var r2 = x2 + w2;

            if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) {
                return false;
            } else {
              
            //REMOVES A NODE WHEN COLLECTED, CREATES A NEW ONE
                $('#node').fadeOut(100, function () {
                    $('#node').remove();
                    makeDiv();
                });
                //return true;
            }
        }

        window.setInterval(function () {
            $('#result').text(collision_node($('#cursor'), $('#node')));
        }, 200);

    })();

});

//A COUNTER FOR THE NODES COLLECTED WILL BE CREATED LATER

//DETECT THE CURSOR'S COORDINATES
(function cursorMapping() {

    var $mouseX = 0,
        $mouseY = 0;
    var $xp = 0,
        $yp = 0;

    $(document).mousemove(function (e) {
        $mouseX = e.pageX;
        $mouseY = e.pageY;
    });

    function showCoords(event) {
        var x = event.clientX;
        var y = event.clientY;
        var coor = "X: " + x + ", Y: " + y;
    }


//DECLARING VARS THAT WILL BE USED TO DETECT POSITION AND SPEED
    var mrefreshinterval = 500; // update display every 500ms
    var lastmousex = -1;
    var lastmousey = -1;
    var lastmousetime;
    var mousetravel = 0;
    var lastmousetravel = 0;



    var speed;
    var marker1 = 1;
    var marker2 = 1;

    var timer = setInterval(function () {
        marker1;
        marker2;
    }, 20);

  
//THIS FUNCTION CHANGES THE CURSOR'S COLOR DEPENDING ON ITS SPEED (NOT AVAILABLE IN THIS CODEPEN)
    var thisInterval = setInterval(function FXInterval() {

        speed = $('#speed').text();
        if (marker1 === marker2 && lastmousetravel === mousetravel || speed < 1.5) {
            $('#cursor').attr('class', 'cursor_transition_revert');
            $('#cursor').css({
                'background-color': '#7AA8CE'
            });
            clearInterval(timer);
            var timer;
        } else {
            $('#cursor').attr('class', 'cursor_transition');
            $('#cursor').css({
                'background-color': '#CE7A7A'
            });
        }

        if (mousetravel > 5000) {
            alert('Done!');
            clearInterval(thisInterval);
        }

    }, 20);

//DETERMINES THE AMOUNT OF PIXELS TRAVELED
    $('html').mousemove(function (e) {
        var mousex = e.pageX;
        var mousey = e.pageY;
        if (lastmousex > -1) mousetravel += Math.max(Math.abs(mousex - lastmousex), Math.abs(mousey - lastmousey));
        lastmousex = mousex;
        lastmousey = mousey;
        var speed = lastmousex + lastmousey;

        setTimeout(function () {
            lastmousetravel = mousetravel;
        }, 20);

        document.getElementById("mousetravel").innerHTML = 'Distance: ' + mousetravel;
    });

    var newSpeed;
    var newColor;
  
//DETECTS COLLISION WITH THE PURPLE NODES THAT SLOW YOUR CURSOR
    setInterval(function () {
        function collision_thing($cursor, $thing) {
            var x1 = $cursor.offset().left;
            var y1 = $cursor.offset().top;
            var h1 = $cursor.outerHeight(true);
            var w1 = $cursor.outerWidth(true);
            var b1 = y1 + h1;
            var r1 = x1 + w1;
            var collides = false;

            $thing.each(function (i) {
                var x2 = $(this).offset().left;
                var y2 = $(this).offset().top;
                var h2 = $(this).outerHeight(true);
                var w2 = $(this).outerWidth(true);
                var b2 = y2 + h2;
                var r2 = x2 + w2;

                collides = collides || !(b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2);
            });

            newSpeed = collides ? 200 : 20;
            //newColor = collides ? '#000' : '#fff';
            changeCursorPosition();

            function changeCursorPosition() {
                $xp += (($mouseX - $xp) / newSpeed);
                $yp += (($mouseY - $yp) / newSpeed);
                $("#cursor").css({
                    left: $xp + 'px',
                    top: $yp + 'px'
                });
                //$($thing).css({'background-color': newColor}); 
            }
        }
        $(collision_thing($('#cursor'), $('.thing')));
    }, 20);

//DETECTS COLLISION WITH THE RED NODES THAT ADD 1000 PIXELS TO YOUR DISTANCE COUNT
    setInterval(function () {
        function collision_add1000($cursor, $add1000) {
            var x1 = $cursor.offset().left;
            var y1 = $cursor.offset().top;
            var h1 = $cursor.outerHeight(true);
            var w1 = $cursor.outerWidth(true);
            var b1 = y1 + h1;
            var r1 = x1 + w1;
            var collides = false;

            $add1000.each(function (i) {
                var x2 = $(this).offset().left;
                var y2 = $(this).offset().top;
                var h2 = $(this).outerHeight(true);
                var w2 = $(this).outerWidth(true);
                var b2 = y2 + h2;
                var r2 = x2 + w2;

                if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) {
                    //return false;
                } else {
                    mousetravel -= 1000;
                    $($add1000).remove();
                    //return true;
                }

            });

        }
        $(collision_add1000($('#cursor'), $('#add1000_1')));
        $(collision_add1000($('#cursor'), $('#add1000_2')));
    }, 20);

//DETECTS COLLISION WITH THE GREEN NODES THAT SUBTRACT 1000 PIXELS TO YOUR DISTANCE COUNT
    setInterval(function () {
        function collision_sub1000($cursor, $sub1000) {
            var x1 = $cursor.offset().left;
            var y1 = $cursor.offset().top;
            var h1 = $cursor.outerHeight(true);
            var w1 = $cursor.outerWidth(true);
            var b1 = y1 + h1;
            var r1 = x1 + w1;
            var collides = false;

            $sub1000.each(function (i) {
                var x2 = $(this).offset().left;
                var y2 = $(this).offset().top;
                var h2 = $(this).outerHeight(true);
                var w2 = $(this).outerWidth(true);
                var b2 = y2 + h2;
                var r2 = x2 + w2;

                if (b1 < y2 || y1 > b2 || r1 < x2 || x1 > r2) {} else {
                    mousetravel += 1000;
                    $($sub1000).remove();
                }

            });

        }
        $(collision_sub1000($('#cursor'), $('#sub1000_1')));
        $(collision_sub1000($('#cursor'), $('#sub1000_2')));
    }, 20);

})();
 html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    width: 100%;
    overflow: hidden;
    cursor: none;
}
#cursor {
    width: 50px;
    height: 50px;
    position: fixed;
    border-radius: 25px;
}
#cursor_info, #db_info {
    color: #000;
    position: absolute;
    top: 0;
}
#db_info {
    right: 0;
}
#flex_container {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
}
#track {
    width: 100%;
    height: 100%;
}
.container {
    width: 100%;
    height: 100%;
    position: relative;
    background: linear-gradient(-45deg, #333, #181818 50%, #333);
    z-index: -1;
}
.cursor_transition_revert {
    background-color: #7AA8CE;
    box-shadow: 0px 0px 30px #7AA8CE;
    animation-name: cursor_transition_revert;
    animation-duration: 2s;
    animation-play-state: running;
}
@keyframes cursor_transition_revert {
    0% {
        background-color: #CE7A7A;
        box-shadow: 0px 0px 30px #CE7A7A;
    }
    100% {
        background-color: #7AA8CE;
        box-shadow: 0px 0px 30px #7AA8CE;
    }
}
.hud {
    font-size: 2em;
    color: #fff;
    font-family: Arial;
    -webkit-animation: neon1 1.5s ease-in-out infinite alternate;
    -moz-animation: neon1 1.5s ease-in-out infinite alternate;
    animation: neon1 1.5s ease-in-out infinite alternate;
}
@keyframes neon1 {
    from {
        text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #fff, 0 0 40px #FF1177, 0 0 70px #FF1177, 0 0 80px #FF1177, 0 0 100px #FF1177, 0 0 150px #FF1177;
    }
    to {
        text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #fff, 0 0 20px #FF1177, 0 0 35px #FF1177, 0 0 40px #FF1177, 0 0 50px #FF1177, 0 0 75px #FF1177;
    }
}
.thing {
    border-radius: 35px;
    animation: thing_glow 1.5s ease-in-out infinite alternate;
}
@keyframes thing_glow {
    from {
        box-shadow: 0px 0px 30px #4625AB;
        filter: blur(2px);
        -webkit-filter:blur(2px);
    }
    to {
        box-shadow: 0px 0px 100px #4625AB;
        filter: blur(12px);
        -webkit-filter:blur(12px);
    }
}
.add1000 {
    border-radius: 20px;
    animation: add1000_glow 1s ease-in-out infinite alternate;
}
@keyframes add1000_glow {
    from {
        box-shadow: 0px 0px 20px #37CF89;
        filter: blur(2px);
        -webkit-filter:blur(2px);
    }
    to {
        box-shadow: 0px 0px 40px #37CF89;
        filter: blur(12px);
        -webkit-filter:blur(12px);
    }
}
.sub1000 {
    border-radius: 20px;
    animation: sub1000_glow 1.5s ease-in-out infinite alternate;
}
@keyframes sub1000_glow {
    0% {
        box-shadow: 0px 0px 20px #D42440;
        filter: blur(2px);
        -webkit-filter:blur(2px);
    }
    50% {
        box-shadow: 0px 0px 20px #D42440;
        filter: blur(2px);
        -webkit-filter:blur(2px);
    }
    to {
        box-shadow: 0px 0px 40px #D42440;
        filter: blur(12px);
        -webkit-filter:blur(12px);
    }
}
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='track'>
    <div class='container'>
        <div id='cursor'>&nbsp;</div>
        <div class='thing' style='width:70px; height:70px; background: #4625AB; position: absolute; bottom: 400px; right: 300px; z-index: -1;'>&nbsp;</div>
        <div class='thing' style='width:70px; height:70px; background: #4625AB; position: absolute; bottom: 200px; right: 400px; z-index: -1;'>&nbsp;</div>
        <div class='add1000' id='add1000_1' style='width:40px; height:40px; background: #fff; position: absolute; bottom: 200px; right: 700px; z-index: -1;'>&nbsp;</div>
        <div class='add1000' id='add1000_2' style='width:40px; height:40px; background: #fff; position: absolute; bottom: 100px; right: 600px; z-index: -1;'>&nbsp;</div>
        <div class='sub1000' id='sub1000_1' style='width:40px; height:40px; background: #fff; position: absolute; bottom: 150px; right: 150px; z-index: -1;'>&nbsp;</div>
        <div class='sub1000' id='sub1000_2' style='width:40px; height:40px; background: #fff; position: absolute; bottom: 250px; right: 500px; z-index: -1;'>&nbsp;</div>
    </div>
</div>
<div id='cursor_info'>
    <p id='mousetravel' class='hud'></p>
</div>
11 голосов | спросил jack_of_all_trades 3 +03002015-10-03T22:11:39+03:00312015bEurope/MoscowSat, 03 Oct 2015 22:11:39 +0300 2015, 22:11:39

1 ответ


16

Я отвечу только на повторение в коде обнаружения столкновения в этом ответе.

Следующие строки кода повторяются несколько раз:

var x1 = $el.offset().left;
var y1 = $el.offset().top;
var h1 = $el.outerHeight(true);
var w1 = $el.outerWidth(true);
var b1 = y1 + h1;
var r1 = x1 + w1;

Единственное, что изменилось, это значение $ el. Поэтому вы можете переместить этот код в отдельную функцию, которая получает $ el. Чтобы получить 4 значения, которые вам нужны из одного вызова функции, вы можете вернуть объект с четырьмя полями: (я переименовал переменные для улучшения читаемости)

function getBoundingBox($el) {
    var left = $el.offset().left;
    var top = $el.offset().top;
    var height = $el.outerHeight(true);
    var width = $el.outerWidth(true);
    var bottom = top + height;
    var right = left + width;

    return {
        left: left,
        top: top,
        bottom: bottom,
        right: right
    };
}

С помощью этой функции код для collision_node становится:

function collision_node($cursor, $node) {
    var cursorBB = getBoundingBox($cursor);
    var nodeBB = getBoundingBox($node);

    if (cursorBB.bottom < nodeBB.top || cursorBB.top > nodeBB.bottom || cursorBB.right < nodeBB.left || cursorBB.left > nodeBB.right) {
        return false;
    } else {

    //REMOVES A NODE WHEN COLLECTED, CREATES A NEW ONE
        $('#node').fadeOut(100, function () {
            $('#node').remove();
            makeDiv();
        });
    }
}

Также повторяется следующее условие:

cursorBB.bottom < nodeBB.top || cursorBB.top > nodeBB.bottom || cursorBB.right < nodeBB.left || cursorBB.left > nodeBB.right

Так как условие зависит от двух объектов (двух ограничивающих полей), его можно разделить на отдельную функцию с двумя аргументами:

function testCollision(bb1, bb2) {
    return !(bb1.bottom < bb2.top || bb1.top > bb2.bottom || bb1.right < bb2.left || bb1.left > bb2.right)
}

Что можно переписать, чтобы избежать инвертирования условия: (исходное условие в collision_node отмечено, было ли no столкновение)

function testCollision(bb1, bb2) {
    return (bb1.bottom >= bb2.top && bb1.top <= bb2.bottom && bb1.right >= bb2.left && bb1.left <= bb2.right)
}

Теперь collision_node выглядит следующим образом:

function collision_node($cursor, $node) {
    var cursorBB = getBoundingBox($cursor);
    var nodeBB = getBoundingBox($node);

    if (!testCollision(cursorBB, nodeBB)) {
        return false;
    } else {

        //REMOVES A NODE WHEN COLLECTED, CREATES A NEW ONE
        $('#node').fadeOut(100, function () {
                $('#node').remove();
                makeDiv();
        });
    }
}

Теперь измените два других места, где у вас есть код тестирования столкновения, чтобы использовать эти две функции. (и добавьте комментарий со ссылкой на обновленный фрагмент кода)!


Важным изменением здесь было объединение нескольких переменных в один объект. Когда у вас есть несколько переменных, которые всегда используются вместе, их обычно следует группировать в один объект. Это позволяет обрабатывать все из них как одно целое, а не коллекцию отдельных переменных. Например, функция testCollision получает два ограничивающих блока вместо восьми чисел.

Удачи!

(Кроме того, перейдите по своему коду и избавьтесь от неиспользуемого материала, например, у вас нет элемента #result, и вы не Мне нужны массивы colors, если у него один цвет, также удалите код с комментариями)

ответил Spike 4 +03002015-10-04T00:09:52+03:00312015bEurope/MoscowSun, 04 Oct 2015 00:09:52 +0300 2015, 00:09:52

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132