开始游戏
进行游戏的代码在MultiplayerGameScreen.java文件中。如果用户进入了这个界面,那就意味着有两个用户在这个房间中且游戏开始了。玩家玩这个游戏,并且他也要更新其他玩家的状态。其他玩家在你的界面上显示成绿色小怪物。
随着玩家在界面上移动以完成游戏关卡,需要绘制它的移动轨迹,也要将位置更新发送给远程玩家。参见WorldRenderer.java(multiplayer)
01 | private void renderBob () { |
06 | batch.draw(keyFrame, world.local_bob.position.x + 0 .5f, world.local_bob.position.y - 0 .5f, side * 1 , 1 ); |
07 | sendLocation(world.local_bob.position.x + 0 .5f, world.local_bob.position.y - 0 .5f, side * 1 , 1 ); |
09 | batch.draw(keyFrame, world.local_bob.position.x - 0 .5f, world.local_bob.position.y - 0 .5f, side * 1 , 1 ); |
10 | sendLocation(world.local_bob.position.x - 0 .5f, world.local_bob.position.y - 0 .5f, side * 1 , 1 ); |
消息通过我们在这个示例中所写的工具方法来发送。WarpClient允许客户端将字节数组广播给它所在的房间。可以使用TCP(默认)或UDP来发送。记住我们已经在成功连接到云服务后的第一个界面中初始化了UDP。
01 | private void sendLocation( float x, float y, float width, float height){ |
03 | JSONObject data = new JSONObject(); |
06 | data.put( "width" , width); |
07 | data.put( "height" , height); |
08 | WarpController.getInstance().sendGameUpdate(data.toString()); |
09 | } catch (Exception e) { |
发送给房间的消息是通过onUpdatePeersReceived的回调方法提供的。在这个回调中我们要解析这个消息并识别发送者,消息类型和与此消息绑定的数据。我们根据这些消息做相应的处理。
1 | public void onUpdatePeersReceived(UpdateEvent event) { |
2 | callBack.onGameUpdateReceived( new String(event.getUpdate())); |
02 | JSONObject data = new JSONObject(message); |
03 | float x = ( float )data.getDouble( "x" ); |
04 | float y = ( float )data.getDouble( "y" ); |
05 | float width = ( float )data.getDouble( "width" ); |
06 | float height = ( float )data.getDouble( "height" ); |
07 | renderer.updateEnemyLocation(x, y, width, height); |
08 | } catch (Exception e) { |
游戏结束
当游戏结束后我们只需要更新房间的属性。其他玩家收到通知后需要根据此消息更新他们的UI。
1 | public void updateResult( int code, String msg){ |
4 | HashMap<string, object= "" > properties = new HashMap<string, object= "" >(); |
5 | properties.put( "result" , code); |
6 | warpClient.lockProperties(properties); |
lockProperties
当两个远程玩家同玩游戏时,他们有可能会同时结束游戏,而这会引起资源竞争。这种情况最好交由服务器解决,所以我们使用了lockProperties API。所以当游戏结束时用户向服务器发送一个lockProperties请求将结果属性锁定。一旦这个结果被某个用户锁定,服务器会放弃处理后续对同一个属性的lockProperties请求。点击此处以了解更多此AppWarp仲裁方式。
随着游戏的结束,其他用户得到通知,StartMultiplayerScreen.java根据以下代码将游戏结束的原因显示到界面上。
01 | public void onGameFinished ( int code) { |
02 | if (code==WarpController.GAME_WIN){ |
03 | this .msg = game_loose; |
04 | } else if (code==WarpController.GAME_LOOSE){ |
06 | } else if (code==WarpController.ENEMY_LEFT){ |
07 | this .msg = enemy_left; |
我们也要离开并取消订阅此房间,并且取消{敏感词};如果游戏不在运行状态我们也要删除房间。由于在这个游戏中我们使用的是AppWarp 动态房间,在使用完后最好立即删除(尽管空动态房间在60分钟后都会被自动删除)。
01 | public void handleLeave(){ |
03 | warpClient.unsubscribeRoom(roomId); |
04 | warpClient.leaveRoom(roomId); |
06 | warpClient.deleteRoom(roomId); |
08 | warpClient.disconnect(); |
1 | private void disconnect(){ |
2 | warpClient.removeConnectionRequestListener( new ConnectionListener( this )); |
3 | warpClient.removeChatRequestListener( new ChatListener( this )); |
4 | warpClient.removeZoneRequestListener( new ZoneListener( this )); |
5 | warpClient.removeRoomRequestListener( new RoomListener( this )); |
6 | warpClient.removeNotificationListener( new NotificationListener( this )); |
7 | warpClient.disconnect(); |
用户可以在这里点击并返回MainMenuScreen,然后我们可以重新进行这个过程。但这次我们只需要找到一个房间就可以开始了(因为我们已经连接到了服务器)。
总结
这篇文章中我们看到如何用AppWarp开发多人游戏。 我们在一个现成的libgdx超级跳跃例子基础上用 AppWarp Cloud特性进行拓展。我们同样看到客户端怎样连接到AppWarp上,怎样加入游戏房间。继承概念不受libgdx的影响,并且可以应有与其他任何Java程序中。
使用Robovm发布到iOS 你可以使用 Robovm 来将超级跳跃游戏发布到iOS上. 下面是几步是任何其它项目中都需要做的。另外你需要做如下改变。
1. 将这些属性添加到 robovm.xml 2 | < pattern >org.apache.harmony.xnet.provider.jsse.OpenSSLProvider</ pattern > |
3 | < pattern >org.apache.harmony.security.provider.cert.DRLCertFactory</ pattern > |
4 | < pattern >com.android.org.bouncycastle.jce.provider.BouncyCastleProvider</ pattern > |
5 | < pattern >org.apache.harmony.security.provider.crypto.CryptoProvider</ pattern > |
6 | < pattern >org.apache.harmony.xnet.provider.jsse.JSSEProvider</ pattern > |
7 | < pattern >com.android.org.bouncycastle.jce.provider.JCEMac$SHA1</ pattern > |
2. 使用如下代码从背景中改变屏幕。 1 | Gdx.app.postRunnable( new Runnable() { |
4 | game.setScreen( new MultiplayerGameScreen(game, StartMultiplayerScreen. this )); |
这里另有要求, 我们得到如下错误,因为AppWarp的回调不在UI线程中。 Exception in thread "MessageDispatchThread" java.lang.IllegalArgumentException: Error compiling shader
3. 超级跳跃中声音不可用了,这是因为iOS中的声音是使用RoboVm。
|