Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Взаимодействие персонажа и элементов массива (http://www.flasher.ru/forum/showthread.php?t=173306)

Обломов 29.12.2011 01:31

Взаимодействие персонажа и элементов массива
 
Всем привет! Подскажите пожалуйста решение проблемы.
Учусь делать платформер, сделал персонажа, научил его двигаться от нажатия игроком клавиш, теперь хочу сделать вот что:
сделать мувиклип из обычного прямоугольника, который мог бы быть основой для карты, то есть платформой, кирпичиком, добавляя который на стол в нужном количестве можно было бы составить уровень - "землю", платформы, далее при загрузке кадра нужно, чтобы все копии этого мувиклипа загружались в массив, а после этого я бы сделал такую проверку: если хиттест персонажа с элементами массива с платформами отрицательный, то к y-координате игрока плюсуется такое-то число, то есть персонаж как бы падает вниз.
я новичек во флеше, пытался сделать описанное выше по разным урокам, но получается такая проблема:
(изначально персонаж находится, допустим, в середине экрана, а платформа/платформы в самом низу экрана)
когда на экране присутствует только одна платформа, персонаж спокойно "приземляется" на нее и стоит на ней, а когда я добавляю в кадр еще одну или больше платформ из библиотеки - персонаж пролетает вниз сквозь платформы, не реагируя на них, причем чем больше платформ в кадре - тем быстрее скорость падения.
Работаю в Флэш Макромедиа 8, какой экшн скрипт не знаю, учусь по урокам, настройки в программе не менял и использую то, что работает и соответствует описанию из урока.
Вот что я делал:
1) в первый кадр мувиклипа snowblock (это платформа) добавлял строку
Код AS1/AS2:

_parent.addBox(this);

2) в кадре игры, в самом начале написал:
Код AS1/AS2:

var boxes = [];
addBox = function (obj) {
        boxes.push(obj);
}

3) в кадре игры написал:
Код AS1/AS2:

function checkHitPlatform() {
        var i = boxes.length;
        while (i--) {
                var curB = boxes[i];
                if (!curB.hitTest(human.p4)) {
                        human._y += 15;
                }
        }
}

где human - инстенс нэйм персонажа, а p4 - инстенс нейм мувиклипа для проверки столкновения снизу, находящийся в мувиклипе персонажа.
P.S.: оформил куски кода наугад, так как не знаю версию экшн скрипта, не ругайтесь.

Tails 29.12.2011 17:08

Интересный способ постройки уровня, первый раз такое вижу.

Используйте лучше у себя переменную для гравитаций:
Код AS1/AS2:

function checkHitPlatform() {
        var i = boxes.length;
        while (i--) {
                var curB = boxes[i];
                if (curB.hitTest(human.p4)) {
                        gravity = 0;
                        break;
                }
        }
}
function gravitiPlayer() {
        human._y += gravity;
        gravity ++;
}

Там где вы запускаете фун. checkHitPlatform():
Код AS1/AS2:

 
checkHitPlatform();
gravitiPlayer();

И описание переменной в начале:
Код AS1/AS2:

var gravity = 0;

А косяк у вас в том, что вы прибавляете _y персонажу столько раз, сколько у вас блоков на сцене. Баг с "проходом через землю" тоже от сюда.

Обломов 30.12.2011 01:01

Спасибо, оба варианта работают! Как убрать следующий баг? Он заключается в том, что персонаж приземляется:
а) в Вашем варианте ногами ниже верхней границы платформы, чем больше высота падения и ускорение - тем глубже он проходит в платформу ногами:
Код AS1/AS2:

var gravity = 0;
humanstep = 15;
var boxes = [];
addBox = function (obj) {
        boxes.push(obj);
};
//счетчик времени полета
jumptime = 0;
humanjump = false;
jumppick = false;
function Movement() {
        if (Key.isDown(key.RIGHT)) {
                human._x += humanstep;
                human._xscale = 40;
                human.gotoAndPlay(1);
        } else if (Key.isDown(key.LEFT)) {
                human._x -= humanstep;
                human._xscale = -40;
                human.gotoAndPlay(1);
        } else if (Key.isDown(key.UP)) {
                humanjump = true;
        } else {
                human.gotoAndPlay(3);
        }
}
checkHitPlatform = function () {
        var i = boxes.length;
        while (i--) {
                var curB = boxes[i];
                if (curB.hitTest(human.p4)) {
                        gravity = 0;
 
                        jumptime = 0;
                        if (humanjump == true) {
                                humanjump = false;
                        }
                }
        }
};
function gravitiPlayer() {
        human._y += gravity;
        gravity++;
}
onEnterFrame = function () {
        gravitiPlayer();
        var i = boxes.length;
        while (i--) {
                var curB = boxes[i];
                if (curB.hitTest(human.p4)) {
                        gravity = 0;
 
                        jumptime = 0;
                        if (humanjump == true) {
                                humanjump = false;
                        }
                }
        }
        Movement();
        //-----------
        if (humanjump == true && jumptime<5) {
                human.gotoAndPlay(2);
                human._y -= 30;
                jumptime += 1;
        }
        //-----------   
};

