在原生环境下运行

1. 在安卓环境下运行

Android端引擎渲染视图使用GLRecorderView跟XERenderView
对于有录制需求的情景,使用GLRecorderView;对于没有录制需求的情况,推荐使用XERenderView


1.1. XERenderView的使用

XERenderView总体上分为以下3个步骤:
  1. view创建并配置
  2. 开始创建view的环境并监听
  3. 加载游戏资源
  4. 释放

具体使用如下:

1.1.1. view的创建(前两步也可以通过xml的方式代替)

  1. new一个View
    mXERenderView = new XERenderView(this);
  2. 添加到容器中
         FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(xxx,xxx);   
         containerFrameLayout.addView(mXERenderView);
    
  3. 创建一个controller并绑定
    mXERenderViewController = new XERenderViewController();
    mXERenderViewController.bindView(mXERenderView);
    
  4. 配置参数
    XEViewConfig config = XEViewConfig.obtain();
    config.mRootPath = "/sdcard/xxx";
    config.mFrameRate = 30;//根据需要设置帧率
    config.mRenderSize = new Point(480, 640);//设置渲染尺寸,若不设置默认view的宽高大小
    mXERenderViewController.config(config);
    
开始准备,监听准备成功回调

注意,如果视图不可见的情况,系统创建surfaceTexture可能失败,所以,一定要保证视图大小不为0,且在屏幕内,可见

  1. 创建一个回调

    XERenderViewController.OnPreparedCallback callback = new XERenderViewController.OnPreparedCallback() {
                 @Override
                 public void onPrepared() {
             //下面是加载资源的逻辑,跟view无关~~~
                        XE3DEngine engine = mController.getEngine();
                      engine.addSearchPath("zombiePartyDemo");
                         engine.getScriptEngine().startGameScriptFile("app");
                 }
    
               @Override
               public void onSurfaceChanged(int w, int h) {
    
                 }
    
                @Override
                public void onDestroyed() {
                     Log.e("LiveGame", "onDestroyed: ");
                 }
             }
    
  2. 开始准备,并传入监听。 环境异步创建成功后,会在onPrepared中进行回调

    mXERenderViewController.prepare(callback);
    
加载资源

在onPrepared回调中,调用engine.getScriptEngine().startGameScriptFile("app")加载资源。
注意路径是基于上面配置的rootPath的。
也可以通过engine.addSearchPath(scenePath)配置searchPath(也是基于rootPath),这样资源也会在searchPath中去查找

参考代码见上一步中onPrepared回调部分
释放

释放有两种方式,即自动释放与手动释放

  1. 自动释放
    页面退出,或者父布局被移除等触发onDetachFromWindow的时候,会触发同步退出
  2. 手动释放
    手动释放需要调用父布局容器的removeView(mXERenderView)来移除,移除过程是同步的,调用remove后会触发onDestroy()回调
    containerFrameLayout.removeView(mXERenderView);
    //containerFrameLayout.removeAllView();
    

2. 在iOS环境下运行

2.1. 普通渲染

场景选择:只有一个业务使用到引擎渲染,且不需要使用渲染录制、截屏功能

渲染视图选择

XSKDisplayView:
封装GLView作为渲染视图,引擎绑定的OpenGLES Context和GLView的Context是同一个,引擎渲染直接通过GLView展示出来。

接口介绍
@interface XSKDisplayView : XSKTouchView

- (instancetype)initWithFrame:(CGRect)frame;

@property (weak) id <XSKDisplayViewDelegatedelegate; // 每帧Render回调

- (void)setupEngine:(NSString *)path; // 启动引擎,建议以XSKEngine接口替换

- (void)destoryEngine; // 销毁引擎,建议以XSKEngine接口替换

@end

@protocol XSKDisplayViewDelegate <NSObject>
@optional
- (void)displayView:(XSKDisplayView *)displayView willRender:(CGRect)renderRect; // 每帧渲染回调
- (void)displayView:(XSKDisplayView *)displayView customRender:(CGRect)renderRect; // 默认调用render(),可以自定义调用render(sceneID)

@end
接入示例
// 启动引擎
NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/demo.bundle"];
[[XSKEngine shareInstance] configResourcePath:path]; // 引擎根路径配置
[[XSKEngine shareInstance] runEngine];    // 启动引擎
[[XSKEngine shareInstance] setupLuaScriptEngine]; // 启动Lua脚本引擎

// 渲染设置
self.preview = [[XSKDisplayView alloc] initWithFrame:CGRectMake(0, 0, 375, 667)];
[self.view addSubview:self.preview];

// 通过lua脚本启动
[[XSKEngine shareInstance] addSearchPath:@"game"]; // 添加脚本在引擎根路径的相对路径
[[XSKEngine shareInstance] execteGameScriptFile:@"app"]; // 启动Lua脚本

// 脚本代码参考文末

2.1.1. 共享渲染

场景选择:有多个业务使用到引擎渲染,如:直播视频特效和交互礼物同事支持,或者需要使用录制、截屏功能

渲染视图选择

XSKGLDisplayView:
封装GLView作为预览视图,引擎绑定的OpenGLES Context和GLView的Context不是同一个,引擎有单独的OpenGLES Context,引擎先渲染到PixelBuffer,然后通过预览视图预览PixelBuffer的内容。

接口介绍
@interface XSKGLDisplayView : XSKTouchView

- (instancetype)initWithFrame:(CGRect)frame;

@property(nonatomic, assign) CGSize renderSize;    //默认为 viewSize*nativeScale

