Идеи для движения

Relike

Здравствуйте. Для курсовой я подготовил программу на управление объектом. Можете мне подкинуть какую нибудь идею, чтобы придать смысл данному алгоритму? Просто у меня что-то никаких идей нет... И еще вопрос, как сделать увеличение скорости интерактивное? (Жалкое подобие там есть, но не работает((( ). Заранее благодарю!
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
    <style type="text/css">#pole {
    width: 500px;
    height: 300px;
    background: url(1.jpg);
    border: 5px solid #6b502e;
    overflow: hidden;
}
 
#obj {
    width: 10px;
    height: 10px;
    background: black;
    border-radius: 50%;
}</style>
    <script type="text/javascript">
var left = false, right = false, top = false, bottom = false, s = false, n = 1;
 
function speed(){
    n = document.getElementById('speed').value
    return n;
}
 
function anim_right(right) {
    if (right){
    left = false; top = false; bottom = false;
    var oldLeft = parseInt(document.getElementById("obj").style.left), speed = n;
    document.getElementById("obj").style.left = oldLeft + speed + "px";
    
    }
    else return false;
}
 
function anim_bottom(bottom) {
    if (bottom){
    left = false; top = false; right = false;
    var oldTop = parseInt(document.getElementById("obj").style.top), speed = n;
    document.getElementById("obj").style.top = oldTop + speed + "px";
   } 
    else return false;
}
 
function anim_left(left) {
    if (left){
    right = false; top = false; bottom = false;
    var oldRight = parseInt(document.getElementById("obj").style.left), speed = n;
    document.getElementById("obj").style.left = oldRight - speed + "px";
    }
    else return false;
}
 
function anim_top(top) {
    if (top){
    right = false; left = false; bottom = false;
    var oldBottom = parseInt(document.getElementById("obj").style.top), speed = n;
    document.getElementById("obj").style.top = oldBottom - speed + "px";
    } ///вызов функции animation() через 100мс
    else return false;
}
 
function stop(s) {
    if (s){
    left = false; right = false; top = false; bottom = false;
    anim_top(top); anim_bottom(bottom); anim_right(right); anim_left(left);
}
    else return false;
}
 
function init(e){
switch (e.keyCode) {
    case 38 : {top = true; anim_top(top); setTimeout("anim_top(top)", 10); break; }
    case 39 : {right = true; anim_right(right); setTimeout("anim_right(right)", 10);  break;}
    case 40 : {bottom = true; anim_bottom(bottom);  setTimeout("anim_bottom(bottom)", 10); break;}
    case 37 : {left = true; anim_left(left); setTimeout("anim_left(left)", 10
        ); break;}
    case 32 : {s = true; stop(s); break;}
    default : return; break;
}
}
</script>
</head>
<body onkeydown="init(event)">
    <div id="pole">
        <div id="obj" style="position : relative; left : 100px; right : 100px; top : 100px; bottom : 100px; width: 10px;
    height: 10px;
    background: black;"></div>
    </div>
    <p>Желаемый уровень сложности (скорость)</p>
    <input type="text" size="2" id="speed">
    <button onclick="speed">Установить</button>
</body>
</html>
14 ответов

Relike

простейшая идея - генерировать лабиринт и гонять ваш "шарик" по этому лабиринтукстати, реализовали бы ещё и движение по диагоналям (типа когда одновременно нажаты "вверх" и вправо") - преподаватель будет в восторгеи ещё... нажатие на клавишу "Пробела" никакой "остановки" не вызывает - "шарик" движется вверх


Relike

kalabuni, движение по диагонали организовать как? Ну я представляю примерно, но как засунуть в свитч имеющийся его, я не знаю. И еще как лабиринт сделать?kalabuni, на сколько я представляю реализацию лабиринта у меня кровь стынет в венах...столько границ прописывать...или можно проще поступить?


Relike

<script>
var dL = dU = dR = dB = 0;
var L = 123; T = 234; S = 5; 
 
onload = function ()
{
document.body.onkeydown = function (ev)
   {
   var e = window.event || ev, K = e.keyCode;
        if (K == 37) dL = -S;
   else if (K == 38) dU = -S; 
   else if (K == 39) dR =  S;
   else if (K == 40) dB =  S;
   }
 
document.body.******* = function (ev)
   {
   var e = window.event || ev, K = e.keyCode;
        if (K == 37) dL = 0;
   else if (K == 38) dU = 0; 
   else if (K == 39) dR = 0;
   else if (K == 40) dB = 0;
   }
 
function move1 ()
   {
   var p = 'px', O = document.getElementById ('myPic').style;
   L += dL + dR, T += dU + dB;
   O.left = L + p; O.top  = T + p;
   setTimeout (move1, 100);
   }
 
move1 ();
}
</script>
 
<body>
Âûáåðèòå ñêîðîñòü ïåðåìåùåГ*ГЁГї:
<select onchange="S = this.value * 1; this.blur ()">
<option value="5">5</option>
<option value="10">10</option>
<option value="20">20</option>
<option value="50">50</option>
</select>
 
<img src="http://www.cyberforum.ru/images/smilies/ae.gif"
     id="myPic"
     style="position: absolute; z-index: 999; left: 123px; top: 234px">
</body>
ну раз "кровь стынет", то лабиринтом заморачиваться не будем


Relike

kalabuni, улыбнул смайлик) Спасибо! Буду ковырять! А как лабиринт генерировать?kalabuni, и если честно...я не понимаю ваш код...но само движение реализовано идеально. Мне бы так.
<script>
var dL = dU = dR = dB = 0; //Для чего эти переменные?
var L = 123; T = 234; S = 5; //Это left/top/speed как я понимаю.
 
onload = function ()
{
document.body.onkeydown = function (ev) //Эту тоже
   {
   var e = window.event || ev, K = e.keyCode; //и эту, что такое ev?
        if (K == 37) dL = -S;
   else if (K == 38) dU = -S; 
   else if (K == 39) dR =  S;
   else if (K == 40) dB =  S;
   }
 
document.body.******* = function (ev) //Объясните эту строку
   {
   var e = window.event || ev, K = e.keyCode;
        if (K == 37) dL = 0;
   else if (K == 38) dU = 0; 
   else if (K == 39) dR = 0;
   else if (K == 40) dB = 0;
   }
 
function move1 ()  //Где инициализируется эта функция?
   {
   var p = 'px', O = document.getElementById ('myPic').style;
   L += dL + dR, T += dU + dB;
   O.left = L + p; O.top  = T + p;
   setTimeout (move1, 100);
   }
 
move1 ();
}
</script>
И вообще объясните по возможности. И можно не лабиринт а какие либо банальные пару препятствий...только я не знаю как сделать проще...
<script>
var dL = dU = dR = dB = 0;
var L = 123; T = 234; S = 5; 
 
onload = function ()
{
document.body.onkeydown = function (ev) 
   {
   var e = window.event || ev, K = e.keyCode;
        if (K == 37) dL = -S;
   else if (K == 38) dU = -S; 
   else if (K == 39) dR =  S;
   else if (K == 40) dB =  S;
   }
 
document.body.******* = function (ev)
   {
   var e = window.event || ev, K = e.keyCode;
        if (K == 37) dL = 0;
   else if (K == 38) dU = 0; 
   else if (K == 39) dR = 0;
   else if (K == 40) dB = 0;
   }
 
function move1 ()
   {
   var p = 'px', O = document.getElementById ('myPic').style;
   L += dL + dR, T += dU + dB;
   O.left = L + p; O.top  = T + p;
   setTimeout (move1, 100);
   }
 
move1 ();
}
</script>
Прокомментируйте код если не сложно... И кровь стынет т.к. я думаю для каждого поворотика нужно границы прописывать, а там код на 500... строк будет... мб вы знаете более оперативный способ? Или добавить парочку препятсявий может быть. Чтобы не просто двигать его...


Relike

var dL = dU = dR = dB = 0; // дельта_Влево = дельта_Вверх = дельта_Вправо = дельта_Вниз = начально равны нулю
var L = 123; T = 234; S = 5; // значения left и top из in-line стиля тега <img> + скорость
// определение начальных значений этих переменных вынесено из функций, ибо они нужны ГЛОБАЛЬНЫМИ
 
onload = function ()
{
document.body.onkeydown = function (ev) //нажатие клавиши - это СОБЫТИЕ, именно в аргумент функции ev это событие и передаётся как ОБЪЕКТ
   {
   var e = window.event || ev, K = e.keyCode; //в браузере MSIE существует специальный объект window.event, во всех остальных используется переданный функции аргумент ev
        if (K == 37) dL = -S;
   else if (K == 38) dU = -S; 
   else if (K == 39) dR =  S;
   else if (K == 40) dB =  S;
   }
 
document.body.******* = function (ev) //аналогично предыдущей - СОБЫТИЕ отпускания клавиши передаётся как аргумент безымянной функции
   {
   var e = window.event || ev, K = e.keyCode; //аналогично, если MSIE - то пользуем стандартный объект window.event, в прочих браузерах - берём событие из аргумента функции
        if (K == 37) dL = 0;
   else if (K == 38) dU = 0; 
   else if (K == 39) dR = 0;
   else if (K == 40) dB = 0;
   }
 
function move1 ()  //здесь эта функция ОПРЕДЕЛЯЕТСЯ, а иницилизируется ниже, в строке #32
   {
   var p = 'px', O = document.getElementById ('myPic').style;
   L += dL + dR, T += dU + dB;
   O.left = L + p; O.top  = T + p;
   setTimeout (move1, 100);
   }
 
move1 ();
}
насчёт лабиринта... судя по вашему уровню (вы ж ещё только учитесь) - я замучаюсь объяснять вам потом алгоритм можно сделать иначе, попроще: -- например, можно реализовать игру типа "собери монетки за какое-то время" (двигаете чем-то типа сундучка, наезжая на случайно появляющиеся на поле монетки; при этом каждая монетка имеет "срок жизни" - бледнеет и исчезает, если не успеть взять) [с учётом выбранного мною облизывающегося смайлика можно сделать "съешь мороженое", которое будет таять ]-- или сделать игру "проверь визуальную память" (рисуется какая-то траектория толстой линией, не меньшей диаметра шарика, затем траектория эта как бы запоминается пользователем и через, положим, минуту, исчезает; пользователю надо за определённое время по памяти провести шарик по этой же траектории, затем показываются обе траектории и вычисляется результат "попадания в колею" в процентах)-- как вариант предыдущего - "проверь память и координацию" - пользователь сначала САМ рисует мышкой траекторию и затем, когда она станет невидима, проводит по ней шарик... и параллельно ведёт по этой же траектории ЕЩЁ и курсор мыши; по окончании отведённого на прохождение времени показываются все три траектории, причём показываются как бы "в записи" и снова вычисляется процент "попадания в колею" и процент совмещения шарика и курсора мыши...эти реализации, полагаю, мне объяснить вам будет легче выбирайте


Relike

kalabuni, Номер 1) Скажите сразу. Мне свои заготовки выкидывать?)


