Показать сообщение отдельно
  #10 (permalink)  
Старый 29.03.2020, 22:31
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,070

ограничение перемещения размерами родительского блока
Nikolay000,
<!DOCTYPE html>
<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  #person {

    width: 80px;
    height: 80px;
    position: absolute;
    background-image: url(http://faoor.com/account/img/back.gif);
    background-repeat: no-repeat;
    border: 1px dotted grey;
}

#point {

    position: absolute;
    left:20%;
    top:30%;
    width: 300px;
    height: 300px;
    background-color: lightgreen;
    border: 1px solid green;
}

#point {

    border: 1px solid grey;
    background-color: #ccc;
}
    html, body {
       width: 100%;
       background: #ffe;
       height: 100%;
}
#content {
       /* максимальная ширина страницы - 600px */
       width: 600px;
       max-width: 600px;
       border: 1px solid;
       position: relative;
       height: 100%;
}
  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
$(function() {
$(document).ready(function () {

    // Персонаж
    var person = $("#person"),

    // информация о скорости, позиции и нажатых клавишах
    velocity_info = $("#velocity"),
    position_info = $("#position"),
    pressed_info = $("#pressed"),

    // текущее положение объекта
    position = [100, 100, 80, 80]
    position[4] = position[0] + position[2]
    position[5] = position[1] + position[3]

    // координаты точки цели и её размеры по ширине и высоте
    var point = [400, 400, 100, 100]
    point[4] = point[0] + point[2]
    point[5] = point[1] + point[3]
    var point_reached = false;

    // вектор скорости
    var velocity = [0, 0, 0, 0, 0 ,0],

    // зажатые клавиши
    pressed = [],

    // обработчик игровой логики (отдельный таймер, НЕ requestAnimationFrame!!!)
    calc = setInterval(calc, 0);

    $('body').append('<div id="point"></div>');
    $('#point').css({'position' : 'absolute',
                     'left' : point[0] + 'px',
                     'top' : point[1] + 'px',
                     'width' : point[2] + 'px',
                     'height' : point[3] + 'px'});

    var point_info = $("#point");

// случаем отдельно события нажатия и отжатия
$('body').on("keydown", function (event) {

    if (pressed.indexOf(event.which) === -1) {
        switch (event.which) {
            case 65: // left
                vec_add(velocity, [-2, 0]);
                break;

            case 87: // forward
                vec_add(velocity, [0, -2]);
                break;

            case 68: // right
                vec_add(velocity, [2, 0]);
                break;

            case 83: // back
                vec_add(velocity, [0, 2]);
                break;
        }

        pressed.push(event.which);

         // после отжатия клавиши перемещения персонажа обновляем его изображение и проверяем достижение им цели
        if (event.which === 65 || event.which === 87 || event.which === 68 || event.which === 83) {
            person_gif ();
            check_point_reach ();
        }
    }
});


$('body').on("keyup", function (event) {

    var index;
    if ((index = pressed.indexOf(event.which)) >= 0) {
        pressed.splice(index, 1);
        switch (event.which) {
            case 65: // left
                vec_sub(velocity, [-2, 0]);
                break;

            case 87: // forward
                vec_sub(velocity, [0, -2]);
                break;

            case 68: // right
                vec_sub(velocity, [2, 0]);
                break;

            case 83: // back
                vec_sub(velocity, [0, 2]);
                break;
        }

        // после отжатия клавиши перемещения персонажа обновляем его изображение и проверяем достижение им цели
        if (event.which === 65 || event.which === 87 || event.which === 68 || event.which === 83) {
            person_gif ();
            check_point_reach ();
        }
    }
});

// запускам отрисовку сцены

if("clamp" in Math === false)
Math.clamp = function clamp(x, lower, upper) {
    return Math.min(Math.max(lower, x), upper);
}
var maxWidth = $("#content").width() -  $("#person").width();
var maxHeight = $("#content").height() -  $("#person").height();
render();
function render() {
    position[0] = Math.clamp(position[0], 0, maxWidth);
    position[1] = Math.clamp(position[1], 0, maxHeight);
    // изменяем позицию объекта
    person.css({'left' : position[0] + "px"});
    person.css({'top' : position[1] + "px"});

    // отладочная информация
    // output(velocity_info, velocity.join(", "));
    // output(position_info, position.join(", "));
    // output(pressed_info, pressed.join(", "));
    // output(point_info, point.join(", "));

    // запрашиваем следующих кадр
    requestAnimationFrame(render);
}

function output(el, text) {
	el.html(text);
}

// расчет игровой логики
function calc() {
    // добавляем вектор скорости
	vec_add(position, velocity);
}


function vec_add(a, b) {
    a[0] += b[0];
    a[1] += b[1];
    a[4] += b[0];
    a[5] += b[1];
}

function vec_sub(a, b) {
    a[0] -= b[0];
    a[1] -= b[1];
    a[4] -= b[0];
    a[5] -= b[1];
}

function person_gif () {

    var fnames = [];
    fnames[65] = 'left';
    fnames[68] = 'right';
    fnames[83] = 'back';
    fnames[87] = 'forward';

    // изображение по умолчанию (когда отжаты все клавиши, либо одновременно нажаты все четыре)
    var fname = 'person';

    // если надат только одна клавиша
    if (pressed.length === 1) {

        fname = fnames[pressed[0]];
    }
    // надаты две клавиши
    else if (pressed.length === 2) {

        // первой нажата кнопка W или S
        if ((fnames[pressed[0]] === 'forward' || fnames[pressed[0]] === 'back') && (fnames[pressed[1]] === 'left' || fnames[pressed[1]] === 'right')) {

            fname = fnames[pressed[0]] + '-' + fnames[pressed[1]];
        }
        // первой нажата кнопка A или D
        else if ((fnames[pressed[0]] === 'left' || fnames[pressed[0]] === 'right') && (fnames[pressed[1]] === 'forward' || fnames[pressed[1]] === 'back')) {

            fname = fnames[pressed[1]] + '-' + fnames[pressed[0]];
        }
    }
    // если нажаты три клавиши
    else if (pressed.length === 3) {

        if (pressed.indexOf(87) >= 0) fname = fnames[87];

        else if (pressed.indexOf(83) >= 0) fname = fnames[83];

    }

    person.css({'background-image' : 'url(http://faoor.com/account/img/back.gif)'});

}

function calc_m () {

    $('#point').text('ОК!');
    $('#point').css ({

        'background-color' : 'lightgreen',
        'border-color' : 'green',
    })
}

function check_point_reach () {

    if (point_reached === false) {
        console.log ('check')
        // если персонаж достиг объекта c любой стороны
        if (
            ( (position[0] >= point[0] && position[0] <= point[4]) || (position[4] >= point[0] && position[4] <= point[4]) ) &&
            ( (position[1] >= point[1] && position[1] <= point[5]) || (position[5] >= point[1] && position[5] <= point[5]) )
        ) {
            point_reached = true;
            calc_m();
        }
    }
}

})
});
  </script>
</head>
<body>
<div id="content">
        <div id="person"></div>
        <div id="velocity"></div>
        <div id="position"></div>
        <div id="pressed"></div>
</div>
</body>
</html>
Ответить с цитированием