0

我正在制作一个简单的 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/Evaluate() 在 Box2D.Dynamics.Contacts::b2Contact/Update() 在 Box2D.Dynamics::b2ContactManager/Collide()在 Box2D.Dynamics::b2World/Step() 在 com.carmstrong.iwanttobeacircle::IWantToBeACircle/everyFrame()

其中指的是GameContactListener类,如下图(add函数在底部):

    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 的第一次尝试,所以如果有任何关于如何让我的代码更高效的提示,我将不胜感激。

提前致谢

4

1 回答 1

0

你在这里问两个问题

  1. 为什么左右墙壁碰撞检测不起作用?
  2. 为什么 GameContactListener/Add() 方法有错误?

看起来他们可能有相同的根本问题。我看到您正在将墙段添加为“相机”的子项(必须跟踪此添加发生的位置......您将“相机”的引用传递给对象的构造函数。)

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

在其中,您将 leftWall 添加为该对象的子对象。但我不确定“相机”是什么……这是你游戏世界对象的一部分吗?

另外,您对 point.shape1 和 point.shape2 的跟踪语句是什么?哪两个物体发生碰撞?

于 2010-12-27T06:28:07.267 回答