Очень часто в играх необходимо реализовать так называемую - камеру. Камера фокусируется на главном герое, и при перемещении главного героя он остается по центру игрового экрана, а весь мир передвигается относительно героя.
В Nape при Debug отрисовке можно использовать при обновлении экрана:
Таким образом мы получаем смещенную отрисовку относительно координат hero, который всегда находится по центру экрана.
Модифицируем наш пример с машинкой:
В примере пространство Nape увеличено, чтобы можно было посмотреть работу камеры. Управление машинкой: вверх/вниз - увеличение/уменьшение скорости, влево/вправо - кувырки.
Поиграть можно тут
camera_x = hero.position.x - stage.width/2; camera_y = hero.position.y - stage.height/2; debug.transform = Mat23.translation( -camera_x, -camera_y);
Таким образом мы получаем смещенную отрисовку относительно координат hero, который всегда находится по центру экрана.
Модифицируем наш пример с машинкой:
package { import flash.display.Sprite; import flash.display.DisplayObject; import flash.events.Event; import flash.events.KeyboardEvent; //клавиатурные события import nape.callbacks.BodyCallback; import nape.constraint.DistanceJoint; import nape.phys.Compound; import nape.phys.Material; import nape.callbacks.CbType; import nape.callbacks.CbEvent; import nape.callbacks.BodyListener; import nape.geom.Vec2; import nape.phys.Body; import nape.phys.BodyType; import nape.shape.Circle; import nape.shape.Polygon; import nape.space.Space; import nape.util.BitmapDebug; import nape.util.Debug; import nape.shape.Shape; import nape.geom.Mat23; public class Main extends Sprite { private var space:Space; private var debug:Debug; private var wheel_front:Body; private var wheel_rear:Body; private var cabin:Body; //Ограничение для колес private var wheel_f_joint:DistanceJoint; private var wheel_r_joint:DistanceJoint; private var cabin_front_joint:DistanceJoint; private var cabin_rear_joint:DistanceJoint; // Объединения private var car:Compound; // Обратные вызовы private var cbCarType:CbType; //Камера private var camera_x:Number = 0; private var camera_y:Number = 0; //Кузов [Embed(source="../assets/cabin.png")] private var Cabin:Class; //Колеса [Embed(source="../assets/wheel.png")] private var Wheel:Class; public function Main():void { super(); if (stage != null) { initialise(null); } else { addEventListener(Event.ADDED_TO_STAGE, initialise); } } private function initialise(ev:Event):void { if (ev != null) { removeEventListener(Event.ADDED_TO_STAGE, initialise); } var gravity:Vec2 = Vec2.weak(0, 400); space = new Space(gravity); debug = new BitmapDebug(stage.stageWidth, stage.stageHeight, stage.color); //Рисуем Ограничения debug.drawConstraints = true; addChild(debug.display); setUp(); // Обработчик клавиатуры stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler); stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler); } private function setUp():void { var w:int = stage.stageWidth; var h:int = stage.stageHeight; //Устанавливаем границы мира var border:Body = new Body(BodyType.STATIC); border.shapes.add(new Polygon(Polygon.rect(0, 0, w*4, -1))); border.shapes.add(new Polygon(Polygon.rect(0, h*3, w*4, 1))); border.shapes.add(new Polygon(Polygon.rect(0, 0, -1, h*3))); border.shapes.add(new Polygon(Polygon.rect(w*4, 0, 1, h*3))); border.space = space; // Статическая земля var floor:Body = new Body(BodyType.STATIC); floor.shapes.add(new Polygon(Polygon.regular(220, 100, 6, 0, false), Material.rubber())); floor.position.setxy(1420, 1800); floor.space = space; // Объединение - машина car = new Compound(); // Колесо переднее wheel_front = new Body(BodyType.DYNAMIC); wheel_front.position.setxy(290, 106); var wheel_frontShape:Shape = new Circle(28, null, Material.rubber()); wheel_frontShape.body = wheel_front; //wheel_front.angularVel = 20; wheel_front.compound = car; // Колесо заднее wheel_rear = new Body(BodyType.DYNAMIC); wheel_rear.position.setxy(200, 106); var wheel_rearShape:Shape = new Circle(28, null, Material.rubber()); wheel_rearShape.body = wheel_rear; //wheel_rear.angularVel = 20; wheel_rear.compound = car; // Кузов var cabinIso:BitmapDataIso = new BitmapDataIso((new Cabin()).bitmapData, 0x80); cabin = IsoBody.run(cabinIso, cabinIso.bounds); cabin.mass = 10; cabin.position.setxy(245, 70); cabin.compound = car; //Ограничение для колес (держит межколесное расстояние) wheel_f_joint = new DistanceJoint(wheel_front, cabin, wheel_front.localCOM, cabin.localCOM, 88, 88); wheel_f_joint.compound = car; wheel_r_joint = new DistanceJoint(wheel_rear, cabin, wheel_rear.localCOM, cabin.localCOM, 80, 80); wheel_r_joint.compound = car; //Передний амортизатор cabin_front_joint = new DistanceJoint(wheel_front, cabin, wheel_front.localCOM, cabin.worldPointToLocal(Vec2.weak(cabin.position.x + 70, cabin.position.y)), 52, 55); cabin_front_joint.compound = car; //Задний амортизатор cabin_rear_joint = new DistanceJoint(wheel_rear, cabin, wheel_rear.localCOM, cabin.worldPointToLocal(Vec2.weak(cabin.position.x - 62, cabin.position.y)), 52, 55); cabin_rear_joint.compound = car; //Выводим машинку со всеми ограничениями car.space = space; //Обратный вызов для переднего колеса cbCarType = new CbType(); wheel_front.cbTypes.add(cbCarType); wheel_front.space.listeners.add(new BodyListener(CbEvent.SLEEP, cbCarType, carSleepHandler)); } private function carSleepHandler(cb:BodyCallback):void { //Как только засыпает - едем! var impulse:Vec2 = Vec2.get(10, 0); impulse.length = 3200; cabin.applyImpulse(impulse); } private function enterFrameHandler(ev:Event):void { space.step(1 / stage.frameRate); //Фокус на машину, центрируем camera_x = cabin.position.x - stage.width/2; camera_y = cabin.position.y - stage.height/2; debug.clear(); debug.transform = Mat23.translation( -camera_x, -camera_y); debug.draw(space); debug.flush(); } private function keyDownHandler(e:KeyboardEvent):void { if (e.keyCode == 37) { // влево car.rotate(wheel_rear.worldCOM, -0.5); } if (e.keyCode == 39) { // вправо car.rotate(wheel_front.worldCOM, 0.5); } if (e.keyCode == 40) { // вниз wheel_front.angularVel -= 3; wheel_rear.angularVel -= 3; if ((wheel_front.angularVel < -30) || (wheel_rear.angularVel < -30)) { wheel_front.angularVel = -30; wheel_rear.angularVel = -30; } } if (e.keyCode == 38) { // вверх wheel_front.angularVel += 3; wheel_rear.angularVel += 3; if ((wheel_front.angularVel > 30) || (wheel_rear.angularVel > 30)) { wheel_front.angularVel = 30; wheel_rear.angularVel = 30; } } } } }
В примере пространство Nape увеличено, чтобы можно было посмотреть работу камеры. Управление машинкой: вверх/вниз - увеличение/уменьшение скорости, влево/вправо - кувырки.
Поиграть можно тут
Комментариев нет:
Отправить комментарий