Очень часто в играх необходимо реализовать так называемую - камеру. Камера фокусируется на главном герое, и при перемещении главного героя он остается по центру игрового экрана, а весь мир передвигается относительно героя.
В 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 увеличено, чтобы можно было посмотреть работу камеры. Управление машинкой: вверх/вниз - увеличение/уменьшение скорости, влево/вправо - кувырки.
Поиграть можно тут
Комментариев нет:
Отправить комментарий