1
votes

I'm trying to set up Collision detection on the cactus-property items on all cactuses in the TMXmap example from andengine Gles2. I have tried various methods - can anyone give me one that works?

Original Code Tmxmaps andengine

One suggested solution: collision detection

Another suggested solution: from andengine.org

I've tried:

if(pTMXTileProperties.containsTMXProperty("cactus", "true")) {
    final Rectangle rect = new Rectangle(pTMXTile.getTileX()+10, pTMXTile.getTileY(),14, 14);
    final FixtureDef boxFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 1f);
    PhysicsFactory.createBoxBody(mPhysicsWorld, rect, BodyType.StaticBody, boxFixtureDef);
    rect.setVisible(false);
    mScene.attachChild(rect);
}

This is from AndEngine: Handling collisions with TMX Objects

But I get this error:

Physicsfactory not found
2

2 Answers

1
votes

I'm using the TMX example you have there as a basis for my game.

This is the main block of code for collisions:

// Define the block behavior

    mPathFinderMap = new IPathFinderMap<TMXLayer>(){

            private boolean mCollide;

            @Override
            public boolean isBlocked(final int pX, final int pY, final TMXLayer pTMXLayer) {
                /*
                 * This is where collisions happen and are detected 
                 */
                mCollide = false;
                //Null check. Used since not all tiles have properties
                if(pTMXLayer.getTMXTile(pX, pY).getTMXTileProperties(mTiledMap) != null){
                    //Get tiles with collision property
                    if(pTMXLayer.getTMXTile(pX, pY).getTMXTileProperties(mTiledMap).containsTMXProperty("COLLISION", "true")) 
                        mCollide = true;                                        
                }   

                if(mTMXmapLoader.getCollideTiles().contains(pTMXLayer.getTMXTile(pX, pY)))
                    mCollide = true;

                return mCollide;
            }

    };

/*
 * This method moves the sprite to the designated location
 */
public void walkTo(TMXTile pFinalPosition) {
    if(mHasFinishedPath){
        mHasFinishedPath = false;//This prevents overlapping paths when the user double clicks. Used to prevent stutter
        //Player coordinates
        final float[] lPlayerCordinates = mPlayerSprite.convertLocalToSceneCoordinates(mPlayerSprite.getWidth()/2, mPlayerSprite.getHeight()/2);
        // Get the tile the center of the player are currently waking on. 
        TMXTile lPlayerPosition = SceneManager.mWorldScene.getTouchLayer().getTMXTileAt(lPlayerCordinates[Constants.VERTEX_INDEX_X], lPlayerCordinates[Constants.VERTEX_INDEX_Y]);
        mFinalPosition = pFinalPosition;

        // Sets the A* path from the player location to the touched location.
        if(mPathFinderMap.isBlocked(pFinalPosition.getTileColumn(), pFinalPosition.getTileRow(), SceneManager.mWorldScene.getTouchLayer())){    
            pFinalPosition = getNextTile(lPlayerPosition, pFinalPosition);
        }

        // These are the parameters used to determine the 
        int lFromCol = lPlayerPosition.getTileColumn(); int lFromRow = lPlayerPosition.getTileRow();
        int lToCol = pFinalPosition.getTileColumn();    int lToRow = pFinalPosition.getTileRow();
        boolean lAllowDiagonal = false;
        // Find the path. This needs to be refreshed
        AStarPath = mAStarPathFinder.findPath(MAX_SEARCH_DEPTH, mPathFinderMap, 0, 0, mTiledMap.getTileColumns() - 1, mTiledMap.getTileRows() - 1, SceneManager.mWorldScene.getTouchLayer(), 
                lFromCol, lFromRow, lToCol, lToRow, lAllowDiagonal, mHeuristic, mCostCallback);

        //Log.i("AstarPath", "AStarPath  " + AStarPath);
        //Only loads the path if the AStarPath is not null
        Path lPlayerPath = loadPathFound();
        //Log.i("AstarPath", "lPlayerPath  " + lPlayerPath);
        if(lPlayerPath != null)
            moveSprite(lPlayerPath);//Moves the sprite along the path
        else
            mHasFinishedPath = true;//If the path is null the player has not moved. Set the flag to true allows input to effect the sprite
    }else{
        //Update parameters
        mFinalPosition = pFinalPosition;
        mWaypointIndex = 0;
    }
}

/*
 * Updates the path
 */
