2013-05-15 51 views
3

我試圖用SurfaceScrollDetector和PinchZoomDetector實現平滑的TMX地圖滾動和縮放。andengine使用SurfaceScrollDetector平滑滾動和縮放,PinchZoomDetector

這裏是我的代碼:

public class TMXTiledMapExample extends SimpleBaseGameActivity implements IOnSceneTouchListener, IScrollDetectorListener, IPinchZoomDetectorListener { 

private static final int CAMERA_WIDTH = 480; 
private static final int CAMERA_HEIGHT = 320; 

private SmoothCamera camera; 

private TMXTiledMap mTMXTiledMap; 

private SurfaceScrollDetector mScrollDetector; 
private PinchZoomDetector mPinchZoomDetector; 
private float mPinchZoomStartedCameraZoomFactor; 

@Override 
public EngineOptions onCreateEngineOptions() { 
    this.camera = new SmoothCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT, 400, 400, 10f); 
    final CroppedResolutionPolicy canvasSurface = new CroppedResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT); 
    EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, canvasSurface, this.camera); 

    if (MultiTouch.isSupported(this)) { 
     if (MultiTouch.isSupportedDistinct(this)) { 
      Toast.makeText(this, "MultiTouch detected --> Both controls will work properly!", Toast.LENGTH_SHORT).show(); 
     } else { 
      Toast.makeText(this, "MultiTouch detected, but your device has problems distinguishing between fingers.\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG) 
        .show(); 
     } 
    } else { 
     Toast.makeText(this, "Sorry your device does NOT support MultiTouch!\n\n(Falling back to SingleTouch.)\n\nControls are placed at different vertical locations.", Toast.LENGTH_LONG).show(); 
    } 

    return engineOptions; 
} 

@Override 
public void onCreateResources() { 
    BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/"); 
} 

@Override 
public Scene onCreateScene() { 
    this.mEngine.registerUpdateHandler(new FPSLogger()); 

    final Scene scene = new Scene(); 
    scene.setOnAreaTouchTraversalFrontToBack(); 

    this.mScrollDetector = new SurfaceScrollDetector(this); 
    this.mPinchZoomDetector = new PinchZoomDetector(this); 

    scene.setOnSceneTouchListener(this); 
    scene.setTouchAreaBindingOnActionDownEnabled(true); 

    try { 
     final TMXLoader tmxLoader = new TMXLoader(this.getAssets(), this.mEngine.getTextureManager(), TextureOptions.BILINEAR, this.getVertexBufferObjectManager(), 
       new ITMXTilePropertiesListener() { 
        @Override 
        public void onTMXTileWithPropertiesCreated(final TMXTiledMap pTMXTiledMap, final TMXLayer pTMXLayer, final TMXTile pTMXTile, 
          final TMXProperties<TMXTileProperty> pTMXTileProperties) { 
        } 
       }); 
     this.mTMXTiledMap = tmxLoader.loadFromAsset("tmx/desert2.tmx"); 

    } catch (final TMXLoadException e) { 
     Debug.e(e); 
    } 

    final TMXLayer tmxLayer = this.mTMXTiledMap.getTMXLayers().get(0); 
    scene.attachChild(tmxLayer); 

    this.camera.setBounds(0, 0, tmxLayer.getHeight(), tmxLayer.getWidth()); 
    this.camera.setBoundsEnabled(true); 

    return scene; 
} 

@Override 
public void onScrollStarted(final ScrollDetector pScollDetector, final int pPointerID, final float pDistanceX, final float pDistanceY) { 
    final float zoomFactor = this.camera.getZoomFactor(); 
    this.camera.offsetCenter(-pDistanceX/zoomFactor, -pDistanceY/zoomFactor); 
} 

@Override 
public void onScroll(final ScrollDetector pScollDetector, final int pPointerID, final float pDistanceX, final float pDistanceY) { 
    final float zoomFactor = this.camera.getZoomFactor(); 
    this.camera.offsetCenter(-pDistanceX/zoomFactor, -pDistanceY/zoomFactor); 
} 

