Создание игры “Набей мяч” box2d

Content on this page requires a newer version of Adobe Flash Player.

Информация
Автор/переводчик: 
Notion-flash
Описание: 

Я думаю каждый играл на iPnone-е в такую игру. Нажимаешь "начать игру" появился стадион и мяч. Цель - набить как можно больше раз. Игра довольно весёлая, особенно если играть с друзьями, выходит такое небольшое соревнование. Еще один плюс, я не нашел ни одного туториала этой игры(возможно плохо искал). Тем не менее всё уже готово.

В предыдущем уроке мы рассмотрели основы движка 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);
}
}

}

Основная работа сделана, а именно: мы создали весь каркас игры, то есть все стены и мы добавили в мир мяч! В следующем уроки мы добавим возможность кликать по мячу и он будет подпрыгивать.

То, что должно получиться - вы видели вверху.

Исходник: 

Создайте свою первую игру во Flash!

Box2D позволяет людям с небольшим опытом или недостаточными математическими знаниями программирования начать делать вещи, которые раньше они сделать не могли.

C помощью этого курса вы сможете программироавть физические взаимодействия, например столкновения двух объектов, а так же научитесь создавать игровой мир и игровых персонажей.

Уже в ближайшее время, после изучения курса и тренировки вы сможете создать свою первую flash игру-платформер, и чем чёрт не шутит - продать её!

Создайте свою первую игру прямо сейчас!

Комментарии

Аватар пользователя VittyRude

QuickBox2В мне больше нравится, там такую штуку можно сделать 2-умя строчками 

smile

 

А подпрыгивание 4-мя строчками 

smile

Аватар пользователя Notion

Не забывайте, что QuickBox2D это всего лишь набор команд библиотеки Box2D и возможности ваши ограничены(я имею ввиду чистое использование).