iOS服务

目前,有两个部分实现的iOS API,即GameCenter和StoreKit。两者都使用下面解释的相同异步调用模型。

异步方法

当请求异步操作时,该方法将如下所示:

Error purchase(Variant p_params);

参数通常是一个字典,其中包含发出请求所必需的信息,调用将有两个阶段。首先,该方法将立即返回一个错误值。如果错误不是“OK”,则调用操作完成,可能在本地导致错误(没有Internet连接、API配置错误等)。如果错误值为“确定”,将生成响应事件并将其添加到“挂起事件”队列中。例子:

func on_purchase_pressed():
    var result = InAppStore.purchase( { "product_id": "my_product" } )
    if result == OK:
        animation.play("busy") # show the "waiting for response" animation
    else:
        show_error()

# put this on a 1 second timer or something
func check_events():
    while InAppStore.get_pending_event_count() > 0:
        var event = InAppStore.pop_pending_event()
        if event.type == "purchase":
            if event.result == "ok":
                show_success(event.product_id)
            else:
                show_error()

记住,当调用返回OK时,API将 总是 通过挂起的事件接口生成事件,即使是错误或网络超时等。例如,您应该能够安全地阻止等待服务器答复的接口。如果任何一个API没有这样的行为,它应该被视为一个bug。

挂起事件接口由两种方法组成:

  • get_pending_event_count() 返回队列中挂起的事件数。

  • Variant pop_pending_event() 从队列中弹出第一个事件并返回它。

存储工具包

实施于 platform/iphone/in_app_store.mm .

可通过“inappstore”单例访问存储工具包API(始终可从gdscript获得)。它是自动初始化的。它有三种购买方法:

  • Error purchase(Variant p_params);

  • Error request_product_info(Variant p_params);

  • Error restore_purchases();

以及挂起的事件接口

int get_pending_event_count();
Variant pop_pending_event();

购买

通过商店工具包API购买产品ID。

参数

以字典为参数,有一个字段, product_id ,包含产品ID的字符串。示例:

var result = InAppStore.purchase( { "product_id": "my_product" } )

响应事件

响应事件将是具有以下字段的字典:

出错时:

{
  "type": "purchase",
  "result": "error",
  "product_id": "the product id requested"
}

成功时:

{
  "type": "purchase",
  "result": "ok",
  "product_id": "the product id requested"
}

request_product_info

请求产品ID列表上的产品信息。

参数

以字典为参数,有一个字段, product_ids ,包含产品ID列表的字符串数组。例子:

var result = InAppStore.request_product_info( { "product_ids": ["my_product1", "my_product2"] } )

响应事件

响应事件将是具有以下字段的字典:

{
  "type": "product_info",
  "result": "ok",
  "invalid_ids": [ list of requested ids that were invalid ],
  "ids": [ list of ids that were valid ],
  "titles": [ list of valid product titles (corresponds with list of valid ids) ],
  "descriptions": [ list of valid product descriptions ] ,
  "prices": [ list of valid product prices ],
  "localized_prices": [ list of valid product localized prices ],
}

restore_purchases

恢复以前在用户帐户上进行的购买。这将为每个以前购买的产品ID创建响应事件。

响应事件

响应事件将是具有以下字段的字典:

{
  "type": "restore",
  "result": "ok",
  "product id": "product id of restored purchase"
}

游戏中心

实施于 platform/iphone/game_center.mm .

Game Center API可通过“GameCenter”Singleton获得。它有8种方法:

  • bool is_authenticated();

  • Error post_score(Variant p_score);

  • Error award_achievement(Variant p_params);

  • void reset_achievements();

  • void request_achievements();

  • void request_achievement_descriptions();

  • Error show_game_center(Variant p_params);

  • Error request_identity_verification_signature();

加上标准的挂起事件接口。

post_score

将分数发布到游戏中心排行榜。

参数

将字典作为参数,有两个字段:

  • score 浮点数

  • category 具有类别名称的字符串

例子:

var result = GameCenter.post_score( { "score": 100, "category": "my_leaderboard", } )

响应事件

响应事件将是具有以下字段的字典:

出错时:

