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的实例。

%E5%BC%80%E5%8F%91IOS%E7%82%B9%E5%AF%B9%E7%82%B9%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%20-%20%E9%A3%8E%E4%BA%91%E6%B0%B8%E6%9D%B0%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD_files/copycode.gif)
//
// 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
%E5%BC%80%E5%8F%91IOS%E7%82%B9%E5%AF%B9%E7%82%B9%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%20-%20%E9%A3%8E%E4%BA%91%E6%B0%B8%E6%9D%B0%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD_files/copycode.gif)

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

%E5%BC%80%E5%8F%91IOS%E7%82%B9%E5%AF%B9%E7%82%B9%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%20-%20%E9%A3%8E%E4%BA%91%E6%B0%B8%E6%9D%B0%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD_files/copycode.gif)
//
// 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
%E5%BC%80%E5%8F%91IOS%E7%82%B9%E5%AF%B9%E7%82%B9%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%20-%20%E9%A3%8E%E4%BA%91%E6%B0%B8%E6%9D%B0%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD_files/copycode.gif)

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

%E5%BC%80%E5%8F%91IOS%E7%82%B9%E5%AF%B9%E7%82%B9%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%20-%20%E9%A3%8E%E4%BA%91%E6%B0%B8%E6%9D%B0%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD_files/copycode.gif)
//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];
}
}
%E5%BC%80%E5%8F%91IOS%E7%82%B9%E5%AF%B9%E7%82%B9%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%20-%20%E9%A3%8E%E4%BA%91%E6%B0%B8%E6%9D%B0%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD_files/copycode.gif)

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

%E5%BC%80%E5%8F%91IOS%E7%82%B9%E5%AF%B9%E7%82%B9%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%20-%20%E9%A3%8E%E4%BA%91%E6%B0%B8%E6%9D%B0%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD_files/copycode.gif)
//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();
}
}
%E5%BC%80%E5%8F%91IOS%E7%82%B9%E5%AF%B9%E7%82%B9%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%20-%20%E9%A3%8E%E4%BA%91%E6%B0%B8%E6%9D%B0%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD_files/copycode.gif)

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

%E5%BC%80%E5%8F%91IOS%E7%82%B9%E5%AF%B9%E7%82%B9%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%20-%20%E9%A3%8E%E4%BA%91%E6%B0%B8%E6%9D%B0%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD_files/copycode.gif)
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();
}
}
%E5%BC%80%E5%8F%91IOS%E7%82%B9%E5%AF%B9%E7%82%B9%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%20-%20%E9%A3%8E%E4%BA%91%E6%B0%B8%E6%9D%B0%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD_files/copycode.gif)

