分布式能力是HarmonOS的特色,可以利用这个特性实现一些创意的小游戏。下图的小游戏使用了手机的陀螺仪控制小球实现了跨端游戏。游戏界面使用JS实现,分布式的相关能力java实现。所以实现这个demo可以学习到js调用java的相关知识。
一、JS调用PA能力callAbilitytry {
var res = await FeatureAbility.callAbility({
bundleName: "com.liangzili.demos", // Ability的包名称,需要与PA端匹配,区分大小写。
abilityName: "RemoteServiceAbility", // Ability名称,需要与PA端匹配,区分大小写。
messageCode: 1002, // Ability操作码,需要与PA端约定
data: "关闭dialog",// 携带的数据
abilityType: 0, // Ability类型,对应PA端不同的实现方式。0:Ability、1:Internal Ability
syncOption: 0 // 非必填,PA侧请求消息处理同步/异步选项,默认使用同步方式。0:Sync、1:Asyn
});
console.info("callAbility result = " res); // 返回JSON格式的字符串
} catch (pluginError) {
console.error("callAbility Plugin Error = " pluginError);
}
二、JS订阅PA能力
try {
var that = this
var result = FeatureAbility.subscribeAbilityEvent({
bundleName: "com.liangzili.demos", // Ability的包名称,需要与PA端匹配,区分大小写。
abilityName: "RemoteServiceAbility", // Ability名称,需要与PA端匹配,区分大小写。
messageCode: 1001, // Ability操作码,需要与PA端约定
abilityType: 0, // Ability类型,对应PA端不同的实现方式。0:Ability、1:Internal Ability
syncOption: 0 // 非必填,PA侧请求消息处理同步/异步选项,默认使用同步方式。0:Sync、1:Asyn
}, function (callbackData) {
console.info("callbackData is:" callbackData);
...
}
});
console.info(" subscribeCommonEvent result = " result);
if (result) {
prompt.showToast({
message: '游戏初始化完成', duration: 2000
})
} else {
prompt.showToast({
message: '游戏初始化失败', duration: 2000
})
}
} catch (pluginError) {
console.error("subscribeCommonEvent error : result= " result JSON.stringify(pluginError));
}
三、JAVA端的代码
java端提供了Ability调用、Internal Ability调用方式两种方式。JAVA端的接口:
我使用的Ability调用的方式。
需要新建一个Service Ability,名字就是js端代码中 abilityName 的值,比如:RemoteServiceAbility
1.在RemoteServiceAbility中new一个RemoteObject
private final MyRemote remote = new MyRemote();
class MyRemote extends RemoteObject implements IRemoteBroker{
public MyRemote(){super("MyRemote");}
@Override
public IRemoteObject asObject() {
return this;
}
@Override
public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) throws RemoteException {
switch (code) {
case 1001: {
reply.writeString("case 1001"); // 上报结果到JS
break;
}
default: {
reply.writeString("service not defined");
return false;
}
}
return true;
}
}
2.FA在请求PA服务时会调用Ability.connectAbility连接PA,连接成功后,需要在onConnect返回一个remote对象,供FA向PA发送消息
@Override
public IRemoteObject onConnect(Intent intent) {
return remote.asObject();
}
3.新建一个变量保存订阅者的信息,多个订阅者就新建数组变量
private static IRemoteObject myJsRemoteObject;
4.按照FA请求时发送的操作码messageCode = code,来进行相应的操作,比如code=1001、1002
switch (code) {
case 1001: { //js启动初始化,>> 订阅java >> java订阅remoteJava
HiLog.info(LABEL_LOG, "case 1001");
myJsRemoteObject = data.readRemoteObject();
reply.writeString("true"); // 上报连接成功到localJs
break;
}
case 1002: { // 点击开始游戏按钮 1002 >> 102 >> 12
HiLog.info(LABEL_LOG, "case 1002 data:" data.readString());
// 连接对方设备的Remoteservice
Operation remoteservice = new Intent.OperationBuilder()
.withDeviceId(getRemoteDeviceId())
.withBundleName("com.liangzili.demos")
.withAbilityName("com.liangzili.demos.RemoteServiceAbility")
.withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
.build();
Intent remoteserviceIntent = new Intent();
remoteserviceIntent.setParam("start", true);
remoteserviceIntent.setOperation(remoteservice);
boolean connectRes = connectAbility(remoteserviceIntent, new IAbilityConnection() {
@Override
public void onAbilityConnectDone(ElementName elementName, IRemoteObject iRemoteObject, int i) {
HiLog.info(LABEL_LOG, "连接成功");
// 到这里就连接成功了,将remote得到的信息保存到全局变量
myRemote = iRemoteObject;
// 关闭dialog
try {
MessageParcel data = MessageParcel.obtain();
MessageParcel reply = MessageParcel.obtain();
MessageOption option = new MessageOption();
myRemote.sendRequest(102, data, reply, option); //转发来自js的消息到remote
reply.reclaim();
data.reclaim();
} catch (RemoteException e) {
HiLog.info(LABEL_LOG, e.toString());
}
}
@Override
public void onAbilityDisconnectDone(ElementName elementName, int i) {
HiLog.info(LABEL_LOG, "连接失败");
}
});
break;
}
case 102: { //
HiLog.info(LABEL_LOG, "case 102 data:" data.readString());
// 关闭dialog
try {
MessageParcel newdata = MessageParcel.obtain();
newdata.writeString("true"); // 事件的内容
myJsRemoteObject.sendRequest(12, newdata, reply, option); //向js订阅者发送消息
reply.reclaim();
data.reclaim();
} catch (RemoteException e) {
HiLog.info(LABEL_LOG, e.toString());
}
reply.writeString("true");
break;
}
case 1003: { // 小球通过了出口,并且data中携带了坐标 1003 >> 103 >> 13
HiLog.info(LABEL_LOG, "case 1003 data:" data.readString());
try {
myRemote.sendRequest(103, data, reply, option); //转发来自js的消息到remote
reply.reclaim();
data.reclaim();
} catch (RemoteException e) {
HiLog.info(LABEL_LOG, e.toString());
}
reply.writeString("true");
break;
}
case 103: {
HiLog.info(LABEL_LOG, "case 103,data:" data.readString());
myJsRemoteObject.sendRequest(13, data, reply, option); //向js订阅者发送消息
reply.reclaim();
data.reclaim();
reply.writeString("true");
break;
}
}
总结:目前版本我还没找到js API直接remote通信的接口,所以这个项目js和远端js通信,整体流程就是 js >> java >> remoteJava >> remoteJs。
另外关于陀螺仪传感器和游戏部分相关代码比较简单,感兴趣的可以直接下载源码体验 https://gitee.com/liangzili/xunlianying
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved