示例中心
功能在线体验
控制台

游戏与地图结合

该demo主要是针对游戏场景,向开发者展示如何在地图上面添加带动画效果的3D模型图。
00:00 / 01:00
扫描二维码在手机端体验功能
体验移动端 扫码体验移动端

使用场景

该demo主要是针对游戏场景,向开发者展示如何在地图上面添加带动画效果的3D模型图。

用到产品

Android 地图 SDK

核心类/接口

接口

说明

版本

AMap

public void setCustomRenderer(CustomRenderer render)

设置获取openGL的回调方法。

V2.1.3版本起

核心难点

1、初始化AMap对象及获取OPENGL绘制回调。

/**
 * 初始化AMap对象
 */
private void init() {
    if (aMap == null) {
        aMap = mapView.getMap();

        //关闭文字
        aMap.showMapText(false);
        //关闭3d楼块
        aMap.showBuildings(false);
        //注1:设置opengl Renderer
        aMap.setCustomRenderer(new MapRenderer(aMap));
    }
}

2、地图开放每桢回调及坐标转换

class MapRenderer implements CustomRenderer{
       TigerModel tiger;
       AMap aMap;
       ...
       @Override
       public void onDrawFrame(GL10 gl) {
           // 地图开放每帧Render 回调
           // 绘制模型
           tiger.draw();
       }
  @Override
 public void OnMapReferencechanged() {
      // 地图放到到一定级别 重新计算缩放比例
      // 开放屏幕、经纬度和OPENGL坐标互转
      aMap.getProjection().fromScreenLocation(screenPos);//屏幕坐标转经纬度
      aMap.getProjection().toScreenLocation(mapLatlng);//经纬度转屏幕坐标
      aMap.getProjection().toOpenGLLocation(mapLatlng);//经纬度转OPENGL坐标
      aMap.getProjection().toOpenGLWidth(screenWidth);//幕宽度转OPENGL宽度
 } 
   }

 

00:00 / 01:00
扫描二维码在手机端体验功能
体验移动端 扫码体验移动端

使用场景

该demo主要是针对游戏场景,向开发者展示如何在地图上面添加带动画效果的3D模型图。

用到产品

iOS 地图 SDK

核心类/接口

接口

说明

版本

AMap3DObjectOverlay

+ (instancetype)objectOverlayWithCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate size:(CLLocationDistance)size vertexPointer:(float *)vertexPointer normalPointer:(float *)normalPointer texCoordPointer:(float *)texCoordPointer vertsNum:(unsigned int)vertsNum;

继承自NSObject,实现了设置coordinate

V4.0.0起

AMap3DObjectOverlayRenderer

- (void)glRender;

自定义Overlay绘制模型的核心代码

V4.0.0起

核心难点

1、自定义Overlay回调

- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id <MAOverlay>)overlay
{
    if ([overlay isKindOfClass:[AMap3DObjectOverlay class]])
    {
        AMap3DObjectOverlay *objOverlay = (AMap3DObjectOverlay *)overlay;
        AMap3DObjectOverlayRenderer * reaverRenderer = [[AMap3DObjectOverlayRenderer alloc] initWithObjectOverlay:overlay];
        [reaverRenderer loadStrokeTextureImage:[UIImage imageNamed:objOverlay.textureName]];
        return reaverRenderer;
    }

    return nil;
}
func mapView(_ mapView: MAMapView!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {
    if overlay.isKind(of: AMap3DObjectOverlay.self) {
        let objOverlay:AMap3DObjectOverlay = overlay as! AMap3DObjectOverlay

        let reaverRender: AMap3DObjectOverlayRenderer = AMap3DObjectOverlayRenderer(objectOverlay: overlay as! AMap3DObjectOverlay)

        let image:UIImage = UIImage.init(named: objOverlay.textureName)!

        reaverRender.loadStrokeTextureImage(image)

        return reaverRender
    }

    return nil
}

2、初始化3D模型

- (void)airPlaneInit
{
    self.airPlaneOverlay = [AMap3DObjectOverlay objectOverlayWithCenterCoordinate:CLLocationCoordinate2DMake(39.984479, 116.494635) size:100 vertexPointer:raptorVerts normalPointer:raptorNormals texCoordPointer:raptorTexCoords vertsNum:raptorNumVerts];

    self.airPlaneOverlay.angle = 128;
    self.airPlaneOverlay.altitude = 10;
    self.airPlaneOverlay.textureName = @"FA-22_Raptor_P01";

    [self.mapView addOverlay:self.airPlaneOverlay];
}
func airPlaneInit() {
    self.airPlaneOverlay = AMap3DObjectOverlay(center: CLLocationCoordinate2DMake(39.984479, 116.494635),
        size: 100,
        vertexPointer: pRaptorVerts,
        normalPointer: pRaptorNormals,
        texCoordPointer: pRaptorTexCoords,
        vertsNum: raptorNumVerts)
    self.airPlaneOverlay.angle = 128
    self.airPlaneOverlay.altitude = 10
    self.airPlaneOverlay.textureName = "FA-22_Raptor_P01"
    self.mapView.add(self.airPlaneOverlay)
}

3、核心模型绘制代码

model为OC写,所以只有OC版本代码说明

- (void)glRender
{
    AMap3DObjectOverlay *objOverlay = self.objOverlay;

    if (_isNeedDoMoveCoordinate) {
        [self didMoveCoordinate];
    }

    if (objOverlay.vertsNum == 0)
    {
        return;
    }

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glEnable(GL_TEXTURE_2D);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glBindTexture(GL_TEXTURE_2D, self.strokeTextureID);
    glColor4f(1, 1, 1, 1);

    glPushMatrix();

    if ([self.objOverlay.textureName isEqualToString:@"FA-22_Raptor_P01"] && objOverlay.altitude < 500) {
        _centerGL.z =  [self calculateSizeInGLReference] / objOverlay.size * objOverlay.altitude;
        objOverlay.altitude += 2;
    }

    glTranslatef(_centerGL.x, _centerGL.y, _centerGL.z);
    glRotatef(90, 1, 0, 0);

    glRotatef(objOverlay.angle, 0, 1, 0);
    if ([self.objOverlay.textureName isEqualToString:@"FelReaverMount"]) {
        objOverlay.angle += 1;
    }

    glScalef(_sizeGL, _sizeGL, _sizeGL);

    glVertexPointer(3, GL_FLOAT, 0, objOverlay.vertexPointer);
    glNormalPointer(GL_FLOAT, 0, objOverlay.normalPointer);
    glTexCoordPointer(2, GL_FLOAT, 0, objOverlay.texCoordPointer);

    glDrawArrays(GL_TRIANGLES, 0, objOverlay.vertsNum);

    glPopMatrix();

    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glDisable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);

}