%E5%BC%80%E5%8F%91IOS%E7%82%B9%E5%AF%B9%E7%82%B9%E7%BD%91%E7%BB%9C%E6%B8%B8%E6%88%8F%20-%20%E9%A3%8E%E4%BA%91%E6%B0%B8%E6%9D%B0%20-%20%E5%8D%9A%E5%AE%A2%E5%9B%AD_files/1.png)
Unity3d使用蓝牙(bluetooth)开发IOS点对点网络游戏的更多相关文章
- iOS蓝牙BLE开发
蓝牙是一个标准的无线通讯协议,具有设备成本低.传输距离近和功耗低等特点,被广泛的应用在多种场合.蓝牙一般分为传统蓝牙和BLE两种模式:传统蓝牙可以传输音频等较大数据量,距离近.功耗相对大:而BLE则用 ...
- iOS 上的蓝牙框架 - Core Bluetooth for iOS
原文: Core Bluetooth for iOS 6 Core Bluetooth 是在iOS5首次引入的,它允许iOS设备可以使用健康,运动,安全,自动化,娱乐,附近等外设数据.在iOS 6 中 ...
- Unity3d开发IOS游戏 基础
Unity3d开发IOS游戏 基础 @阿龙 - 649998群 1.先说明两个问题,我在WIN7下面的U3D里面,用了雅黑字体,但是导出为ios后,字体就看不见了,这是为什么呢?这是需要在MAC下找 ...
- Android开发之蓝牙(Bluetooth)操作(一)--扫描已经配对的蓝牙设备
版权声明:本文为博主原创文章,未经博主允许不得转载. 一. 什么是蓝牙(Bluetooth)? 1.1 BuleTooth是目前使用最广泛的无线通信协议 1.2 主要针对短距离设备通讯(10m) ...
- 蓝牙(Bluetooth) IEEE 802.15.1 协议学习
catalogue . 蓝牙概念 . 配对和连接 . 机密安全性 . 蓝牙协议分类 . 蓝牙协议栈 1. 蓝牙概念 蓝牙(Bluetooth)是一种无线技术标准,可实现固定设备.移动设备和楼宇个人域网 ...
- (转)火溶CEO王伟峰:Unity3D手机网游开发
今天看到这篇文章,感觉很不错,尤其是那句“Unity3D的坑我觉得最严重的坑就是没有懂3D的程序员,把Unity当成Office用”. 转自http://blog.csdn.net/wwwang891 ...
- 深入了解Android蓝牙Bluetooth——《基础篇》
什么是蓝牙? 也可以说是蓝牙技术.所谓蓝牙(Bluetooth)技术,实际上是一种短距离无线电技术,是由爱立信公司公司发明的.利用"蓝牙"技术,能够有效地简化掌上电脑.笔记本电 ...
- iOS开发-iOS 10 由于权限问题导致崩溃的那些坑
iOS开发-iOS 10 由于权限问题导致崩溃的那些坑 6月份的WWDC大会结束有一段时间了,相信很多开发者也是在努力工作的闲时用着Xcode8 Beta版学习着新的特性吧. 使用Xcode8写自己 ...
- BLK-MD-BC04-B蓝牙模块开发说明
BLK-MD-BC04-B蓝牙模块开发说明 日期:2011-9-24 浏览次数:4178 BLK-MD-BC04-B蓝牙通信模块, BLK-MD-BC04-B蓝牙通信模块 为本公司自主开发的智 ...
随机推荐
- 记录我学github的路程(二)
2015-12-09 更新 1,现在,本地有了一个库,你可能会想到GitHub创建一个库,并且关联起来.这样,远程的库既可以当作备份,又可以让其他人通过该仓库来协作. 2,步骤: (1)登录GitHu ...
- jquery的常用的容易忘记的东西
1.浅谈jQuery中 wrap() wrapAll() 与 wrapInner()的差异 http://www.jb51.net/article/57336.htm 2. jquery的each方 ...
- [vijos1892]树上的最大匹配(树形DP)
题目:https://vijos.org/p/1892 分析:(100分其实用到各种c++优化,没什么实际意义,所以弄70就可以了) 题目很简单,很容易想出用树形DP,但是求方案数的时候,满满都是细节 ...
- WCF入门 (13)
前言 公司略无聊,周三前同事推荐跳槽,于是会去更新了一下简历,突然发现,快一年了,我竟然想不出我可以往简历上添加点什么值得自豪的东西.下午和小伙伴聊了一会天,他告诉我,可以往简历上写上“英语口语水平有 ...
- G-nav-04
'use strict';define([ 'jquery'], function($) { var nav = { init : function() { $("#burger-menu& ...
- ansible-2添加公钥
该文章摘自:http://www.fwqtg.net/%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E5%B7%A5%E5%85%B7ansible%E5 ...
- Spring-MVC流程图
Spring MVC工作流程图 图一 图二 Spring工作流程描述 1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获: ...
- Java设计模式-访问者模式(Visitor)
访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化.访问者模式适用于数据结构相对稳定算法又易变化的系统.因为访问者模式使得算法操作增加变得容易.若系统数据结构对象易于变化,经 ...
- Ecshop /admin/get_password.php Password Recovery Secrect Code Which Can Predict Vulnerability
目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 Ecshop提供了密码找回功能,但是整个密码找回流程中存在一些设计上的安全隐患 . ...
- Aho-Corasick算法、多模正则匹配、Snort入门学习
希望解决的问题 . 在一些高流量.高IO的WAF中,是如何对规则库(POST.GET)中的字符串进行多正则匹配的,是单条轮询执行,还是多模式并发执行 . Snort是怎么组织.匹配高达上千条的正则规则 ...