2010-01-14 6 views
0

Je fais un simple jeu Box2D (http://iwanttobeacircle.com), où vous commencez comme un triangle et rebondissez sur des formes plus grandes pour gagner des côtés. J'ai un bug bizarre avec mes murs ... les deux sont créés à partir de la même classe, mais la gauche fonctionne et la droite ne fonctionne pas. Si j'ajoute seulement le bon, alors cela fonctionne, mais pour une raison quelconque, les ajouter tous les deux semble causer un problème quelque part.Box2D Walls - même code: le gauche fonctionne, le droit

La classe WallSegment est ci-dessous:

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 

Pour maintenir le niveau dynamique, les murs sont tirés juste devant l'objet de joueur à chaque fois dans la classe principale, en utilisant le code suivant:

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 

Je reçois cette erreur:

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()

qui fait référence à la classe GameContactListener , illustré ci-dessous (la fonction d'ajout est en bas):

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 

J'apprécierais des idées ou des idées. Aussi, c'est mon premier coup à Box2D donc j'apprécierais des conseils sur la façon de rendre mon code plus efficace.

Merci à l'avance

+0

Il peut être utile de préciser quelles données sont nulles dans la méthode Add() - il y a beaucoup d'options: point, point.shape1, point.shape1.GetBody(), etc. –

Répondre

0

Vous posez deux questions ici

  1. Pourquoi la détection de collision paroi gauche et droit ne fonctionne pas?
  2. Pourquoi y a-t-il une erreur dans la méthode GameContactListener/Add()?

Il semble qu'ils puissent avoir le même problème de racine. Je vois que vous ajoutez les segments de mur en tant qu'enfants de la "caméra" (vous deviez tracer où cet ajout se produisait ... vous passez une référence de "caméra" dans le constructeur de l'objet.)

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

À l'intérieur, vous ajoutez le leftWall en tant qu'enfant de cet objet. Mais je ne suis pas sûr de ce qu'est "appareil photo" ... Est-ce que cette partie de votre objet de jeu du monde?

En outre, quelles sont vos instructions de trace pour point.shape1 et point.shape2? Quels 2 objets sont en collision?

Questions connexes