@property(nonatomic, assign) NSUInteger frameRate; //默认是 30帧

@property(nonatomic, weak) id <XSKGLDisplayViewDataOutputDelegatedelegate; // 录屏回调

@property(nonatomic, readonly) CGFloat nativeScale; // 来自UIScene的nativeScale

- (void)shot:(void (^)(UIImage *))callback; // 截图

- (void)pause; // 渲染暂停,不调用引擎render()

- (void)resume; // 恢复渲染

- (void)updateRenderID:(NSString *)renderID; // 特殊情况需要用到指定渲染ID调用此接口

@end

// 回调录屏PixelBuffer,不设置代理则不处理录屏相关操作,性能会更高
@protocol XSKGLDisplayViewDataOutputDelegate <NSObject>
@optional
- (void)displayView:(XSKGLDisplayView *)displayView didOutputVideoPixelBuffer:(CVPixelBufferRef)pixelBuffer timinginfo:(CMSampleTimingInfo)timingInfo;
@end
接入示例
// 启动引擎
NSString *path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/demo.bundle"];
[[XSKEngine shareInstance] configResourcePath:path]; // 引擎根路径配置
[[XSKEngine shareInstance] runEngine];    // 启动引擎
[[XSKEngine shareInstance] setupLuaScriptEngine]; // 启动Lua脚本引擎

// 渲染设置
self.preview = [[XSKGLDisplayView alloc] initWithFrame:CGRectMake(0, 0, 375, 667)];
[self.view addSubview:self.preview];
// 渲染尺寸设置
self.displayView.renderSize = CGSizeMake(720, 1280));

// 通过lua脚本启动
[[XSKEngine shareInstance] addSearchPath:@"game"]; // 添加脚本在引擎根路径的相对路径
[[XSKEngine shareInstance] execteGameScriptFile:@"app"]; // 启动Lua脚本

// 脚本代码参考文末

2.1.2. 示例使用Lua脚本参考

function ONLINE_LOG(log)
    print(tostring(os.time()) .. "  GAME_LOG:  " .. tostring(log))
end

local App = {}

function App.onStart()
    ONLINE_LOG("App onStart")

    local scene = xe.Scene:new("com.wemomo.engine")
    scene:GetWorld():LoadScene("xxxx.xscene")
    xe.Director:GetInstance():PushScene(scene)

end

function App.onResume()
    ONLINE_LOG("App onResume")
end

function App.onPause()
    ONLINE_LOG("App onPause")
end

function App.onEnd()
    ONLINE_LOG("App onEnd")
end

xe.AppDelegate = App

3. 与原生环境通信

引擎提供了Bridge模块进行Lua与原生平台的通信.

3.1. Lua调用原生平台

在原生平台注册Bridge Handler后才可以进行在Lua中调用原生平台.

3.1.1. 注册Handler

在iOS中:

//Handler实现类
@interface MyHandler : NSObject

- (NSString *)action:(NSString *)msg;

- (void)actionAsync:(NSString *)msg callback:(void (^)(NSString *))callback;

@end

//注册Handler
MyHandler *handler = [[MyHandler alloc] init];
[XSKBridge regist:handler forHandler:@"handler"];

在安卓中:

//Handler实现类
public class MMGameHandler {
    public String action(String msg);
    public void actionAsync(String msg, ScriptBridge.Callback callback);
}

//注册Handler
MyHandler handler = new MyHandler();
ScriptBridge.regist(new MMGameHandler(),"handler");

3.1.2. 在Lua中调用Handler

--调用同步方法
local result = xe.ScriptBridge:call("handler", "action", "lua message");
--调用异步方法
xe.ScriptBridge:callAsync("handler", "actionAsync", "message form lua", function(result)
        print(result);
end);

注意事项:Bridge Handler 中的方法被Lua调用时是在引擎的渲染线程中,所以需要使用者注意线程问题,如有需要自行在bridge方法中调度线程。

3.2. 原生平台调用Lua

相对于Lua调用原生平台看来说,原生调用Lua的时候,我们提供了更多的方式以适应不同的业务场景

3.2.1. 通过事件派发器

在安卓中:

//Java
DataEvent event = new DataEvent();
event.setName("ActionName");
event.setContent("Action");
XE3DEngine.getInstance().sendEvent(event);

在iOS中

//Objc
xes::DataEvent event;
event.SetName("ActionName");
event.SetContent("Action);
xes::Director::GetInstance()->GetEventDispatcher()->DispatchEvent(&event);

在Lua中:

self.datalst = xe.DataEventListener:Create()
self.datalst:RegisterHandler(function(sender, data)
    print('数据监听 ', data)
end, "ActionName")

xe.Director:GetInstance():GetEventDispatcher():AddEventListener(self.datalst, self)

3.2.2. 通过Bridge

在Lua中:

--lua
LuaObject = {}    --全局对象
LuaObject.action = function(message) 
    print("原生调用Lua传递消息", message)
end

在安卓中:

//Java
ScriptBridge.callLua("LuaObject", "action", "message");

在iOS中:

//Objc
[XSKBridge callLua:@"LuaObject" action:@"action" message:@"message"];
通过脚本解释器

在安卓中:

//Java
XELuaEngine.getInstance().executeScriptFile("print('lua print')");

在iOS中:

//Objc
xes::LuaEngine::GetInstance()->ExecuteString("print('lua print')")
@Copyright © cosmos 2019 all right reserved,powered by Gitbook修订时间: 2021-04-12 18:28:18

results matching ""

    No results matching ""