Relike

Скажите сразу. Мне свои заготовки выкидывать?)
зачем же?вам, наоборот, надо будет потрудиться -- для начала возьмите мой алгоритм движения (без изменения скорости) и присобачьте его внутрь "игрового поля" игровое поле - прямоугольник с "золотым сечением" (ну то есть как экран монитора/телевизора - отношение высоты к ширине как 3 : 4) -- добейтесь, чтобы двигаемый объект не выходил за пределы игрового поля, т.е. если даже юзер жмёт клавишу вниз, а шарик находится у нижней границы поля, то шарик вниз не двигается [подсказываю: нужно знать ширину/высоту игрового поля и ширину/высоту картинки шарика; поле делаете position: relative, шарик внутри поля position: absolute; для левой и верхней границы всё просто - если L или T равны нулю, то, значит, шарик находится у какой-то границы; для правой и нижней границы к L и T надо добавить ширину/высоту картинки шарика]дерзайте выложите здесь рабочий код, будем делать дальшено завтра - у меня уже 01:30 ночи, спать пора


Relike

kalabuni, мерси, приеду с учебы буду делать! kalabuni, Так, чтобы не накосячить, я не понял. Если L = 0 || L = 390 и T = 0 || T = 290 зпускать что-то вроде моей старой функции стоп (относительно для l, r, t, b относительно)?
function stop(s) {
    if (s){
    left = false; right = false; top = false; bottom = false;
    anim_top(top); anim_bottom(bottom); anim_right(right); anim_left(left);
}
    else return false;
}
Типа такой?


