|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Коллизии и оптимизация кода
Господа, тема избита, вопросы обсуждались тысячи раз здесь и даже при моём участии, но вот , снова столкнулся, снова прошу помощи и это спустя почти 1.5 года, прошу подсказок и вменяемой критики, ибо знаю о своей криворукости.
Ближе к делу. Есть готовый код, работает, но не так, как хотелось бы - вина всему - проверка коллизий, проверка в циклах с тремя вложенными. Код прилагаю, надеюсь на помощь, есть ориентир, что должно выйти в итоге. Не поленитесь, пожалуйста - прочитайте код и предложите выход. Кода 250 строк. Коллизию проверяю попиксельно ибо реакция на отклик важна до миллиметра. Мой ориентир - http://flukedude.com/theimpossiblegame/?lang=ru/ тут флешка с игрой , кубик скачет У меня впрочем - то всё хорошо , но отклик на прыжок слабоват очень... Сам Код... <?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="800" height="600" frameRate="65" name="scroll" keyDown="keys(event)"> <fx:Style source="imp.css"/> <fx:Declarations> <!-- Разместить невизуальные элементы (например, службы или объекты значений) --> </fx:Declarations> <fx:Script> <![CDATA[ import mx.controls.Alert; import mx.events.FlexEvent; public var _maxHeight:Number; public var _returnValue:Boolean; public var rec:Rectangle = new Rectangle; public var i:int = 1; public var level:Array; public var jump:Boolean=false; public var jump2:Boolean=false; public var jumpcost:int=90; public var jumped:int=0; public var sx:int; public var sy:int; public var speed:int=6; public var ani:int=0; public var anim:Array = ["player1.png","player3.png","player5.png","player.png"]; public var col:Boolean = false; public function keys(event:KeyboardEvent):void { if(event.keyCode == Keyboard.R) { if((jump==false)&&(jump2==false)&&(_returnValue==true)) { jump=true; } } if(event.keyCode == Keyboard.Q) { player.source="pole.png"; } if(event.keyCode == Keyboard.W) { player.source="player.png"; } } public function onbutton(event:Event):void { base.addEventListener(Event.ENTER_FRAME, framed); } public function start(event:Event):void { rec.x=0; rec.y=0; rec.width=800; rec.height=600; level=base.getChildren(); base.focusEnabled=true; this.setFocus(); sy=player.y; sx=player.x; player.load("player.png"); level=base.getChildren(); } public function framed(event:Event):void { shader.x=player.x-107; shader1.x=player.x-137; based.scrollRect=rec; var py:int; i=level.length-1; var l:int=0; if((jump==true)||(jump2==true)) { } i=level.length-1; if((jump==true)&&(jump2==false)) { player.y=player.y-8; jumped=jumped+8; if(jumped>=jumpcost) { jump2=true; jump=false; jumped = 0; } } py=player.y; if(!jump) { player.y=player.y+5; } for(i;i>-1;i--) { complex(player,level[i]) if((_returnValue==false)&&(jumped>=jumpcost)) { jump2=true; break; } else if(_returnValue==true) { test.text="true"; player.y=py; l=0; for(l;l<5;l++) { complex(player,level[i]) if(_returnValue==false) { player.y++; break; } else { if((player.x+60>=level[i].x)&&(level[i].name!="floor")&&(player.y>=level[i].y-58)&&(level[i].name!="ice")) { player.x=sx; player.y=sy; } if((player.y>=level[i].y+level[i].height)||(level[i].name=="spike")||(level[i].name=="lava")) { player.x=sx; player.y=sy; } if(level[i].name=="ice") { speed=8; } if(level[i].name!="ice") { speed=7; } break; } } break; } } player.x=player.x+speed; rec.x=player.x-70; } public function complex(clip1:DisplayObjectContainer, clip2:DisplayObjectContainer):Boolean { var _onePoint:Point; var _twoPoint:Point; var _tp:Point; var _fp:Point; var _oneRectangle:Rectangle; var _twoRectangle:Rectangle; var _oneClipBmpData:BitmapData; var _twoClipBmpData:BitmapData; var _oneOffset:Matrix; var _twoOffset:Matrix; var _maxWidth:Number; _oneRectangle = clip2.getBounds(clip2); _twoRectangle = clip1.getBounds(clip1); _oneOffset = clip1.transform.matrix; _oneOffset.tx = clip1.x - clip2.x; _oneOffset.ty = clip1.y - clip2.y; _twoOffset = clip2.transform.matrix; _twoOffset.tx = clip2.x - clip2.x; _twoOffset.ty = clip2.y - clip2.y; _maxWidth = Math.max(_oneRectangle.width, _twoRectangle.width); _maxHeight = Math.max(_oneRectangle.height, _twoRectangle.height); _twoClipBmpData = new BitmapData(_maxWidth, _maxHeight, true, 0); _oneClipBmpData = new BitmapData(_maxWidth, _maxHeight, true, 0); _twoClipBmpData.draw(clip1, _oneOffset); _oneClipBmpData.draw(clip2, _twoOffset); _onePoint = new Point(_oneRectangle.x, _oneRectangle.y); _twoPoint = new Point(_twoRectangle.x, _twoRectangle.y); _tp = new Point(_oneRectangle.x+_oneRectangle.width, _oneRectangle.y+_oneRectangle.height); _fp = new Point(_twoRectangle.x+_twoRectangle.width, _twoRectangle.y+_twoRectangle.height); if((_oneClipBmpData.hitTest(_onePoint, 255, _twoClipBmpData, _twoPoint, 255))||(_oneClipBmpData.hitTest(_tp, 255, _twoClipBmpData, _fp, 255))) { _returnValue = true; jump=false; jumped=0; jump2=false; } else { _returnValue = false; } _twoClipBmpData.dispose(); _oneClipBmpData.dispose(); return _returnValue; } ]]> </fx:Script> <s:BorderContainer x="0" y="0" width="1500" height="600" backgroundColor="#F5FB91" contentBackgroundColor="#B4B4B4" addedToStage="start(event)" id="based"> <mx:Canvas id="base" x="0" y="0" width="8000" height="600" backgroundColor="#EAEAEA"> <mx:Canvas x="0" y="382" width="8000" height="127" backgroundColor="#878787" name="floor"> </mx:Canvas> <s:Button x="71" y="9" label="Кнопка" buttonDown="onbutton(event)"/> <s:Label x="167" y="18" id="test"/> <s:Image x="1500" y="343" width="40" height="40" scaleMode="stretch" source="spike.png" smooth="true" smoothingQuality="high" name="spike" /> <s:Image x="2200" y="343" width="40" height="40" scaleMode="stretch" source="spike.png" smooth="true" smoothingQuality="high" name="spike" /> <s:Image x="2500" y="343" width="40" height="40" scaleMode="stretch" source="spike.png" smooth="true" smoothingQuality="high" name="spike" /> <s:Image x="3000" y="343" width="40" height="40" scaleMode="stretch" source="spike.png" smooth="true" smoothingQuality="high" name="spike" /> <s:Image x="3400" y="343" width="40" height="40" scaleMode="stretch" source="spike.png" smooth="true" smoothingQuality="high" name="spike" /> <s:Image x="3440" y="343" width="40" height="40" scaleMode="stretch" source="spike.png" smooth="true" smoothingQuality="high" name="spike" /> <s:Image x="3590" y="343" width="40" height="40" scaleMode="stretch" source="spike.png" smooth="true" smoothingQuality="high" name="spike" /> <s:Image x="3820" y="320" width="40" height="40" scaleMode="stretch" source="spike1.png" smooth="true" smoothingQuality="high" name="spike" /> <s:Image x="3860" y="320" width="40" height="40" scaleMode="stretch" source="spike1.png" smooth="true" smoothingQuality="high" name="spike" /> <s:Image x="3900" y="320" width="40" height="40" scaleMode="stretch" source="spike1.png" smooth="true" smoothingQuality="high" name="spike" /> <s:Image x="4100" y="343" width="40" height="40" scaleMode="stretch" source="spike.png" smooth="true" smoothingQuality="high" name="spike" /> <s:Image x="800" y="343" width="40" height="40" scaleMode="stretch" source="cube.png" smooth="true" smoothingQuality="high"/> <s:Image x="840" y="368" width="160" height="15" scaleMode="stretch" source="lava.png" smooth="true" smoothingQuality="high" name="lava"/> <s:Image x="2240" y="377" width="260" height="15" scaleMode="stretch" source="ice.png" smooth="true" smoothingQuality="high" name="ice"/> <s:Image x="1000" y="343" width="40" height="40" scaleMode="stretch" source="cube.png" smooth="true" smoothingQuality="high"/> <s:Image x="1200" y="343" width="40" height="40" scaleMode="stretch" source="cube.png" smooth="true" smoothingQuality="high"/> <s:Image x="3820" y="263" width="40" height="40" scaleMode="stretch" source="cube.png" smooth="true" smoothingQuality="high"/> <s:Image x="3900" y="263" width="40" height="40" scaleMode="stretch" source="cube.png" smooth="true" smoothingQuality="high"/> </mx:Canvas> <s:BorderContainer id="shader" x="0" y="0" width="111" height="601" backgroundAlpha="0.5" backgroundColor="#EFEFEF" borderVisible="false" borderWeight="0"> </s:BorderContainer> <s:BorderContainer id="shader1" x="0" y="0" width="111" height="601" backgroundAlpha="0.7" backgroundColor="#EFEFEF" borderVisible="false" borderWeight="0"> </s:BorderContainer> <mx:Image id="player" x="38" y="247" width="80" height="80" /> </s:BorderContainer> </s:WindowedApplication>
__________________
...Nothing can't be coded... |
|
|||||
Регистрация: Feb 2012
Сообщений: 1,540
|
Удивительно, делать игру на флексе.
А так, мне кажется, что Вам больше подойдет какой-нибудь движок, например Nape. Так как попиксельная проверка занимает много процессорного времени. |
|
|||||
Да, флекс, да странно, но с другой стороны больше свободы - меньше твинов - хардкор...
Если вы смотрели пример - к чему я стремлюсь, то понимаете, что коллизии попиксельно просто самый подходящий выход для меня - ибо каждый пиксель важен. Я прошу подсказать варианты проверки коллизий методами быстрее этого, желательно примеры. На данный момент у меня только одна мысль - проверять коллизию только под маской прозрачной в зоне досягаемости куба. Создать маску прозрачную и через неё добавлять и удалять в массив проверки элементы дочерние спрайта base. Намного ли это уменьшит время процессорного отклика? EDIT: Есть ещё идея - просчитывать от центра куба вектор до ближайшей цели и когда длинна вектора < пол куба то коллизия true. но в таком случае, что делать с полом и насколько это рентабельно в плане ресурсоёмкости, подскажите же , гуру, я уже рыдаю.
__________________
...Nothing can't be coded... |
|
|||||
Регистрация: Feb 2012
Сообщений: 1,540
|
Цитата:
Работать будет в *очень много раз* быстрее, при этом качество будет таким же, даже лучше. Цитата:
Правда в Nape/Box2D это еще быстрее выходит. |
|
|||||
Насчёт формул тригонометрии, подскажите, в каком направлении копать. пожалуйста?
А на счёт векторов да, можно, но как узнать в случае с пирамидой в каком месте я её касаюсь? Однако вопрос... Учитывая, что пирамида - PNG файл... Подскажите алгоритм вычислений, если не трудно. И точно ли эти методы будут занимать меньше времени ибо кода будет значимо больше.
__________________
...Nothing can't be coded... |
|
|||||
Регистрация: Feb 2012
Сообщений: 1,540
|
Не выдумывайте велосипедов, используйте готовые движки, советую Nape.
А если лень разбираться - Citrus Engine. Благо Google есть. |
|
|||||
Весь интерес ведь в том, чтобы сделать самому, да и в движке я рыть буду дольше, чем в тригонометрии, не уж то никто не занимался коллизиями так плотно, все использовали движки?
EDIT: И ещё кое что, движок привертеть к FLEX... Тот ещё изврат я так полагаю, оно того стоит? =)
__________________
...Nothing can't be coded... |
|
|||||
Banned
[+4 24.02.14]
[+4 07.11.13] [+ 13.03.14] Регистрация: Mar 2013
Сообщений: 1,864
|
Цитата:
И по теме - больше кода, чаще всего и ускорят работу. И если Вы хотите лучшее - скачайте Nape, изучите его, пусть хоть несколько месяцев пройдет, а потом сядете и сделаете либо так же, либо так же. Но если Вы знаете математику, то зачем Вам это надо? |
|
|||||
В одной игре проверку делал через getPixel. Там птичка летела по туннелю. И каждый момент времени проверялось несколько точек у птички. Если в хоть одной точке туннель не прозрачен, то столкновение.
__________________
Чтобы доказать, что вы не робот, причините вред другому человеку. |
Часовой пояс GMT +4, время: 05:07. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|