Создание Куколок.
В этом Уроке я покажу, как я создаю ragdoll'ы
для своих игр С множественным числом я погорячился — для своей игры Необходимо:
Adobe Flash Studio (у меня CS4) — Для рисования.
Flash Develop + haxe — Для программирования.
Nape — физический двиг.
Как настраивать проект и где брать — не скажу.
Ибо я показываю метод, а не детальное руководство.
Хочется верить, что я программист (
Хотя иногда приходиться открывать штуки для рисования.
ИДЕ у меня появилось не давно — осваивать его решил.
Идея такая не задавать кодом структуру
человечка, а определить функцию, которая считывает
клип с его частями.
Этап 1: Рисование куколок
К сожалению, что во мне спит художник — я точно не верю)
Разбудить мне его не удалось, поэтому не буду
показывать как я рисовал, только результат.
Рисуем части тела по отдельности.
Вот что у меня вышло — ужас):
Теперь конвертируем части тела в клипы:
Я сделал так:
Также, как видно, я добавил еще один символ
— маленький круг — joint
это крепления для частей.
Создаем новый символ ragdoll
и распологаем по местам все наши части,
там где должны быть соединения ставим joint:
И важно, не забыть, прописать всем символам
имена(instance Name).Я написал такие же, как и названия символов.
А Соединениям нужно писать, если голова- join_head, рука — joint_hand_left и тп.
Теперь в свойствах Символа разрешаем ему Экспортироваться
С именем CRagdoll (С большой буквы, ибо Хакс не понимает классы с маленькой)
Все теперь можно нажать Shift+F12 или Publish
Рисование кончалось)
Начинаем прогать.
Этап 2: Куколка живи
Создаем новый хакс проект во ФлещДевелоп
В проекте создаем папку lib
в нее добавим наш ragdoll.swf
Надеюсь нап вы сами скачаете.
У Луки какие-то проблемы с версией под хакс, так что качать лучше код.
Теперь к проекту подключаем библиотеку
Нажать на проект — добавить (Add) — Libraly Asset выбираем наш файл ragdoll.swf
Утомился я писать)
Исходники прикреплю.
Описывать весь процесс не стану — слишком долго, кода вышло много)
опишу методы: createBoxBySprite — Создает Тело с прикрепленным к нему спрайтом. createBoxByChild — создает тело по имени ребенка у спрайта createPivotJoint — создает точечное соединение createPivotJointByChild — по имени чайлда createRotaryLimitJoint — создает соединение, ограничивающее углы createRagdollBySprite — главная наша функция создает регдольчик
Да, много функций для урока) но они потом пригодятся, к примеру для
объектов уровня и тп
Плюс этого метода.
Что теперь художник может нарисовать персонажа
— любого роста и телосложения, а нам — программерам — пофиг)
Что вышло — смотреть ниже (флешку сюда вставить нельзя?, сейчас залью куда-нибудь)
кликаем на экран появляется куколка)
мой нет-бук держит порядка 20 тел, но злоупотреблять не стоит… Архив с исходником и медией: или Смотреть:
Не уверер, что кто-то смотрел код на haxe), а я старался. Так, что показываю здесь
package ;
import flash.Lib;
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.geom.Point;
import flash.events.Event;
import flash.events.MouseEvent;
import nape.geom.Vec2;
import nape.geom.AABB;
import nape.space.Space;
import nape.space.UniformSleepSpace;
import nape.phys.Body;
import nape.phys.PhysObj;
import nape.phys.Material;
import nape.util.Tools;
import nape.constraint.PivotJoint;
import nape.constraint.RotaryLimitJoint;
class Main extends Sprite
{
static function main()
{
var main:Main = new Main();
Lib.current.addChild(main);
}
static private var GRAVITY:Vec2 = new Vec2(0, 250);
static private var DELTA:Float = 0.016;
static private var WIDTH:Int = 640;
static private var HEIGHT:Int = 480;
static private var WIDTH_H2:Int =320;
static private var HEIGHT_H2:Int = 240;
private var space:Space;
public function new()
{
super();
space = new UniformSleepSpace(new AABB(0, 0, WIDTH, HEIGHT), 30, GRAVITY); //Физика
createBorder(); //Границы мира
this.graphics.beginFill(0x901010);
this.graphics.drawRect(0, 0, WIDTH, HEIGHT);
this.graphics.endFill();
addEventListener(Event.ENTER_FRAME, update); // Обновить мир
addEventListener(MouseEvent.CLICK, click);
}
private function click(e:Event):Void
{
//куколки
createRagdollBySprite(space, this, new Vec2(mouseX, mouseY), new CRagdoll(),(Math.random()>0.9 ? true : false));
}
private function update(e:Event):Void
{
space.step(DELTA);
}
private function createBorder():Void
{
var p:PhysObj;
space.addObject(p = Tools.createBox(-20, HEIGHT_H2, 50, HEIGHT, 0, 0, 0, true, Material.Wood));
addChild(p.graphic);
space.addObject(p = Tools.createBox(WIDTH +20, HEIGHT_H2, 50, HEIGHT, 0, 0, 0, true, Material.Wood));
addChild(p.graphic);
space.addObject(p = Tools.createBox(WIDTH_H2, -20, WIDTH, 50, 0, 0, 0, true, Material.Wood));
addChild(p.graphic);
space.addObject(p = Tools.createBox(WIDTH_H2, HEIGHT + 20, WIDTH, 50, 0, 0, 0, true, Material.Wood));
addChild(p.graphic);
}
//вспомогательные функции для работы с физикой
static private var G2R:Float = 0.017453292519; // Math.PI / 180;
static private var R2G:Float = 57.295779514719; // 180 / Math.PI;
static public inline function createBoxBySprite(space:Space,render:Sprite, pos:Vec2, sprite:Sprite,material:Material, isStatic:Bool, ?data:Dynamic,?collision=0xffffffff):PhysObj
{
if (sprite!=null)
{
var pobj:PhysObj;
pobj = Tools.createBox(0, 0, sprite.width , sprite.height , 0, 0, 0, isStatic, material,collision);
pobj.setPos(pos.px + sprite.x, pos.py + sprite.y, G2R * sprite.rotation);
pobj.assignGraphic(sprite);
pobj.data = data;
if(isStatic) pobj.body.stopAll();
pobj.body.update();
space.addObject(pobj);
render.addChild(pobj.graphic);
return pobj;
}
else return null;
}
static public inline function createBoxByChild(space:Space, render:Sprite, pos:Vec2, parent:Sprite, name:String, material:Material, isStatic:Bool, ?data:Dynamic,?collision=0xffffffff):PhysObj
{
var child:DisplayObject = parent.getChildByName(name);
if (child!=null)
{
var point:Point = child.localToGlobal(new Point());
// parent.removeChild(point);
child.x = point.x-parent.x;
child.y = point.y-parent.y;
child.rotation = parent.rotation;
return createBoxBySprite(space, render, pos, cast(child,Sprite), material, isStatic, data,collision);
}
else return null;
}
static public inline function createPivotJointByChild(space:Space,body1:PhysObj,body2:PhysObj, pos:Vec2,breakable:Bool,maxForce:Float, parent:Sprite,name:String):PivotJoint
{
var child:DisplayObject = parent.getChildByName(name);
if (child!=null)
{
var sumPos:Vec2 = pos.clone();
sumPos.px += child.x;
sumPos.py += child.y;
return createPivotJoint(space, body1, body2, sumPos,breakable,maxForce);
}
else return null;
}
static public inline function createPivotJoint(space:Space, obj1:PhysObj, obj2:PhysObj, pos:Vec2, ?breakable:Bool=false, ?maxForce:Float=1600000):PivotJoint
{
if (obj1 == null || obj2 == null) return null;
else
{
var p:PivotJoint = new PivotJoint(obj1, obj2, pos);
p.breakable = breakable;
if (breakable) p.maxForce = maxForce;
p.biasCoef = 0.5;
p.ignore = true;
space.addConstraint(p);
return p;
}
}
static public inline function createRotaryLimitJoint(space:Space, obj1:PhysObj, obj2:PhysObj, min:Float, max:Float,?breakable:Bool=false,?maxForce:Float=2000000):RotaryLimitJoint
{
if (obj1 == null || obj2 == null) return null;
else
{
var p:RotaryLimitJoint = new RotaryLimitJoint(obj1, obj2, min, max);
p.breakable = breakable;
if (breakable) p.maxForce = maxForce;
p.biasCoef = 0.5;
p.ignore = true;
space.addConstraint(p);
return p;
}
}
static public inline function createRagdollBySprite(space:Space, render:Sprite,pos:Vec2, sprite:Sprite, ?isbreak:Bool=false):Void
{
var head:PhysObj;
var body:PhysObj;
var leftfoot:PhysObj;
var rightfoot:PhysObj;
var lefthand:PhysObj;
var righthand:PhysObj;
var material:Material = Material.Wood;
// # bodyes
leftfoot = createBoxByChild(space, render, pos, sprite, 'foot_left', material,false,null,1);
rightfoot = createBoxByChild(space, render, pos, sprite, 'foot_right',material,false,null,2);
body = createBoxByChild(space, render, pos, sprite, 'body', material,false,null,4);
head = createBoxByChild(space, render, pos, sprite, 'head', material,false,null,8);
lefthand = createBoxByChild(space, render, pos, sprite, 'hand_left', material,false,null,16);
righthand = createBoxByChild(space, render, pos, sprite, 'hand_right',material,false,null,32);
// # pivot joints
createPivotJointByChild(space, head, body, pos, isbreak, 1600000, sprite, 'joint_head');
createPivotJointByChild(space, lefthand, body, pos, isbreak, 1600000, sprite, 'joint_hand_left');
createPivotJointByChild(space, righthand, body, pos, isbreak, 1600000, sprite, 'joint_hand_right');
createPivotJointByChild(space, leftfoot, body, pos, isbreak, 1600000, sprite, 'joint_foot_left');
createPivotJointByChild(space, rightfoot, body, pos, isbreak, 1600000, sprite, 'joint_foot_right');
// # rotary limits
createRotaryLimitJoint(space, lefthand, body, -0.45, 0.45, isbreak);
createRotaryLimitJoint(space, head, body, -0.45, 0.45, isbreak);
createRotaryLimitJoint(space, righthand,body, -0.45, 0.45, isbreak);
createRotaryLimitJoint(space, leftfoot, body, -0.25, 0.25, isbreak);
createRotaryLimitJoint(space, rightfoot,body, -0.25, 0.25, isbreak);
}
}
угу и я про то) в напе его тоже удальть можно))
Я же писал про.
к примеру, регдол сильно ударить или упал с большой высоты — конечность то сама оторвется — это удобненько)
Угу, шустрый.
Там сейчас, к примеру, несколько куколок коллизится так
голова с голвой
туловище с туловищем
нога с ного и тп)
Я так сделал в свойе игре… забыл убрать
Привет, интересно.
Тоже публикуй.
Я же, не сравнивал с боксом.
Я хотел показать, как я беру части из нарисованного sprit'а
и у меня код на хаксе.
а зачем ты спрайт, каждый раз двигаешь, ведь в Напе
нужно просто ФизическиеОбъект.assignGraphics… — это удобней.
ну и так есть замечания) публикуй в комментах напишу.
Не думаю, но плюсы, действительно есть.
Хотя я вот уже планирую вернуться или на ас3 или попробовать, что-то еще.
Хакс — хорош, но нет никаких движух в коммуните, да и коммунити очень маленькое.
Сейчас он как морская свинка — и плавает плохо, и скушать мало) имхо.
Разницу в скорости при обычном использовании ты вряд ли заметишь. Ну, генерит он чуть более оптимизированный байткод, ну и что. В итоге всё равно тот же флеш. Но как ЯП для меня хакс более удобный, чем as3.
Ему скорее нехватает актуальной IDE (в том числе под OSX), способ без хитрых манипуляций подключать AS3-код, проектов, написанных на нём и комьюннити, активно его юзающего.
Как минимум стоит его попробовать. Мне понравилось.
Если УГ это то что я думаю)
то полностью согласен…
какое-то время сидел в линуксе с эклипсом и флешбилдером.
привыкнуть смог)
и вроде все есть и побольшей части работает, но не так как-то оно — не то…
кстати, да, было бы круто, если можно было бы нормально вставлять ас3-код...))
Так зайдите на форум, он специально для этого. Зачем делать исключения, если можно зашариться на форум (раз время и желание есть пообсуждать что-то эдакое...}
ну хоть что-нибудь расскажи, реально интересно же, и я уверен не только мне :)
А автору цитаты анреспет — какая разница сколько игр сделано, главное чтобы...}
ну обман скорее психологический :) скачивая Angry Birds за бесплатно — ты ожидаешь полную версию Angry Birds (просто тебе повезло и игра сегодня бесплатная :) такое ...}
На 50 коментов ни одного с критикой.
Генератор уровней по-моему сыроват, из-за этого игра местами хардкорная:
Трамплин иногда запускает игрока прямиком ...}
Нет возможности читать вам лекции, тематических книг очень много. Вкратце.
Предсказания будущего — это громко сказано. На 90% (допустим) все события в бу...}
Комментарии (22)
RSS свернуть / развернутьSmrdis
по ссылки с исходниками?
может с фолдора
horror812
zarkua
zarkua
abyss
у одного из 10…
эта я показать, что в напе легко сделать разрушаемые лжойтны,
пс тоя я и не поню может в боксе также (
horror812
elmortem
Там если джойн сильно натянуть (в зависимости от параметров)
— он порвется.
А в боксе не помню, есть ли такое)
horror812
elmortem
Я же писал про.
к примеру, регдол сильно ударить или упал с большой высоты — конечность то сама оторвется — это удобненько)
horror812
elmortem
Я заполнил весь экран рэгдоллами, а он даже подтормаживать не начал!
MidnightOne
Там сейчас, к примеру, несколько куколок коллизится так
голова с голвой
туловище с туловищем
нога с ного и тп)
Я так сделал в свойе игре… забыл убрать
horror812
спасибо и +1!
flashco
Хотя вот моя старая статья… может пригодится комунибудь…
solver
Тоже публикуй.
Я же, не сравнивал с боксом.
Я хотел показать, как я беру части из нарисованного sprit'а
и у меня код на хаксе.
а зачем ты спрайт, каждый раз двигаешь, ведь в Напе
нужно просто ФизическиеОбъект.assignGraphics… — это удобней.
ну и так есть замечания) публикуй в комментах напишу.
horror812
ТОварищи, а что хакс вот прям такой весь удобный, ьыстрый и крутой по-сравнению с ас3?
shaman4d
Хотя я вот уже планирую вернуться или на ас3 или попробовать, что-то еще.
Хакс — хорош, но нет никаких движух в коммуните, да и коммунити очень маленькое.
Сейчас он как морская свинка — и плавает плохо, и скушать мало) имхо.
horror812
Ему скорее нехватает актуальной IDE (в том числе под OSX), способ без хитрых манипуляций подключать AS3-код, проектов, написанных на нём и комьюннити, активно его юзающего.
Как минимум стоит его попробовать. Мне понравилось.
elmortem
dlancer
elmortem
то полностью согласен…
какое-то время сидел в линуксе с эклипсом и флешбилдером.
привыкнуть смог)
и вроде все есть и побольшей части работает, но не так как-то оно — не то…
кстати, да, было бы круто, если можно было бы нормально вставлять ас3-код...))
horror812
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.