Relike

Relike, лучше работайте с канвой(Canvas). Гипертекст не был предназначен для сверх интерактивных вещей вроде игр, поэтому в W3 придумали элемент Canvas и удобный API к нему. Вот пример:
Кликните здесь для просмотра всего текста
<!DOCTYPE HTML>
<html lang="en">
 
<head>
    <meta charset="utf-8">
    <title></title>
    <style>
        #canvas {
            display:block;
            margin:auto;
            background-color:#C4C4C4;
            width: 640px;
            height: 480px;
        }
    </style>
</head>
 
<body>
    <canvas id="canvas"></canvas>
    <script>
    
        // Найдем элемент Канвы
        var canvas = document.getElementById("canvas");
        
        // Установим разрешение канвы
        canvas.width = 640;
        canvas.height = 480;
        
        // Вызовем 2D контекст канвы для рисования
        var context = canvas.getContext('2d');
 
        // переменные для клавиатуры
        var tope = false, left = false, right = false, down = false;
        
        // Найдем элемент тела страницы, чтобы регистрировать нажатия кнопок
        var body = document.getElementsByTagName('body')[0];
        
        // Устанавливаем всем переменным true при отпускании клавиш
        body.addEventListener('keydown', function(e){
            switch(e.keyCode){
            case 37: left = true; break;
            case 38: tope = true; break;
            case 39: right = true; break;
            case 40: down = true; break;
            }
        });
        
        // Устанавливаем всем переменным false при отпускании клавиш
        body.addEventListener('*****', function(e){
            switch(e.keyCode){
            case 37: left = false; break;
            case 38: tope = false; break;
            case 39: right = false; break;
            case 40: down = false; break;
            }
        });
        
        // Конструктор игрового объекта
        function Rect(x, y){
            this.x = x;
            this.y = y;
        }
        
        // Метод игрового объекта для рисования
        Rect.prototype.draw = function(){
            context.strokeRect(this.x, this.y, 30, 30);
        }
        
        // Метод игрового объекта для передвижения
        Rect.prototype.move = function(vel){
            if(left){
                this.x -= vel;
            }
            if(right){
                this.x += vel;
            }
            if(tope){
                this.y -= vel;
            }
            if(down){
                this.y += vel;
            }
        }
        
        // Создадим один игровой объект
        var newGameObj = new Rect(100, 100);
        
        // Запустим игровой цикл где будем рисовать и двигать объект
        setInterval(function(){
            context.clearRect(0, 0, 640, 480);
            newGameObj.move(3);
            newGameObj.draw();
        }, 30);
        
    </script>
