Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Змейка с поворотом на произвольный угол (http://www.flasher.ru/forum/showthread.php?t=171457)

saikspaik 16.11.2011 09:29

Змейка с поворотом на произвольный угол
 
Вложений: 1
Нужно сделать змейку, чтобы она работала по принципу паровоза - за головой идут остальные звенья - как вагоны паровоза.

Алгоритм я придумал такой:
1. Поворачиваем голову на заданный угол
2. Двигаем голову на N пикселей
3. Поворачиваем следующее звено в сторону предыдущего
4. Двигаем это звено на N пикселей
Повторяем 3,4 пункты для остальных звеньев.

Но так как с геометрией/тригонометрией/алгеброй туго, алгоритм работает не так как задумано, и звенья при повороте, постепенно сбиваются в кучу.
Подскажите пожалуйста правильный алгоритм.

Код главного класса:
Код AS3:

public class Snake extends Sprite {
                public var dir:int = 0;//Направление головы змейки
                private var speed:int = 2;//Скорость змейки
                private var speedX:Number;//Скорость по x
                private var speedY:Number;//Скорость по y
                private var piecesNum:int = 5;//Количество звеньев змейки
                private var pieces:Array = [];//Массив для звеньев
 
                private const PI:Number = Math.PI;//Чтобы быстрее обращаться к PI
 
                public function Snake():void {
 
                        for (var i:int = 0; i < piecesNum; i++) {
                                pieces[i] = new Link(400 + i * 16, 200);//Добавляем части змейки
                                addChild(pieces[i]);
                        }
 
                        stage.addEventListener(KeyboardEvent.KEY_DOWN, onKDown);
                        addEventListener(Event.ENTER_FRAME, loop);
                }
 
                private function onKDown(e:KeyboardEvent):void {
                        //Поворачиваем голову змейки
                        switch (e.keyCode) {
                                case 40:
                                        pieces[0].rotation += 15;
                                break;
                                case 38:
                                        pieces[0].rotation -= 15;
                                break;
                        }
                }
 
                private function loop(e:Event):void {
                        speedX = Math.cos(pieces[0].rotation/180*PI) * speed;//Вычисляем на сколько передвигать голову по x
                        speedY = Math.sin(pieces[0].rotation/180*PI) * speed;//Вычисляем на сколько передвигать голову по y
 
                        pieces[0].x -= speedX;//Передвигаем голову по x
                        pieces[0].y -= speedY;//Передвигаем голову по y
 
                        //Пытаемся двигать остальные звенья за головой
                        for (var i:int = 1; i < piecesNum; i++) {
                                pieces[i].rotation = Math.atan2(pieces[i-1].y - pieces[i].y, pieces[i-1].x - pieces[i].x) * (180 / PI) + 180;//Вычисляем угол между текущим звеном и предыдущим, и поворачиваем текущее звено на этот угол
                                speedX = Math.cos(pieces[i].rotation/180*PI) * speed;//Вычисляем на сколько передвигать текущее звено по x
                                speedY = Math.sin(pieces[i].rotation/180*PI) * speed;//Вычисляем на сколько передвигать текущее звено по y
                                pieces[i].x -= speedX;//Передвигаем текущее звено по x
                                pieces[i].y -= speedY;//Передвигаем текущее звено по y
                        }
                }
 
        }

Код звена:
Код AS3:

public function Link(_x:int, _y:int) {
                        x = _x;
                        y = _y;
 
                        graphics.lineStyle(10, 0x75C525, 1, false, "normal", "none");
                        graphics.lineTo( -16, 0);
 
                }

Вот флешка, как это выглядит:
http://megaswf.com/serve/1292233
Клавишами вверх/вниз, меняем направление. Красные точки - это центр звена.

И на всякий случай, проект во вложении.

GBee 16.11.2011 10:23

Высчитываем новые параметры головы, старые отдаем 2 звену из него старые 3ему, и так далее.

Вообще можно сделать односторонний список и по нему спускаться до хвоста.

nuToH 16.11.2011 12:44

почему скорость звена константа, когда в поворотах она далжна быть разная для каждого из них. грубо говоря скорость звена - расстояние между звеньями минус длина звена.
Код AS3:

//Пытаемся двигать остальные звенья за головой
for (var i:int = 1; i < piecesNum; i++) {
        pieces[i].rotation = Math.atan2(pieces[i-1].y - pieces[i].y, pieces[i-1].x - pieces[i].x) * (180 / PI) + 180;//Вычисляем угол между текущим звеном и предыдущим, и поворачиваем текущее звено на этот угол
        var v:Point = new Point(pieces[i-1].x - pieces[i].x, pieces[i-1].y - pieces[i].y);
        var s:Number = v.length - 16;
 
        speedX = Math.cos(pieces[i].rotation/180*PI) * s;//Вычисляем на сколько передвигать текущее звено по x
        speedY = Math.sin(pieces[i].rotation/180*PI) * s;//Вычисляем на сколько передвигать текущее звено по y
        pieces[i].x -= speedX;//Передвигаем текущее звено по x
        pieces[i].y -= speedY;//Передвигаем текущее звено по y
}

Добавлено через 2 минуты
ток получилась веревка вместо змеи))

saikspaik 16.11.2011 21:31

Цитата:

Сообщение от GBee (Сообщение 1046362)
Высчитываем новые параметры головы, старые отдаем 2 звену из него старые 3ему, и так далее.

Спасибо, за алгоритм :drinks: хороший вариант, тоже думал о нем. Если допилить, будет как раз то что я хотел.
Если просто отдавать следующему звену параметры текущего, то все звенья сбиваются в кучу. Нужно как-то запоминать шаги звена, и отдавать следующему не текущие параметры, а которые были N шагов назад.

Цитата:

Сообщение от nuToH (Сообщение 1046395)
почему скорость звена константа, когда в поворотах она далжна быть разная для каждого из них. грубо говоря скорость звена - расстояние между звеньями минус длина звена.

Благодарю. Особенно за код. :drinks:
Цитата:

ток получилась веревка вместо змеи))
Зеленая веревка, тоже змея :D


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

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