б) в моем варианте он приземляется выше платформы или ровно на ее поверхность по очереди при прыжках:

Код AS1/AS2:

humanstep = 15;
var boxes = [];
addBox = function (obj) {
        boxes.push(obj);
};
//счетчик времени полета
jumptime = 0;
humanjump = false;
jumppick = false;
function Movement() {
        if (Key.isDown(key.RIGHT)) {
                human._x += humanstep;
                human._xscale = 40;
                human.gotoAndPlay(1);
        } else if (Key.isDown(key.LEFT)) {
                human._x -= humanstep;
                human._xscale = -40;
                human.gotoAndPlay(1);
        } else if (Key.isDown(key.UP)) {
                humanjump = true;
                        } else {
                human.gotoAndPlay(3);
        }
}
checkHitPlatform = function () {
        var i = boxes.length;
        while (i--) {
                var curB = boxes[i];
                if (curB.hitTest(human.p4)) {
                        //контакт сверху
                        human._y -= 20;
                        jumptime = 0;
                        if (humanjump == true) {humanjump = false;}
                }
        }
};
onEnterFrame = function () {
        human._y += 20;
        checkHitPlatform();
        Movement();
        //-----------
        if (humanjump == true && jumptime<5) {
                human.gotoAndPlay(2);
                human._y -= 30;
                jumptime += 1;
        }
 
        //-----------   
};


Tails 31.12.2011 12:01

Код AS1/AS2:

var gravity = 0;
humanstep = 15;
var boxes = [];
addBox = function (obj) {
        boxes.push(obj);
};
//счетчик времени полета
jumptime = 0;
humanjump = false;
jumppick = false;
function Movement() {
        if (Key.isDown(key.RIGHT)) {
                human._x += humanstep;
                human._xscale = 40;
                human.gotoAndPlay(1);
        } else if (Key.isDown(key.LEFT)) {
                human._x -= humanstep;
                human._xscale = -40;
                human.gotoAndPlay(1);
        } else if (Key.isDown(key.UP)) {
                humanjump = true;
        } else {
                human.gotoAndPlay(3);
        }
}
checkHitPlatform = function () {
        var i = boxes.length;
        while (i--) {
                var curB = boxes[i];
                if (curB.hitTest(human.p4)) {
                        gravity = 0;
 
                        jumptime = 0;
                        if (humanjump == true) {
                                humanjump = false;
                        }
                }
        }
};
function gravitiPlayer() {
        human._y += gravity;
        gravity++;
}
onEnterFrame = function () {
        gravitiPlayer();
        var i = boxes.length;
        while (i--) {
                var curB = boxes[i];
                if (curB.hitTest(human.p4)) {
                        gravity = 0;
                        // Если утонул в блоке, вытаскиваем: <<<------------------------ изменение
                        while(curB.hitTest(human.p4)){
                                human._y-=0.1;
                        }
 
 
                        jumptime = 0;
                        if (humanjump == true) {
                                humanjump = false;
                        }
                }
        }
        Movement();
        //-----------
        if (humanjump == true && jumptime<5) {
                human.gotoAndPlay(2);
                human._y -= 30;
                jumptime += 1;
        }
        //-----------   
};


Обломов 02.01.2012 21:29

Сделал, работает отлично! После этого сделал столкновение справа и слева, все гуд, но не получается нормально сделать столкновение с платформой сверху, при прыжке - прыжок тормозится, но персонаж всё равно головой проходит сквозь платформу, пробовал исправить тем же приемом, что Вы посоветовали выше - не помогает. Что можете подсказать?
Вот код на данный момент:
Код AS1/AS2:

var boxes = [];
addBox = function (obj) {
        boxes.push(obj);
};
prityazhenie = 20;
humanstep = 15;
grav = 3; //замедление скорости прыжка, направленной вверх
jumptime = 0;
humanjump = false;
humanreversed = false;
jumpstep = 25;
//движение вправо и влево
function Movement() {
        if (Key.isDown(key.RIGHT)) {
                human._x += humanstep;
                human._xscale = 40;
                human.gotoAndPlay(1);
                humanreversed = false;
        } else if (Key.isDown(key.LEFT)) {
                human._x -= humanstep;
                human._xscale = -40;
                human.gotoAndPlay(1);
                humanreversed = true;
        } else {
                human.gotoAndPlay(3);
        }
}
checkHitPlatform = function () {
        var i = boxes.length;
        while (i--) {
                var curB = boxes[i];
                if (curB.hitTest(human.p4)) {
                        //контакт ног персонажа с платформой
                        prityazhenie = 0;
                        upact = false;
                        jumptime = 0;
                        jumpstep = 40;
                        if (humanjump == true) {
                                humanjump = false;
                        }
                        if (!curB.hitTest(human.p4)) {
                                while (!curB.hitTest(human.p4)) {
                                        human._y += 0.1;
                                }
                        }
                        if (curB.hitTest(human.p4)) {
                                while (curB.hitTest(human.p4)) {
                                        human._y -= 0.1;
                                }
                        }
                } else {
                        prityazhenie = 20;
                }
                if (curB.hitTest(human.p3)) {
                        //контакт c платформой справа
                        human._x -= humanstep;
                }
                if (curB.hitTest(human.p3) && humanreversed == true) {
                        //контакт с платформой слева
                        human._x += humanstep*2;
                }
                if (curB.hitTest(human.p2)) {
                        //контакт головы персонажа с платформой
                        upact = true;
                        hero._y = curB._y-curB._height/2-hhy;
                }
        }
};
onEnterFrame = function () {
        human._y += prityazhenie; //притяжение вниз
        checkHitPlatform();
        Movement();
        //----------- прыжок
        if (((Key.isDown(key.UP) && Key.isDown(key.RIGHT)) || (Key.isDown(key.LEFT) && Key.isDown(key.UP)) || (Key.isDown(key.UP))) && upact == false) {
                humanjump = true;
        } else {
                humanjump = false;
        }
        if (humanjump == true && jumptime<5) {
                human.gotoAndPlay(2);
                human._y -= jumpstep;
                jumptime += 1;
                jumpstep -= grav;
        }
        //-----------                 
};


