Создание игры “Набей мяч” box2d
Я думаю каждый играл на iPnone-е в такую игру. Нажимаешь “начать игру” появился стадион и мяч. Цель – набить как можно больше раз. Игра довольно весёлая, особенно если играть с друзьями, выходит такое небольшое соревнование. Еще один плюс, я не нашел ни одного туториала этой игры(возможно плохо искал). Тем не менее всё уже готово.
Автор: Notion-flash
Источник: https://flash-master.net/archives/162
В предыдущем уроке мы рассмотрели основы движка box2d. А сегодня попробуем что то простенькое создать. Надеюсь вы читали мой урок /flashlearn/flatexttutorials/1934-httpflash-masternetarchives31.html.
Прежде всего хочу сказать, что вы должны понимать основы box2d(или тут) и применения сил. Поскольку отдельный урок я еще не успел написать(разница между ApplyForce(), ApplyImpulse(), SetLinearVelocity()), в двух словах розкажу суть. В общем ApplyForce это сила тяжести(неважно в какую сторону – вниз, вверх, вправо, влево). В свою очередь ApplyImpulse являет собой грубую силу(например вы ударили мяч, значит вы применили Импульс на мяч). И на последок SetLinearVelocity – это просто “прыжок”, тут нет никакой гравитации(просто вверх, или в сторону). Не слишком детально это все описал, но суть, надеюсь, понятна.
Ок, приступим! Сначала создаем новый документ Flash, проект FD и класс, примером Main, который мы назначим документ-классом и сразу же подключаем саму библиотеку
- Во флеше: нажимаем Ctrl+Shift+F12, вкладка Flash, кнопка “Подробности”, в новом окошке укажите путь к папке “Box2d”
- Тоже самое проделываем и в FlashDevelop(Project, Propeties, Classpaths)
Теперь мы готовы начать. Сразу же создаем переменную _world типа b2World, слушатель ENTER_FRAME и DebugDraw. В общем у меня получилось что то в этом духе:
package net { import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2DebugDraw; import Box2D.Dynamics.b2World; import net.build.Constants; /** * ... * @author Notion-flash */ public class Main extends MovieClip { public static var _world:b2World = new b2World(new b2Vec2(0, 25), true); public function Main() { debugDraw() addEventListener(Event.ENTER_FRAME, update) } private function update(e:Event):void { _world.Step(1 / Constants.METR, 10, 10) _world.ClearForces() _world.DrawDebugData() } private function debugDraw():void { var drawThis:b2DebugDraw = new b2DebugDraw(); var spriteToDraw:Sprite = new Sprite(); addChild(spriteToDraw); drawThis.SetSprite(spriteToDraw); drawThis.SetFlags(b2DebugDraw.e_shapeBit); drawThis.SetDrawScale(Constants.METR); drawThis.SetAlpha(0.4); drawThis.SetLineThickness(1); _world.SetDebugDraw(drawThis); } } }
Если вам это непонятно, читаем этот урок!
Забыл сказать что я создал еще один класс – Constants. Собственно вот он:
package net.build { /** * ... * @author Notion-flash */ public class Constants { static public const METR:int = 30; } }
Константой METR я перевожу пиксели в метры. Для тех кто забыл: 1 метр = 30 пикс. Дальше нам предстоит создать стены, что бы мяч не вылетал за пределы сцены. Для этого я опять же создал новый класс, чисто для удобности. Назвал я его BoxCreator.as, и находится он в пакете build (к стати, как вы могли заметить, что Constants тоже в этом же пакете). Вот этот класс:
package net.build { import Box2D.Collision.Shapes.b2PolygonShape; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2FixtureDef; import flash.display.DisplayObjectContainer; import flash.display.MovieClip; import flash.display.Stage; import net.Main; /** * ... * @author Notion-flash */ public class BoxCreator extends MovieClip { public function boxCreator(px:Number, yp:Number, h:Number, w:Number, rot:Number, dinamicBox:Boolean):b2Body { var box:b2Body; var boxDef:b2BodyDef; var boxShapeDef:b2PolygonShape; var boxFixture:b2FixtureDef; boxDef = new b2BodyDef(); boxDef.position.Set(px / Constants.METR, yp / Constants.METR); boxDef.angle = rot * Math.PI / 180; if (dinamicBox) { boxDef.type = b2Body.b2_dynamicBody; } else { boxDef.type = b2Body.b2_staticBody; } boxShapeDef = new b2PolygonShape(); boxShapeDef.SetAsBox((w / 2) / Constants.METR, (h / 2) / Constants.METR); boxFixture = new b2FixtureDef(); boxFixture.shape = boxShapeDef; boxFixture.density = 0.5; boxFixture.friction = 0.5; boxFixture.restitution = 0.4; box = Main._world.CreateBody(boxDef); box.CreateFixture(boxFixture); return box; } } }
В этот класс мы будем передавать такие параметры, как: позиция по оси ОХ и ОУ, ширина и высота, угол поворота и определять, будет ли наше тело динамическим(я описал все параметры по порядку). По сути, об этом классе я ничего больше сказать и не могу, так как он довольно простой.
После создания чудесного класса, который будет добавлять новые тела, сразу же давайте создадим пол, стены и потолок. Навожу пример кода, как это реализовал я:
_boxCreator.boxCreator(550 / 2, 400, 20, 550, 0, false) //пол _boxCreator.boxCreator(550 / 2, 0, 20, 550, 0, false) //потолок _boxCreator.boxCreator(0, 200, 400, 20, 0, false) //стена слева _boxCreator.boxCreator(550, 200, 400, 20, 0, false) //стена справа
Протестируйте ролик, у вас должно получится что то такое:
Ок, стены есть. Сейчас нам предстоит создать мяч, то есть круг. Это мы сделаем очень просто, а точнее: создадим новый класс Ball.as и добавим туда круг. Навожу пример кода:
package net { import Box2D.Collision.Shapes.b2CircleShape; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef; import Box2D.Dynamics.b2FixtureDef; import flash.display.MovieClip; import net.build.Constants; /** * ... * @author Notion-flash */ public class Ball { public static function circleCreator():b2Body { var circle:b2Body; var circleDef:b2BodyDef; var circleShapeDef:b2CircleShape; var circleFixture:b2FixtureDef; circleDef = new b2BodyDef(); circleDef.position.Set(250 / Constants.METR, 200 / Constants.METR); circleDef.type = b2Body.b2_dynamicBody; circleShapeDef = new b2CircleShape(20/Constants.METR); circleFixture = new b2FixtureDef(); circleFixture.shape = circleShapeDef; circleFixture.density = 0.5; circleFixture.friction = 0.8; circle = Main._world.CreateBody(circleDef); circle.CreateFixture(circleFixture); return circle; } } }
Вот сейчас хочу сказать несколько слов о создании тела – круг. Ка можно заметить, точнее сразнить:
boxDef = new b2BodyDef(); boxDef.position.Set(px / Constants.METR, yp / Constants.METR);
-------
circleShapeDef = new b2CircleShape(20/Constants.METR);
Для создания круга использовать b2BodyDef - нельзя! В свою очередь мы будем юзать b2CircleShape. В данные экземпляр класса нам нужно передавать радиус(обратите внимание, что радиус – это половина ширины). Если нужно создать круг 40 на 40, на следует написать b2CircleShape(20/Constants.METR).После написания этого класса, нужно добавить мяч(круг) в мир. Но перед этим я создам новую переменную типа b2Body и назову её, например – ball. Таким образом навожу полный код главного класса Main.as:
package net { import Box2D.Common.Math.b2Vec2; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2DebugDraw; import Box2D.Dynamics.b2World; import flash.display.Sprite; import flash.events.Event; import net.build.BoxCreator; import net.build.Constants; /** * ... * @author Notion-flash */ public class Main extends MovieClip { public static var _world:b2World = new b2World(new b2Vec2(0, 25), true); private var _boxCreator:BoxCreator = new BoxCreator(); static public var ball:b2Body; public function Main() { //тестовая отрисовка debugDraw() //метод-создатель, для удобности createMe() //фрейм addEventListener(Event.ENTER_FRAME, update) } private function createMe():void { //присваеваем тело переменной(должны же мы както обращатся к нему) ball = Ball.circleCreator(); //стены _boxCreator.boxCreator(550 / 2, 400, 20, 550, 0, false) _boxCreator.boxCreator(550 / 2, 0, 20, 550, 0, false) _boxCreator.boxCreator(0, 200, 400, 20, 0, false) _boxCreator.boxCreator(550, 200, 400, 20, 0, false) } private function update(e:Event):void { _world.Step(1 / Constants.METR, 10, 10) _world.ClearForces() _world.DrawDebugData() } private function debugDraw():void { var drawThis:b2DebugDraw = new b2DebugDraw(); var spriteToDraw:Sprite = new Sprite(); addChild(spriteToDraw); drawThis.SetSprite(spriteToDraw); drawThis.SetFlags(b2DebugDraw.e_shapeBit); drawThis.SetDrawScale(Constants.METR); drawThis.SetAlpha(0.4); drawThis.SetLineThickness(1); _world.SetDebugDraw(drawThis); } } }
Основная работа сделана, а именно: мы создали весь каркас игры, то есть все стены и мы добавили в мир мяч! В следующем уроки мы добавим возможность кликать по мячу и он будет подпрыгивать.
Скачать исходник:
На этом всё, с вами был Notion-flash и удачи.
Регистрация: 8.05.2011
Публикаций: 0
Комментариев: 32
QuickBox2В мне больше нравится, там такую штуку можно сделать 2-умя строчками
А подпрыгивание 4-мя строчками