前回に引き続き、ブロック崩しの作成について、説明していきます。
現時点では、物理オブジェクトとして設定しているものはブロック及びバーの2種類です。
その為、ボールが左右へ行っても画面外へ出てしまうので、上下左右にBox2dを設定し
ボールが画面内に留まるようにします。
グローバル変数の追加及び、init内Box2dワールドを生成した後に以下を追加します。
グローバル変数
- //画面上部の境界線
- var spr_disp_upper = null;
- //画面下部の境界線
- var spr_disp_bottom = null;
- //画面左側の境界線
- var spr_disp_left = null;
- //画面右側の境界線
- var spr_disp_right = null;
init内
- var fixDef = new b2FixtureDef;
- fixDef.density = 1.0;
- //摩擦係数
- fixDef.friction = 0;
- //反発係数
- fixDef.restitution = 1;
- var bodyDef = new b2BodyDef;
- //create ground
- bodyDef.type = b2Body.b2_staticBody;
- fixDef.shape = new b2PolygonShape;
- //上下の境界線の幅と高さ設定
- fixDef.shape.SetAsBox(320.0 / PTM_RATIO, 1 / PTM_RATIO);
- //upper
- //ダミーでsprite設定
- //表示は行わない
- //CB関数用の変数となります
- spr_disp_upper = cc.Sprite.create( “res/boll.png” );
- bodyDef.position.Set(320.0 / PTM_RATIO / 2, 380.0 / PTM_RATIO);
- bodyDef.userData = spr_disp_upper;
- world.CreateBody(bodyDef).CreateFixture(fixDef);
- //bottom
- //ダミーでsprite設定
- //表示は行わない
- //CB関数用の変数となります
- spr_disp_bottom = cc.Sprite.create( “res/boll.png” );
- bodyDef.position.Set(320.0 / PTM_RATIO / 2, -1);
- bodyDef.userData = spr_disp_bottom;
- world.CreateBody(bodyDef).CreateFixture(fixDef);
- //左右の境界線の幅と高さ設定
- fixDef.shape.SetAsBox(1 / PTM_RATIO, 380.0 / PTM_RATIO);
- //left
- //ダミーでsprite設定
- //表示は行わない
- //CB関数用の変数となります
- spr_disp_left = cc.Sprite.create( “res/boll.png” );
- bodyDef.position.Set(0, 380.0 / PTM_RATIO / 2);
- bodyDef.userData = spr_disp_left;
- world.CreateBody(bodyDef).CreateFixture(fixDef);
- //right
- //ダミーでsprite設定
- //表示は行わない
- //CB関数用の変数となります
- spr_disp_right = cc.Sprite.create( “res/boll.png” );
- bodyDef.position.Set(320.0 / PTM_RATIO, 380.0 / PTM_RATIO / 2);
- bodyDef.userData = spr_disp_right;
- world.CreateBody(bodyDef).CreateFixture(fixDef);
境界線を設定するために必要なFixtureDef、b2BodyDefのインスタンスを生成します。
摩擦係数や密度の初期化を行います。
生成したFixtureDefを使用して幅と高さをしているのが
fixDef.shape.SetAsBox(320.0 / PTM_RATIO, 1 / PTM_RATIO);
になります。
前回の記事でも説明したとおり、Box2Dの世界では長さの単位にM(メートル)を使用します。
そのため、実際に指定する幅・高さを PTM_RATIO で割る形になっています。
bodyDefインスタンスのポジションセットにより、fixtureDefで設定した境界線を設置する場所を指定します。
bodyDef.position.Set(320.0 / PTM_RATIO / 2, 380.0 / PTM_RATIO);
上記までが境界線の設定となり
実際に境界線の生成を行っているのが以下になります。
world.CreateBody(bodyDef).CreateFixture(fixDef);
それぞれの引数に「bodyDef」「fixDef」を指定することによって
先ほど設定した幅高さの境界線(※1)が指定した箇所(※2)に生成されることになります。
※1.FixtureDefにより設定
※2.BodyDefにより設定
これで、ボールが画面内に収まるようになりました。
残りは当たったブロックを消去する処理が必要になります。
上記を可能にするために、衝突イベント時リスナーを登録します。
追記する場所は、init内になります。
- var listener = new Box2D.Dynamics.b2ContactListener;
- listener.BeginContact = function (contact) {
- var contactA = contact.GetFixtureA().GetBody().GetUserData();
- var contactB = contact.GetFixtureB().GetBody().GetUserData();
- if (contactA == spr_disp_upper || contactB == spr_disp_upper) {
- //上の壁
- }
- else if (contactA == spr_disp_bottom || contactB == spr_disp_bottom) {
- //下の壁
- }
- else if (contactA == spr_disp_left || contactB == spr_disp_left) {
- //左の壁
- }
- else if (contactA == spr_disp_right || contactB == spr_disp_right) {
- //右の壁
- }
- else {
- //その他
- }
- };
- listener.EndContact = function (contact) {
- };
- world.SetContactListener(listener);
ブロック衝突時処理のため、今回はその他の部分に追記することになりますが
初めに、ブロック消去処理に必要となる変数を追加しましょう。
グローバル変数定義部に追加
- //ブロックが存在するかどうか
- var appear_block = new Array();
- //ブロックの残数
- var block_count = 0;
ブロック生成部に追加
- //ブロックが存在するかどうか
- appear_block[i * 8 + j] = true;
- block_count++;
その後、以下の処理をその他内に記載して下さい。
- for (var i = 0; i < spr_block.length; i++) {
- if (contactA == spr_block[i] || contactB == spr_block[i]) {
- layer.removeChild(spr_block[i]);
- //gamestart対処 Start
- //ブロックの数マイナス
- appear_block[i] = false;
- block_count–;
- //破壊する
- //layer.removeChild(spr_block[i]);
- setTimeout(function () {world.DestroyBody(body_block[i]);}, 1);
- break;
- }
- }
これにより、ブロック崩しとして一通りの動作が可能になりました。
しかし現在の状態では、初回の弾を発射後でもクリックをすると
ボールの物理オブジェクトが生成されてしまいます。
それを防ぐため、次の処理を追記します。
var ball_moved = false;
※グローバル変数に追加
上記変数を追加後
onTouchesEnded関数内の処理を以下のように変更します。
- if (ball_moved == false) {
- var size = cc.Director.getInstance().getWinSize();
- body_ball = this.addNewSpriteWithCoords(spr_ball, cc.p( size.width / 2 – 5, BAR_Y + BAR_HEIGHT / 2 + BALL_HEIGHT / 2 ), BALL_WIDTH, BALL_HEIGHT, true);
- var b2Vec2 = Box2D.Common.Math.b2Vec2;
- //弾の発射角度を調整 Start
- var ball_angle_work = Math.random() * 40;
- if (ball_angle_work < 20) {
- ball_angle_work = -1 * ball_angle_work – 20;
- } else {
- ball_angle_work = ball_angle_work;
- }
- ball_angle = ball_angle_work / 180;
- body_ball.SetLinearVelocity(new b2Vec2(-1 * ball_velocity * Math.sin(ball_angle), ball_velocity * Math.cos(ball_angle)));
- ball_moved = true;
- }
※上記の太字箇所を追加
以上で、本記事は終了となります。
今回の処理を追記したソースコードはこちら。
<次回以降の更新について>
次回は、プレイヤーの残機設定や速度調整等の細かな部分の修正や追加について、
引き続き説明していきます。