Tails 02.01.2012 21:45

У вас внутри human есть p4 как я понял - ноги, на которые и проверяеться столкновение с блоками. Создайте внутри human ещё такой-же регион только для головы.

Обломов 03.01.2012 00:20

Вложений: 1
Он есть, это p2 в коде, а p3 для столкновений сбоку, вот скрин размещения платформ, но в принципе он особой информации для решения проблемы не несет - хиттест проходит нормально - проверял переменной, состояние которой отображалось в специальном текстовом поле. p1 пока не использую.

Tails 03.01.2012 01:01

Может как-то так:
Код AS1/AS2:

//движение вправо и влево
function Movement() {
        if (Key.isDown(key.RIGHT)) {
                human._x += humanstep;
                human._xscale = 40;
                human.gotoAndPlay(1);
                humanreversed = false;
        } else if (Key.isDown(key.LEFT)) {
                human._x -= humanstep;
                human._xscale = -40;
                human.gotoAndPlay(1);
                humanreversed = true;
        } else {
                human.gotoAndPlay(3);
        }
}
checkHitPlatform = function () {
        var i = boxes.length;
        while (i--) {
                var curB = boxes[i];
 
 
                if(curB.hitTest(human.p2)) {
                        while (curB.hitTest(human.p2)) {
                                human._y += 0.1;
                                prityazhenie = 0;
                                jumptime = 0;
                                humanjump = false;
                                jumpstep = 0;
                        }
                }
 
                if (curB.hitTest(human.p4)) {
                        //контакт ног персонажа с платформой
                        prityazhenie = 0;
                        upact = false;
                        jumptime = 0;
                        jumpstep = 40;
                        if (humanjump == true) {
                                humanjump = false;
                        }
                        if (curB.hitTest(human.p4)) {
                                while (curB.hitTest(human.p4)) {
                                        human._y -= 0.1;
                                }
                        }
                } else {
                        prityazhenie = 20;
                }
                if (curB.hitTest(human.p3)) {
                        //контакт c платформой справа
                        human._x -= humanstep;
                }
                if (curB.hitTest(human.p3) && humanreversed == true) {
                        //контакт с платформой слева
                        human._x += humanstep*2;
                }
                if (curB.hitTest(human.p2)) {
                        //контакт головы персонажа с платформой
                        upact = true;
                        hero._y = curB._y-curB._height/2-hhy;
                }
        }
};
onEnterFrame = function () {
 
        checkHitPlatform();
        human._y += prityazhenie; //притяжение вниз
 
        Movement();
        //----------- прыжок
        if (((Key.isDown(key.UP) && Key.isDown(key.RIGHT)) || (Key.isDown(key.LEFT) && Key.isDown(key.UP)) || (Key.isDown(key.UP))) && upact == false) {
                humanjump = true;
        } else {
                humanjump = false;
        }
        if (humanjump == true && jumptime<5) {
                human.gotoAndPlay(2);
                human._y -= jumpstep;
                jumptime += 1;
                jumpstep -= grav;
        }
        //-----------                 
};

Для временной проверки переменных и прочего удобнее использовать:
Код AS1/AS2:

trace(переменная);
trace(human._y);


Обломов 03.01.2012 21:22

Персонаж стал дергаться, пока находится сверху от платформы, а при прыжке всё равно головой проходит сквозь платформу сверху. Метод трэйс и правда удобный, особенно для проверки состояния массива.

Tails 05.01.2012 11:04

Попробуйте p2 и p4 пошире сделать

Обломов 10.01.2012 16:08

Никаких изменений кроме перемен в движении горизонтально!

Добавлено через 30 часов 27 минут
Никаких изменений, кроме изменений в передвижении горизонтально.


Часовой пояс GMT +4, время: 07:30.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.