Box2D Walls - тот же код: левый работает, правый - нет - PullRequest
0 голосов
/ 14 января 2010

Я делаю простую игру Box2D (http://iwanttobeacircle.com), где вы начинаете как треугольник и отскакиваете от больших фигур, чтобы получить стороны.

У меня странная ошибка с моими стенами ... обе созданы из одного класса, но левая работает, а правая - нет. Если я добавлю только правильное, то это сработает, но по какой-то причине добавление их обоих, кажется, вызывает проблемы где-то.

Класс WallSegment ниже:

    package com.carmstrong.iwanttobeacircle {

 import flash.display.DisplayObjectContainer;
 import flash.display.Sprite;
 import flash.display.Shape;
 import Box2D.Collision.Shapes.*;
 import Box2D.Dynamics.*;
 import Box2D.Common.Math.b2Vec2;

 import com.carmstrong.iwanttobeacircle.Config;

 public class WallSegment extends Actor {

  private var _shape:Sprite;
  private var _shapeBody:b2Body;
  private var _colour:uint = 0x666666;

  private var prevEdge:int;
  private var thisEdge:int;
  private var side:Number;

  private var name:String;

  private var _pathWidth:int;
  private var _parent:DisplayObjectContainer;

  public function WallSegment(Width:int, Position:String, Parent:DisplayObjectContainer) {
   name = "Wall";
   _pathWidth = Width;
   _parent = Parent;

   if(Position == "left") {
    side = 1;
    prevEdge = (Config.WIDTH - Config.PREV_WIDTH)/2;
    thisEdge = (Config.WIDTH-_pathWidth)/2;
   } else {
    side = -1;
    prevEdge = Config.WIDTH-(Config.WIDTH - Config.PREV_WIDTH)/2;
    thisEdge = Config.WIDTH-(Config.WIDTH-_pathWidth)/2;
   }// check if its left or right wall


   //Create the costume
   drawShape();
   drawBody();

   super(_shapeBody, _shape);
  }//DynamicWall

  private function drawShape():void {
   //Draw visual
   _shape = new Sprite();

   var left:Sprite = new Sprite();

   left.graphics.beginFill(_colour, 0.5);
   left.graphics.moveTo(prevEdge, Config.HEIGHT/2);
   left.graphics.lineTo(prevEdge-Config.WIDTH*side, Config.HEIGHT/2);
   left.graphics.lineTo(thisEdge-Config.WIDTH*side, -Config.HEIGHT/2);
   left.graphics.lineTo(thisEdge, -Config.HEIGHT/2);
   left.graphics.endFill();
   _shape.addChild(left);

   _parent.addChild(_shape);
  }//drawShape

  private function drawBody():void {
   //Create the shape definition
   var shapeDef:b2PolygonDef = new b2PolygonDef();
   shapeDef.vertexCount = 4;
   b2Vec2(shapeDef.vertices[0]).Set(prevEdge/Config.RATIO, Config.HEIGHT/2/Config.RATIO);
   b2Vec2(shapeDef.vertices[1]).Set((prevEdge-Config.WIDTH*side)/Config.RATIO, Config.HEIGHT/2/Config.RATIO);
   b2Vec2(shapeDef.vertices[2]).Set((thisEdge-Config.WIDTH*side)/Config.RATIO, -Config.HEIGHT/2/Config.RATIO);
   b2Vec2(shapeDef.vertices[3]).Set(thisEdge/Config.RATIO, -Config.HEIGHT/2/Config.RATIO);
   shapeDef.density = 0;
   shapeDef.friction = 10;
   shapeDef.restitution = 0.45;

   //Create the body definition (specify location here)
   var shapeBodyDef:b2BodyDef = new b2BodyDef();
   shapeBodyDef.position.Set(0, -Config.HEIGHT*(Config.CURRENT_SEGMENT+1)/Config.RATIO);

   //Create the body
   _shapeBody = Config.world.CreateBody(shapeBodyDef);

   //Create the shape
   _shapeBody.CreateShape(shapeDef);

  }//drawBody

 }//class

    }//package

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

private function addWall(Width:int) {      
   Config.CURRENT_SEGMENT++;

   //addWalls
   var leftWall:WallSegment = new WallSegment(Width, "left",camera);
   var rightWall:WallSegment = new WallSegment(Width, "right",camera);

   Config.PREV_WIDTH = Width;
  }//addWall

Я получаю эту ошибку:

TypeError: Ошибка # 1010: термин не определено и не имеет свойств. в com.carmstrong.iwanttobeacircle :: GameContactListener / Add () в Box2D.Dynamics.Contacts :: b2CircleContact / Оценивать () в Box2D.Dynamics.Contacts :: b2Contact / Update () в Box2D.Dynamics :: b2ContactManager / Collide () в Box2D. Динамика :: b2World / Step () в com.carmstrong.iwanttobeacircle :: IWantToBeACircle / everyFrame ()

Относится к классу GameContactListener, показанному ниже (функция добавления находится внизу):

    package com.carmstrong.iwanttobeacircle {

 import Box2D.Collision.b2ContactPoint;
 import Box2D.Dynamics.b2ContactListener;

 public class GameContactListener extends b2ContactListener {

  public function GameContactListener() {

  }//GameContactListener  

  override public function Add(point:b2ContactPoint):void {

   if (point.shape1.GetBody().GetUserData() is ShapeActor && point.shape2.GetBody().GetUserData() is ShapeActor) {
    //trace("Two shapes collided: Shape 1 has "+ point.shape1.GetBody().GetUserData().sides + " sides and Shape 2 has " + point.shape2.GetBody().GetUserData().sides + " sides");

    if (point.shape1.GetBody().GetUserData().sides > point.shape2.GetBody().GetUserData().sides) {
     //remove side from shape 1 and add side to shape 2
     point.shape1.GetBody().GetUserData().sides--;
     point.shape2.GetBody().GetUserData().sides++;
     //point.shape2.GetBody().GetUserData().updateColour;
    } else if (point.shape1.GetBody().GetUserData().sides < point.shape2.GetBody().GetUserData().sides) {
     //remove side from shape 2 and add side to shape 1
     point.shape1.GetBody().GetUserData().sides++;
     point.shape2.GetBody().GetUserData().sides--;
     //point.shape2.GetBody().GetUserData().updateColour;
    }// add side to smaller shape and take away from larger shape

    if(point.shape1.GetBody().GetUserData().name == "player" || point.shape2.GetBody().GetUserData().name == "player") {


     if(point.shape1.GetBody().GetUserData().name == "player" && point.shape2.GetBody().GetUserData().sides <= point.shape1.GetBody().GetUserData().sides) {
      Config.FULFILLMENT++;
      Config.SOUNDS[3+Math.ceil(Math.random()*5)][1].play();
      trace(Config.FULFILLMENT);
     } else if (point.shape2.GetBody().GetUserData().name == "player" && point.shape1.GetBody().GetUserData().sides <= point.shape2.GetBody().GetUserData().sides) {
      Config.FULFILLMENT++;
      Config.SOUNDS[Math.ceil(Math.random()*5)][1].play();
      trace(Config.FULFILLMENT);
     } else {
      Config.SOUNDS[Math.ceil(Math.random()*3)][1].play();
      Config.FULFILLMENT = int(Config.FULFILLMENT - 5);
      trace(Config.FULFILLMENT);
     }//if other shape is less than or equal to player
    }//if one of the shapes is player
   }// if both collider objects are shapes

   super.Add(point);

  }// override Add

 }//class 

    }//package

Буду признателен за любые мысли или идеи. Кроме того, это мое первое знакомство с Box2D, поэтому буду благодарен за любые советы о том, как сделать мой код более эффективным.

Заранее спасибо

1 Ответ

0 голосов
/ 27 декабря 2010

Вы задаете два вопроса здесь

  1. Почему обнаружение столкновений левой и правой стен не работает?
  2. Почему возникает ошибка в методе GameContactListener / Add ()?

Похоже, у них может быть та же самая проблема с корнем. Я вижу, вы добавляете сегменты стены как дочерние элементы "камеры" (нужно было отследить, где происходило это добавление ... вы передаете ссылку "камера" в конструктор объекта.)

i.e.    var leftWall:WallSegment = new WallSegment(Width, "left",camera);

Там вы добавляете leftWall как дочерний элемент этого объекта. Но я не уверен, что такое «камера» ... Это часть вашего игрового мира?

Кроме того, каковы ваши операторы трассировки для point.shape1 и point.shape2? Какие 2 объекта сталкиваются?

...