views:

137

answers:

0

I'm making a simple Box2D game ( http://iwanttobeacircle.com ), where you start off as a triangle and bounce off bigger shapes to gain sides.

I'm having a bizarre bug with my walls... both are created from the same class, yet the left one works and the right doesn't. If I only add the right one, then it works, but for some reason adding them both seems to be causing a problem somewhere.

The WallSegment class is below:

    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

To keep the level dynamic, the walls are drawn just ahead of the player object each time in the main class, using the following code:

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

I'm getting this error:

TypeError: Error #1010: A term is undefined and has no properties. at com.carmstrong.iwanttobeacircle::GameContactListener/Add() at Box2D.Dynamics.Contacts::b2CircleContact/Evaluate() at Box2D.Dynamics.Contacts::b2Contact/Update() at Box2D.Dynamics::b2ContactManager/Collide() at Box2D.Dynamics::b2World/Step() at com.carmstrong.iwanttobeacircle::IWantToBeACircle/everyFrame()

Which refers to the GameContactListener class, shown below (the add function is at the bottom):

    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

I would appreciate any thoughts or ideas. Also, this is my first go at Box2D so would appreciate any tips on how to make my code more efficient.

Thanks in advance