public void updatePath(TMXTile pFinalPosition) {    
    //Player coordinates
    final float[] lPlayerCordinates = mPlayerSprite.convertLocalToSceneCoordinates(mPlayerSprite.getWidth()/2, mPlayerSprite.getHeight()/2);
    // Get the tile the feet of the player are currently waking on. 
    TMXTile lPlayerPosition = SceneManager.mWorldScene.getTouchLayer().getTMXTileAt(lPlayerCordinates[Constants.VERTEX_INDEX_X], lPlayerCordinates[Constants.VERTEX_INDEX_Y]);

    // Sets the A* path from the player location to the touched location.
    if(mPathFinderMap.isBlocked(pFinalPosition.getTileColumn(), pFinalPosition.getTileRow(), SceneManager.mWorldScene.getTouchLayer())){    
        pFinalPosition = getNextTile(lPlayerPosition, pFinalPosition);
    }

    // Determine the tile locations
    int FromCol = lPlayerPosition.getTileColumn();
    int FromRow = lPlayerPosition.getTileRow();
    int ToCol = pFinalPosition.getTileColumn();
    int ToRow = pFinalPosition.getTileRow();
    // Find the path. This needs to be refreshed
    AStarPath = mAStarPathFinder.findPath(MAX_SEARCH_DEPTH, mPathFinderMap, 0, 0, mTiledMap.getTileColumns()-1, mTiledMap.getTileRows()-1, SceneManager.mWorldScene.getTouchLayer(), 
            FromCol, FromRow, ToCol, ToRow, false, mHeuristic, mCostCallback);

    //Loads the path with the astar specifications
    Path lPlayerPath = loadPathFound();
    //Moves the sprite along the path
    if(lPlayerPath != null){
        moveSprite(lPlayerPath);
    }else{
        //If the path is still null after the path manipulation then the path is finished
        mHasFinishedPath = true;
        mWaypointIndex = 0;
        //mPlayerSprite.stopAnimation();
        //AStarPath = null;
    }
}

The TMXmapLoader does the rest:

//Get the collision, ext, and changing tiles from the object sets on the map
    mCollideTiles = this.getObjectGroupPropertyTiles("COLLIDE",  TMXGroupObjects);  
    mExitTiles = this.getObjectPropertyTiles("EXIT", mTMXObjects);
    mChangingTiles = this.getObjectGroupPropertyTiles("CHANGE", TMXGroupObjects);
...
public ArrayList<TMXTile> getCollideTiles(){
    return mCollideTiles;       
}
...
public ArrayList<TMXTile> getObjectGroupPropertyTiles(String pName, final int pLayer, ArrayList<TMXObjectGroup> pTMXObjectGroups){
    ArrayList<TMXTile> ObjectTile = new ArrayList<TMXTile>();
    for (final TMXObjectGroup pObjectGroups : pTMXObjectGroups) {
        // Iterates through the properties and assigns them to the new variable
        for (final TMXObjectGroupProperty pGroupProperties : pObjectGroups.getTMXObjectGroupProperties()) {
            //Sees if any of the elements have this condition
            if (pGroupProperties.getName().contains(pName)) {
                for (final TMXObject pObjectTiles : pObjectGroups.getTMXObjects()) {
                    int ObjectX = pObjectTiles.getX();
                    int ObjectY = pObjectTiles.getY();
                    // Gets the number of rows and columns in the object
                    int ObjectRows = pObjectTiles.getHeight() / WorldActivity.TILE_HEIGHT;
                    int ObjectColumns = pObjectTiles.getWidth() / WorldActivity.TILE_WIDTH;

                    for (int TileRow = 0; TileRow < ObjectRows; TileRow++) {
                        for (int TileColumn = 0; TileColumn < ObjectColumns; TileColumn++) {
                            float lObjectTileX = ObjectX + TileColumn * WorldActivity.TILE_WIDTH;
                            float lObjectTileY = ObjectY + TileRow * WorldActivity.TILE_HEIGHT;
                            ObjectTile.add(mTMXTiledMap.getTMXLayers().get(pLayer).getTMXTileAt(lObjectTileX, lObjectTileY));                       
                        }                            
                    }
                }
            }           
        }
    }
    return ObjectTile;
}
0
votes

I'm not familiar with android development, but the error seems to indicate that PhysicsFactory hasn't been imported. Maybe try adding an import statement like this to the top of your file?

import org.anddev.andengine.extension.physics.box2d.PhysicsFactory;