![]() |
|
||||||||||
|
|||||
|
Мечтаю написать Ragdoll... Прочитал много инфы, пока сделал вот такую штуку:
(использовал "интеграцию Верлета"). Есть кучка вопросов: 1. --- уже решён --- 2. Как сделать ограничение угла в суставе между двумя точками?.. 3. На конце верёвки болтается треугольник, образованный 3-мя точками. Его всё время клонит в сторону. Как добавить силу тяжести точкам, чтобы они висели ровно?.. Или как-то по-другому это дело решается... package
{
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class Main extends Sprite
{
var pt_1:Particle = new Particle(270,150);
var pt_2:Particle = new Particle(270,175);
var pt_3:Particle = new Particle(270,200);
var pt_4:Particle = new Particle(270,225);
var pt_5:Particle = new Particle(270,250);
var pt_6:Particle = new Particle(270,275);
var pt_7:Particle = new Particle(255,285);
var pt_8:Particle = new Particle(285,285);
var canvas:Shape = new Shape();
// ========================================================== //
public function Main():void
{
stage.frameRate = 30;
addChild(canvas);
addChild(pt_1);
addChild(pt_2);
addChild(pt_3);
addChild(pt_4);
addChild(pt_5);
addChild(pt_6);
addChild(pt_7);
addChild(pt_8);
addEventListener(Event.ENTER_FRAME, checkJoints);
addEventListener(Event.ENTER_FRAME, ptMouse);
}
// ========================================================== //
private function ptMouse(event:Event):void
{
pt_1.x = mouseX;
pt_1.y = mouseY;
drawLine(pt_1, pt_2);
}
// ========================================================== //
private function checkJoints(event:Event):void
{
canvas.graphics.clear();
// Joints
ptJoint(pt_1, pt_2, 25);
ptJoint(pt_2, pt_3, 25);
ptJoint(pt_3, pt_4, 25);
ptJoint(pt_4, pt_5, 25);
ptJoint(pt_5, pt_6, 25);
ptJoint(pt_6, pt_7, 30);
ptJoint(pt_6, pt_8, 30);
ptJoint(pt_7, pt_8, 30);
// Lines
drawLine(pt_2, pt_3);
drawLine(pt_3, pt_4);
drawLine(pt_4, pt_5);
drawLine(pt_5, pt_6);
drawLine(pt_7, pt_6);
drawLine(pt_8, pt_6);
drawLine(pt_7, pt_8);
}
// ========================================================== //
private function ptJoint(p1:Particle, p2:Particle, len:int):void
{
var dx:Number;
var dy:Number;
var d_len:Number;
var diff:Number;
var angle:Number;
dx = p2.x-p1.x;
dy = p2.y-p1.y;
// Method #1
d_len = Math.sqrt(dx*dx + dy*dy);
diff = (d_len-len)/d_len;
p2.x -= dx*diff;
p2.y -= dy*diff;
// Method #2
/*
angle = Math.atan2(dy, dx);
p2.x = p1.x+Math.cos(angle)*len;
p2.y = p1.y+Math.sin(angle)*len;
*/
}
// ========================================================== //
private function drawLine(p1:Particle, p2:Particle):void
{
canvas.graphics.lineStyle(1,0x000000);
canvas.graphics.moveTo(p1.x,p1.y);
canvas.graphics.lineTo(p2.x, p2.y);
}
// ========================================================== //
}
}
// ****************************************************************** //
// ***** [ Particle Class ] ***************************************** //
// ****************************************************************** //
import flash.display.Sprite;
import flash.events.Event;
internal class Particle extends Sprite
{
private var old_x:Number;
private var old_y:Number;
private var grav:Number = 5;
// ========================================================== //
public function Particle(_x:int, _y:int):void
{
x = _x;
y = _y;
old_x = _x;
old_y = _y;
addChild(drawCircle());
addEventListener(Event.ENTER_FRAME, ptGrav);
}
// ========================================================== //
private function ptGrav(event:Event):void
{
var dx:Number = (x - old_x);
var dy:Number = (y - old_y) + grav;
old_x = x;
old_y = y;
x += dx/1.3;
y += dy/1.3;
}
// ========================================================== //
static function drawCircle():Sprite
{
var circle:Sprite = new Sprite();
circle.graphics.lineStyle(1, 0x000000);
circle.graphics.beginFill(0xFFD22B);
circle.graphics.drawCircle(0,0,5);
circle.graphics.endFill();
return circle;
}
// ========================================================== //
}
Метод "ptGrav" в классе "Particles" реализует "интеграцию Верлета". (код можно тупо вставить как документ-класс, и спкомпилить=)) Так же в зипе приложил этот же код в *.as файле. Всем спасибо за внимание! Последний раз редактировалось Crash512; 18.09.2008 в 00:19. |
|
|||||
|
Попробуй так:
private function ptGrav(event:Event):void
{
var dx:Number = (x - old_x);
var dy:Number = (y - old_y) + grav;
old_x = x;
old_y = y;
x += dx/1.2;
y += dy/1.2;
}
Сам не знаю почему, но эта штука мне понравилась ![]() Последний раз редактировалось E-mail; 17.09.2008 в 23:32. |
|
|||||
|
Спасибо!=)) Первый вопрос решён... Сам не догадался, всё ж просто=)) (В коде первого поста поправил)
А как быть с угловыми ограничениями?.. Я слышал, вроде как это называется инверсной кинематикой... Последний раз редактировалось Crash512; 17.09.2008 в 23:39. |
|
|||||
|
Можно задействовать 2-й метод и ввести ограничение на углы:
angle = Math.atan2(dy, dx);
if (angle > 3*Math.PI/4)
{
angle = 3*Math.PI/4;
} else if (angle < Math.PI/4)
{
angle = Math.PI/4;
}
p2.x = p1.x+Math.cos(angle)*len;
p2.y = p1.y+Math.sin(angle)*len;
Хотя мне кажется это не то, т.к. углы будут не относительными |
|
|||||
|
Регистрация: May 2003
Адрес: Tallinn
Сообщений: 3,182
|
с какой целью пишете? если для саморазвития, то ок, если же для создания проекта, где необходимо использовать ragdoll, то советую изпользовать бесплатные библиотеки...самая удачная (на мой взгляд) www.box2d.com
|
|
|||||
|
Для саморазвития, и для себя=) Бокс2Д крут, но я не хочу юзать чужие библиотеки... Объясните, плиз, про силу тяжести для частиц...
Я обновил исходник, если кто уже старый качал... Последний раз редактировалось Crash512; 18.09.2008 в 17:05. |
|
|||||
|
Цитата:
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Регистрация: Jun 2007
Сообщений: 374
|
Psycho Tiger, там для флэша тоже есть
|
|
|||||
|
Psycho Tiger, у Box2D есть AS3.0 port...
Ребяты! Плиз, не засоряйте эфир... Хочется всё-таки по теме что-нибудь услышать... |
|
|||||
|
Регистрация: Feb 2008
Сообщений: 111
|
Погугли статью Position based dynamics, там все есть.
А вообще рагдолы надо делать не Верлетом, а через LCP |
![]() |
![]() |
Часовой пояс GMT +4, время: 14:53. |
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | |
| Опции просмотра | |
|
|