</body>
</html>


Relike

Padimanskas, Canvas не вариант. Нельзя его использовать


Relike

Canvas не вариант. Нельзя его использовать
Тогда используйте объекты для вашей игры(кстати, пример иллюстрирует и это). И дайте по уху преподу.


Relike

kalabuni, Так-с вот чего я добился.
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript">
    var dL = dU = dR = dB = 0;
var L = 123; T = 234; S = 5; 
var nL = false, nT = false;
 
onload = function ()
{
document.body.onkeydown = function (ev)
   {
   var e = window.event || ev, K = e.keyCode;
        if (K == 37) dL = -S;
   else if (K == 38) dU = -S; 
   else if (K == 39) dR =  S;
   else if (K == 40) dB =  S;
   }
 
document.body.******* = function (ev)
   {
   var e = window.event || ev, K = e.keyCode;
        if (K == 37) dL = 0;
   else if (K == 38) dU = 0; 
   else if (K == 39) dR = 0;
   else if (K == 40) dB = 0;
   }
 
function move1 ()
   {
   var p = 'px', O = document.getElementById ('img').style;
   if ((L >= 0 && L <= 390)&&(T >= 0 && T <= 290)) {
   L += dL + dR, T += dU + dB;
   O.left = L + p; O.top  = T + p;
   setTimeout (move1, 100);
   }
   else ; //Вот тут вопрос....что же сюда воткнуть? return если втыкать то шарик дальше не едет....а так...что еще можно?
   }
   
move1 ();
}
</script>
</head>
<body>
<div id="pole" style="width : 400px; height : 300px; position : relative; background : #e5e5e5; border : 5px solid #000;">
    <div id="img" style="position: absolute; z-index: 999; left: 123px; top: 234px; position : absolytion; width : 10px; height : 10px; border-radius : 50%; background : #000;"></div>
</div>
</body>
</html>
Воот...жду вашего ответа)


Relike

Если L = 0 || L = 390 и T = 0 || T = 290 зпускать что-то вроде моей старой функции стоп (относительно для l, r, t, b относительно)?
зачем такие сложности? в коде есть 2 подряд идущие строки, в первой вычисляются значения L и T во второй строке эти значения присваиваются координатам шарика вот они: L += dL + dR, T += dU + dB; O.left = L + p; O.top = T + p;если шарик хочет "пересечь", например, левую границу, то, значит, L станет меньше нуля проверим это и вернем L обратно в ноль; аналогично и для T для верхней границы а для нижней/правой границы проверяем на "больше чем" 290/390 и, если больше, возвращаем 290/390т.е. нужно между вычислением значений L и T и их присвоением добавить эти проверки/назначения (выделил их комментариями):
   L += dL + dR, T += dU + dB;
   if (L < 0) L = 0; if (L > 390) L = 390;//остановка у вертикальных границ игрового поля
   if (T < 0) T = 0; if (T > 290) T = 290;//остановка у горизонтальных границ игрового поля
   O.left = L + p; O.top  = T + p;
проверьте


Relike

kalabuni, ааа вот оно что! Понятно! Что дальше делать? Нужно наверное что-то более подходящее чем шарик найти?