{
  "type": "post_score",
  "result": "error",
  "error_code": the value from NSError::code,
  "error_description": the value from NSError::localizedDescription,
}

成功时:

{
  "type": "post_score",
  "result": "ok",
}

award_achievement

修改游戏中心成就的进度。

参数

以字典为参数,包含3个字段:

  • name (字符串)成就名称

  • progress (浮动)从0.0到100.0的成就进展(传递到 GKAchievement::percentComplete

  • show_completion_banner (bool)游戏中心是否应在屏幕顶部显示成就横幅

例子:

var result = award_achievement( { "name": "hard_mode_completed", "progress": 6.1 } )

响应事件

响应事件将是具有以下字段的字典:

出错时:

{
  "type": "award_achievement",
  "result": "error",
  "error_code": the error code taken from NSError::code,
}

成功时:

{
  "type": "award_achievement",
  "result": "ok",
}

reset_achievements

清除所有游戏中心成就。函数不接受任何参数。

响应事件

响应事件将是具有以下字段的字典:

出错时:

{
  "type": "reset_achievements",
  "result": "error",
  "error_code": the value from NSError::code
}

成功时:

{
  "type": "reset_achievements",
  "result": "ok",
}

request_achievements

请求玩家在游戏中心取得的所有成就。函数不接受任何参数。

响应事件

响应事件将是具有以下字段的字典:

出错时:

{
  "type": "achievements",
  "result": "error",
  "error_code": the value from NSError::code
}

成功时:

{
  "type": "achievements",
  "result": "ok",
  "names": [ list of the name of each achievement ],
  "progress": [ list of the progress made on each achievement ]
}

request_achievement_descriptions

无论进展如何,请求对所有现有游戏中心成就的描述。函数不接受任何参数。

响应事件

响应事件将是具有以下字段的字典:

出错时:

{
  "type": "achievement_descriptions",
  "result": "error",
  "error_code": the value from NSError::code
}

成功时:

{
  "type": "achievement_descriptions",
  "result": "ok",
  "names": [ list of the name of each achievement ],
  "titles": [ list of the title of each achievement ]
  "unachieved_descriptions": [ list of the description of each achievement when it is unachieved ]
  "achieved_descriptions": [ list of the description of each achievement when it is achieved ]
  "maximum_points": [ list of the points earned by completing each achievement ]
  "hidden": [ list of booleans indicating whether each achievement is initially visible ]
  "replayable": [ list of booleans indicating whether each achievement can be earned more than once ]
}

show_game_center

显示内置游戏中心覆盖,显示排行榜、成就和挑战。

参数

将字典作为参数,有两个字段:

  • view (string)(可选)要显示的视图的名称。接受“默认”、“排行榜”、“成就”或“挑战”。默认为“默认”。

  • leaderboard_name (字符串)(可选)要显示的排行榜的名称。仅在“查看”为“排行榜”时使用(或“默认”配置为显示排行榜)。如果未指定,Game Center将显示聚合排行榜。

实例:

var result = show_game_center( { "view": "leaderboards", "leaderboard_name": "best_time_leaderboard" } )
var result = show_game_center( { "view": "achievements" } )

响应事件

响应事件将是具有以下字段的字典:

关闭时:

{
  "type": "show_game_center",
  "result": "ok",
}

多平台游戏

当你在多平台游戏中工作时,你不会总是有“游戏中心”的单人游戏(例如在PC或Android上运行时)。因为gdscript编译器在编译时查找单例,所以不能只查询单例来查看和使用条件块中需要的内容,还需要将它们定义为有效的标识符(局部变量或类成员)。这是如何在类中解决此问题的示例:

var GameCenter = null # define it as a class member

func post_score(p_score):
    if GameCenter == null:
        return
    GameCenter.post_score( { "value": p_score, "category": "my_leaderboard" } )

func check_events():
    while GameCenter.get_pending_event_count() > 0:
        # do something with events here
        pass

func _ready():
    # check if the singleton exists
    if Globals.has_singleton("GameCenter"):
        GameCenter = Globals.get_singleton("GameCenter")
        # connect your timer here to the "check_events" function