@Override 
public void onScrollFinished(final ScrollDetector pScollDetector, final int pPointerID, final float pDistanceX, final float pDistanceY) { 
    final float zoomFactor = this.camera.getZoomFactor(); 
    this.camera.offsetCenter(-pDistanceX/zoomFactor, -pDistanceY/zoomFactor); 
} 

@Override 
public void onPinchZoomStarted(final PinchZoomDetector pPinchZoomDetector, final TouchEvent pTouchEvent) { 
    this.mPinchZoomStartedCameraZoomFactor = this.camera.getZoomFactor(); 
} 

@Override 
public void onPinchZoom(final PinchZoomDetector pPinchZoomDetector, final TouchEvent pTouchEvent, final float pZoomFactor) { 
    this.camera.setZoomFactor(this.mPinchZoomStartedCameraZoomFactor * pZoomFactor); 
} 

@Override 
public void onPinchZoomFinished(final PinchZoomDetector pPinchZoomDetector, final TouchEvent pTouchEvent, final float pZoomFactor) { 
    this.camera.setZoomFactor(this.mPinchZoomStartedCameraZoomFactor * pZoomFactor); 
} 

@Override 
public boolean onSceneTouchEvent(final Scene pScene, final TouchEvent pSceneTouchEvent) { 
    this.mPinchZoomDetector.onTouchEvent(pSceneTouchEvent); 

    if (this.mPinchZoomDetector.isZooming()) { 
     this.mScrollDetector.setEnabled(false); 
    } else { 
     if (pSceneTouchEvent.isActionDown()) { 
      this.mScrollDetector.setEnabled(true); 
     } 
     this.mScrollDetector.onTouchEvent(pSceneTouchEvent); 
    } 

    return true; 
} 
} 

滾動在這碼變焦都不是很順利。它的問題在哪裏?如何創建漂亮的慣性滾動?

還有一個縮放問題。如何用最大和最小zoomfactor來限制它?我應該在IPinchZoomDetectorListener方法中放置一些特殊的條件,還是可以使用提供給我的相機對象的某些參數來實現它?

另外,什麼是最後三個SmoothCamera參數的最後一個「正常」值 - 最終浮動pMaxVelocityX,最終浮動pMaxVelocityY,最終浮動pMaxZoomFactorChange?

回答

3

我之前完成過類似的工作,所以我可以幫助您實現目標。

首先,如果你想放大/縮小功能,那麼你必須使用ZoomCamera,其中你只需要給出寬度和高度,所有其他參數默認使用。

mZoomCamera = new ZoomCamera(0, 0, Constants.CAMERA_WIDTH, 
      Constants.CAMERA_HEIGHT); 
    mZoomCamera.setBounds(0f, 0f, Constants.CAMERA_WIDTH, 
      Constants.CAMERA_HEIGHT); 
    mZoomCamera.setBoundsEnabled(true); 

在示例代碼中,您會看到我如何爲相機設置邊界,因此沒有機會讓相機可以離開它。而且我還因爲你提供的速度不合適而導致你的行爲異常。

用於設置特定變焦值,可以使用下面的代碼,

private void setCameraZoomFactor(float pZoomFactor) { 
    newZoomFactor = mPinchZoomStartedCameraZoomFactor * pZoomFactor; 
    if (newZoomFactor < 1f) 
     newZoomFactor = 1f; 
    if (newZoomFactor > 1.5f) 
     newZoomFactor = 1.5f; 

    mZoomCamera.setZoomFactor(newZoomFactor); 
} 

你要調用此方法在您的onPinchZoom方法。

我想現在我已經給出了所有問題的答案。

+0

感謝您的回答!還有一個問題 - SmoothCamera和ZoomCamera有什麼區別。 SmoothCamera擴展了ZoomCamera。我應該使用哪一個? – alexanoid

+0

我很高興能爲您提供幫助。對於平滑相機和變​​焦相機的區別,我必須明白,所以我不會誤導你。根據我的建議,你必須使用變焦相機,因爲你不必在這裏提供任何速度值。所以沒有錯誤概念的機會。 – Siddharth

+0

是啊,現在一切正常,謝謝! – alexanoid