zoukankan      html  css  js  c++  java
  • Unity3d使用蓝牙(bluetooth)开发IOS点对点网络游戏

    著作权声明:本文由http://www.cnblogs.com/icker 原创,欢迎转载分享。转载时请保留该声明和作者博客链接,谢谢!

      最近使用Unity3d制作的IOS游戏需要加入联网对战功功能,因此使用ObjC语言利用IOS SDK的GameKit.framework的Peer-to-peer Connectivity实现了网络连接,在此分享。

    啥话都不说,先上代码。点我下载工程文件

    类NetWorkP2P,继承自NSObject。提供GKSessionDelegate和GKPeerPickerControllerDelegate的实现。并且利用单例模式实现一个类方法+( NetWorkP2P *) sharedNetWorkP2P;此方法返回一个NetWorkP2P的实例。

    复制代码
    复制代码
    //
    // NetWorkP2P.h
    // P2PTapWar
    //
    // Created by on 11-9-14.
    // Copyright 2011年 __MyCompanyName__. All rights reserved.
    //

    #import<Foundation/Foundation.h>
    #import<GameKit/GameKit.h>

    #define AMIPHD_P2P_SESSION_ID @"amiphd-p2p"
    #define START_GAME_KEY @"startgame"
    #define TIME_KEY @"time"
    #define END_GAME_KEY @"endgame"
    #define TAP_COUNT_KEY @"taps"
    #define TIMES_KEY @"times"

    @interface NetWorkP2P : NSObject<GKSessionDelegate,GKPeerPickerControllerDelegate>{

    UInt32 playerScore;
    UInt32 opponentScore;

    UInt32 playerTimes;
    UInt32 opponentTimes;

    NSString
    *opponentID;
    BOOL actingAsHost;
    GKSession
    *gkSession;
    }
    +( NetWorkP2P *) sharedNetWorkP2P;
    -(void)showPeerPickerController;

    -(void)addTheScore: (UInt32)score;
    -(void)addTimes;

    -(UInt32)getOpponentScore;
    -(UInt32)getPlayerScore;
    -(UInt32)getPlayerTimes;
    -(UInt32)getOpponentTimes;

    -(NSString *)getOpponentID;
    @end
    复制代码
    复制代码

    类NetWorkP2P的实现文件,fileName:NetWorkP2P.m

    复制代码
    复制代码
    //
    // NetWorkP2P.m
    // P2PTapWar
    //
    // Created by on 11-9-14.
    // Copyright 2011年 __MyCompanyName__. All rights reserved.
    //

    #import"NetWorkP2P.h"

    @implementation NetWorkP2P
    +(NetWorkP2P *) sharedNetWorkP2P{
    static NetWorkP2P *sharedNetWorkObject;
    if(!sharedNetWorkObject)
    sharedNetWorkObject
    =[[NetWorkP2P alloc] init];
    return sharedNetWorkObject;
    }

    - (id)init
    {
    self
    = [super init];
    if (self) {
    // Initialization code here.
    }

    return self;
    }
    -(UInt32)getPlayerScore{
    return playerScore;
    }
    -(UInt32)getOpponentScore{
    return opponentScore;
    }
    -(UInt32)getOpponentTimes{
    return opponentTimes;
    }
    -(UInt32)getPlayerTimes{
    return playerTimes;
    }
    -(NSString *)getOpponentID
    {
    return opponentID;
    }
    -(void) showPeerPickerController
    {
    if(!opponentID)
    {
    actingAsHost
    =YES;
    GKPeerPickerController
    *peerPickerContrller=[[GKPeerPickerController alloc] init];
    peerPickerContrller.
    delegate=self;
    peerPickerContrller.connectionTypesMask
    =GKPeerPickerConnectionTypeNearby;
    [peerPickerContrller show];
    }
    }
    -(void)addTheScore:(UInt32)score
    {
    playerScore
    +=score;
    NSMutableData
    *message=[[NSMutableData alloc]init];
    NSKeyedArchiver
    *archiver=[[NSKeyedArchiver alloc]initForWritingWithMutableData:message];
    [archiver encodeInt:playerScore forKey:TAP_COUNT_KEY];
    [archiver finishEncoding];
    GKSendDataMode sendMode
    =GKSendDataUnreliable;
    [gkSession sendDataToAllPeers:message withDataMode:sendMode error:NULL];
    [archiver release];
    [message release];

    }
    -(void)addTimes
    {
    playerTimes
    ++;
    NSMutableData
    *message=[[NSMutableData alloc]init];
    NSKeyedArchiver
    *archiver=[[NSKeyedArchiver alloc] initForWritingWithMutableData:message];
    [archiver encodeInt:playerTimes forKey:TIMES_KEY];
    [archiver finishEncoding];
    GKSendDataMode sendMode
    =GKSendDataUnreliable;
    [gkSession sendDataToAllPeers:message withDataMode:sendMode error:NULL];
    [archiver release];
    [message release];
    }
    #pragma mark game logic

    -(void) initGame{
    playerScore
    =0;
    opponentScore
    =0;
    }
    -(void) hostGame{
    [self initGame];
    NSMutableData
    *message=[[NSMutableData alloc] init];
    NSKeyedArchiver
    *archiver=[[NSKeyedArchiver alloc] initForWritingWithMutableData:message];
    [archiver encodeBool:YES forKey:START_GAME_KEY];
    [archiver finishEncoding];

    NSError
    *sendErr=nil;
    [gkSession sendDataToAllPeers:message withDataMode:GKSendDataReliable error:
    &sendErr];
    if (sendErr) {
    NSLog(
    @"send greeting failed : %@",sendErr);
    }
    [message release];
    [archiver release];
    }
    -(void) joinGame{
    [self initGame];
    }
    -(void) showEndGameAlert{
    }
    -(void) endGame{
    opponentID
    =nil;
    [gkSession disconnectFromAllPeers];
    [self showEndGameAlert];
    }

    #pragma mark GKPeerPickerControllerDelegate methods

    -(GKSession *) peerPickerController:(GKPeerPickerController *)picker sessionForConnectionType:(GKPeerPickerConnectionType)type
    {
    if(!gkSession)
    {
    gkSession
    =[[GKSession alloc] initWithSessionID:AMIPHD_P2P_SESSION_ID displayName:nil sessionMode:GKSessionModePeer];
    gkSession.
    delegate=self;
    }
    return gkSession;
    }
    -(void) peerPickerController:(GKPeerPickerController *) picker didConnectPeer:(NSString *)peerID toSession:(GKSession *)session
    {
    NSLog (
    @"connected to peer %@", peerID);
    [session retain];
    // TODO: who releases this?
    [picker dismiss];
    [picker release];
    }
    - (void)peerPickerControllerDidCancel:(GKPeerPickerController *)picker {
    NSLog (
    @"peer picker cancelled");
    [picker release];
    }

    #pragma mark GKSessionDelegate methods

    //START:code.P2PTapWarViewController.peerdidchangestate
    - (void)session:(GKSession *)session peer:(NSString *)peerID
    didChangeState:(GKPeerConnectionState)state {
    switch (state)
    {
    case GKPeerStateConnected:
    [session setDataReceiveHandler: self withContext: nil];
    opponentID
    = peerID;
    actingAsHost
    ? [self hostGame] : [self joinGame];
    break;
    }
    }
    //END:code.P2PTapWarViewController.peerdidchangestate


    //START:code.P2PTapWarViewController.didreceiveconnectionrequestfrompeer
    - (void)session:(GKSession *)session
    didReceiveConnectionRequestFromPeer:(NSString
    *)peerID {
    actingAsHost
    = NO;
    }
    //END:code.P2PTapWarViewController.didreceiveconnectionrequestfrompeer

    - (void)session:(GKSession *)session connectionWithPeerFailed:(NSString *)peerID withError:(NSError *)error {
    NSLog (
    @"session:connectionWithPeerFailed:withError:");
    }

    - (void)session:(GKSession *)session didFailWithError:(NSError *)error {
    NSLog (
    @"session:didFailWithError:");
    }
    #pragma mark receive data from session
    -(void) receiveData: (NSData *) data fromPeer : (NSString *) peerID inSession: (GKSession *) session context:(void*) context{
    NSKeyedUnarchiver
    *unarchiver=[[NSKeyedUnarchiver alloc] initForReadingWithData:data];
    if([unarchiver containsValueForKey:TAP_COUNT_KEY])
    {
    opponentScore
    =[unarchiver decodeIntForKey:TAP_COUNT_KEY];
    }
    if([unarchiver containsValueForKey:TIMES_KEY])
    {
    opponentTimes
    =[unarchiver decodeIntForKey:TIMES_KEY];
    }
    if([unarchiver containsValueForKey:END_GAME_KEY])
    {
    [self endGame];
    }
    if([unarchiver containsValueForKey:START_GAME_KEY])
    {
    [self joinGame];
    }
    [unarchiver release];
    }
    @end
    复制代码
    复制代码

    fileName:NetWorkP2PBinding.m在此文件中实现C语言接口,以方便在UnityScript中调用。

    复制代码
    复制代码
    //NetWorkP2PBinding.mm
    #import"NetWorkP2P.h"

    extern"C"{
    void _showPeerPicker()
    {
    [[NetWorkP2P sharedNetWorkP2P] showPeerPickerController];
    NSLog(
    @"call the mothed _showPeerPicker");
    }

    constchar* _getName()
    {
    return [@"fyn" UTF8String];
    }
    int _getOpponentScore()
    {
    return [[NetWorkP2P sharedNetWorkP2P]getOpponentScore];
    }
    int _getPlayerScore()
    {
    return [[NetWorkP2P sharedNetWorkP2P]getPlayerScore];
    }

    void _addTheScore( UInt32 score)
    {
    [[NetWorkP2P sharedNetWorkP2P] addTheScore:score];
    }
    void _addTheTimes()
    {
    [[NetWorkP2P sharedNetWorkP2P] addTimes];
    }
    int _getOpponentTimes()
    {
    return [[NetWorkP2P sharedNetWorkP2P] getOpponentTimes];
    }
    int _getPlayerTimes()
    {
    return [[NetWorkP2P sharedNetWorkP2P] getPlayerTimes];
    }
    constchar* _getOpponentID()
    {
    return [[[NetWorkP2P sharedNetWorkP2P ]getOpponentID] UTF8String];
    }
    }
    复制代码
    复制代码

    FileName:P2PBinding.cs 这是在Unity3d中C#脚本,在这里面调用NetWorkP2PBinding.mm实现的C语言方法。

    复制代码
    复制代码
    //P2PBinding.cs

    using UnityEngine;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;


    publicclass P2PBinding{
    [DllImport(
    "__Internal")]
    privatestaticexternvoid _showPeerPicker();

    publicstaticvoid showPeerPicker()
    {
    if(Application.platform==RuntimePlatform.IPhonePlayer)
    _showPeerPicker();
    }

    [DllImport(
    "__Internal")]
    privatestaticexternint _getOpponentScore();

    [DllImport(
    "__Internal")]
    privatestaticexternint _getOpponentTimes();

    [DllImport(
    "__Internal")]
    privatestaticexternint _getPlayerScore();

    [DllImport(
    "__Internal")]
    privatestaticexternint _getPlayerTimes();

    [DllImport(
    "__Internal")]
    privatestaticexternvoid _addTheTimes();

    [DllImport(
    "__Internal")]
    privatestaticexternvoid _addTheScore(int score);

    publicstaticint getOpponentScore()
    {
    if(Application.platform==RuntimePlatform.IPhonePlayer)
    {
    return _getOpponentScore();
    }
    return-1;
    }
    publicstaticint getOpponentTimes()
    {
    if(Application.platform==RuntimePlatform.IPhonePlayer)
    {
    return _getOpponentTimes();
    }
    return-1;
    }
    publicstaticint getPlayerScore()
    {
    if(Application.platform==RuntimePlatform.IPhonePlayer)
    {
    return _getPlayerScore();
    }
    return-1;
    }
    publicstaticint getPlayerTimes()
    {
    if(Application.platform==RuntimePlatform.IPhonePlayer)
    {
    return _getPlayerTimes();
    }
    return-1;
    }
    publicstaticvoid addTheScore(int score)
    {
    if(Application.platform==RuntimePlatform.IPhonePlayer)
    {
    _addTheScore(score);
    }
    }
    publicstaticvoid addTheTimes()
    {
    _addTheTimes();
    }
    }
    复制代码
    复制代码

    FileName:GameDate.cs 此文件提供游戏的数据,并保持和NetWorkP2P文件中数据同步,将此文件附加到一个GameObject上。

    复制代码
    复制代码
    using UnityEngine;
    using System.Collections;

    publicclass GameDate : MonoBehaviour {

    publicstring opponentID;

    publicint playerTimes;
    publicint opponentTimes;
    publicint playerScore;
    publicint opponentScore;

    // Use this for initialization
    void Start () {
    P2PBinding.showPeerPicker();
    }

    // Update is called once per frame
    void Update () {
    opponentTimes
    =P2PBinding.getOpponentTimes();
    opponentScore
    =P2PBinding.getOpponentScore();
    }
    }
    复制代码
    复制代码

     

  • 相关阅读:
    微信抢红包算法备注
    APP测试-drozer安装和使用
    APP测试--应用签名信息检测
    绕过CDN获得网站真实IP
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xd5 in position 9: ordinal not in range(128)
    检查APP 数据库.xml文件
    APP本地数据库安全
    APP重新打包签名
    APP完整性检测
    dex2jar和jd-gui联合使用查看代码是否经过混淆处理或者加壳
  • 原文地址:https://www.cnblogs.com/123ing/p/3703792.html
Copyright © 2011-2022 走看看