大家好,关于游戏网站app源码分享很多朋友都还不太明白,今天小编就来为大家分享关于游戏公司网站源码的知识,希望对各位有所帮助!
石头、纸和剪刀
我将演示如何使用SwiftUI4实现一个基本的Multipeer连接应用程序,不需要UIKit!
事不宜迟,让我们开始吧!
应用结构
我们的应用程序的基本结构如下:
一个MultipeerSession对象,用于处理与配对节点的配对和通信PairView将向用户显示可用同伴的列表,并允许他们邀请他们参加游戏GameView将显示游戏控件并向用户显示他们是赢还是输
游戏将是一个基本的“石头、纸、剪刀”游戏。用户将相互配对,然后他们将看到三个选项,石头、纸或剪刀。当用户选择一个动作时,它将被发送到对手的设备,一旦计时器到了,结果就会显示出来。
有了基本的概述,让我们深入研究一些代码。
代码
我们将从创建MultipeerSession对象开始。首先,我们需要将MultipeerConnectivity导入到我们的类中,并继承NSObject和ObrvableObject。
classRPSMultipeerSession:NSObject,ObservableObject{\nprivateletserviceType=&34;\nprivatevarmyPeerID:MCPeerID\n\npublicletserviceAdvertiser:MCNearbyServiceAdvertiser\npublicletserviceBrowser:MCNearbyServiceBrowser\npublicletsession:MCSession\n}
在这里,我们创建了一个serviceType字符串,它将让其他正在扫描对等点的设备知道我们正在使用RPS应用程序并且仅在寻找RPS对等点。这个字符串可以是任何东西来区分我们的Multipeer服务和其他服务。然后我们创建一些实例变量来保存我们的MCPeerID、MCNearbyServiceAdvertiser、MCNearbyServiceBrowser和MCSession。这些字段需要公开,以便我们可以在RPSMultipeerSession类之外对它们执行操作。
在我们对象的init()内部,我们需要为上面创建的变量赋值。
init(username:String){\nmyPeerID=MCPeerID(displayName:username)\n\nsession=MCSession(peer:peerID,securityIdentity:nil,encryptionPreference:.none)\nserviceAdvertiser=MCNearbyServiceAdvertiser(peer:peerID,discoveryInfo:nil,serviceType:serviceType)\nserviceBrowser=MCNearbyServiceBrowser(peer:peerID,serviceType:serviceType)\nsuper.init()\n}
在我们的应用程序中,我们将允许用户创建用户名,以便更轻松地发现对等点。在这里,我们将提供的用户名作为初始化程序中的参数,并从中创建一个MCPeerID。
同样在初始化器内部,我们创建:
session:用于发送和接收RPS动作serviceAdvertiser:用于向附近的玩家宣传我们自己serviceBrowser:用于查找附近可用的玩家
并且不要忘记调用super.init()来调用超类的init方法!
接下来,我们需要考虑如何从对等方接收数据。稍后,我们将为我们的会话对象创建一个委托,该委托将从我们的对等方接收一个数据对象,然后我们可以将其转换为更易于使用的东西。
由于我们实际上只有四个选项(石头、纸、剪刀和无),我们将使用枚举来使处理响应更具可读性和更容易使用。
像这样放置在与我们的RPSMultipeerSession类相同的文件中就足够了:
enumMove:String,CaseIterable,CustomStringConvertible{\ncaserock,paper,scissors,unknown\n\nvardescription:String{\nswitchself{\ncase.rock:return&34;\ncase.paper:return&34;\ncase.scissors:return&34;\ndefault:return&34;\n}\n}\n}
稍后我们将使用移动的字符串表示来向我们的玩家显示图像。通过使用CustomStringConvertible,我们可以减少执行此操作所需的代码量。
现在我们已经创建并可用了Move枚举,我们应该考虑需要为我们的视图提供什么类型的数据。我们知道,我们的PairView将允许玩家找到并与他们的朋友配对,它需要访问当前可用同伴的列表。
同样的视图需要知道我们何时收到来自其他玩家的邀请,以及该玩家是谁。GameView需要知道我们何时收到对手的动作。
我们的多个视图可能会发现了解我们当前是否与玩家配对很有用,最后,我们的PairView需要有某种方式来接受或拒绝来自另一个玩家的邀请。
@PublishedvaravailablePeers:[MCPeerID]=[]\n@PublishedvarreceivedMove:Move=.unknown\n@PublishedvarrecvdInvite:Bool=false\n@PublishedvarrecvdInviteFrom:MCPeerID?=nil\n@Publishedvarpaired:Bool=false\n@PublishedvarinvitationHandler:((Bool,MCSession?)->Void)?
总之,我们的RPSMultipeerSession中将有六个@Published属性。使这些变量@Published使我们的视图不仅可以看到变量的值,而且可以在值更改时通知它们。
除此之外,我们需要为我们的会话、serviceAdvertiser和serviceBrowser创建一些委托。让我们从最长的MCSessionDelegate开始。
会话委托具有处理方法:
当对等点更改状态(已连接、已断开、正在连接)时当我们从对等点接收数据时当我们从对等点收到InputStream当我们从对等点收到资源时(有或没有进展)当我们从对等端收到证书时(身份验证)
我们实际上只关心其中两种方法:当对等方更改状态时以及我们从用户接收数据时。即使是这种情况,这些方法中的每一个都需要在委托内部实现。
Swift有一个简洁的特性,叫做扩展。如果您不熟悉,扩展基本上可以让您将代码添加到任何Swift类。
可以在String类上创建一个扩展来对字符串执行任何类型的操作。扩展非常强大,我强烈建议您查看细节,但现在这应该是让我们继续前进的充分介绍。
为了防止我们的RPSMultipeerSession变得太大而无法处理,我们将利用Swift的扩展来实现这些委托。我们可以简单地做:
extensionRPSMultipeerSession:MCSessionDelegate
并在那里实现委托函数,在主类之外,但仍然在同一个文件中。可以将这些代表放在单独的文件中,但我个人选择将它们全部放在一个文件中。
extensionRPSMultipeerSession:MCSessionDelegate{\nfuncsession(_session:MCSession,peerpeerID:MCPeerID,didChangestate:MCSessionState){\nlog.info(&34;)\nswitchstate{\ncaseMCSessionState.notConnected:\n//Peerdisconnected\nbreak\ncaseMCSessionState.connected:\n//Peerconnected\nbreak\ndefault:\n//Peerconnectingorsomethingelse\nbreak\n}\n}\n\nfuncsession(_session:MCSession,didReceivedata:Data,fromPeerpeerID:MCPeerID){\nifletstring=String(data:data,encoding:.utf8),letmove=Move(rawValue:string){\n//Receivedmovefrompeer\n}else{\nlog.info(&34;)\n}\n}\n\npublicfuncsession(_session:MCSession,didReceivestream:InputStream,withNamestreamName:String,fromPeerpeerID:MCPeerID){\nlog.error(&34;)\n}\n\npublicfuncsession(_session:MCSession,didStartReceivingResourceWithNameresourceName:String,fromPeerpeerID:MCPeerID,withprogress:Progress){\nlog.error(&34;)\n}\n\npublicfuncsession(_session:MCSession,didFinishReceivingResourceWithNameresourceName:String,fromPeerpeerID:MCPeerID,atlocalURL:URL?,withErrorerror:Error?){\nlog.error(&34;)\n}\n\npublicfuncsession(_session:MCSession,didReceiveCertificatecertificate:[Any]?,fromPeerpeerID:MCPeerID,certificateHandler:@escaping(Bool)->Void){\ncertificateHandler(true)\n}\n}
就像我之前说的,这是一个*大*。确保使用Xcode的自动完成功能来获得声明的函数。
如您所见,大多数函数只是向控制台打印一行,实际上根本不做任何事情。这是因为我们的应用程序不支持发送或接收流或资源。不过,这可能会随着教程的进行而改变。
我们还没有完成!如果您按照代码进行操作,您可能已经注意到委托实际上并没有做任何事情。我们需要实现响应对等连接状态变化和接收对手数据的逻辑。我将在第2部分详细介绍如何处理这些事件,所以现在,让我们继续。
接下来,我们将实现MCNearbyServiceAdvertiserDelegate。这个更容易消化:
extensionRPSMultipeerSession:MCNearbyServiceAdvertiserDelegate{\nfuncadvertiser(_advertiser:MCNearbyServiceAdvertiser,didNotStartAdvertisingPeererror:Error){\nlog.error(&34;)\n}\n\nfuncadvertiser(_advertiser:MCNearbyServiceAdvertiser,didReceiveInvitationFromPeerpeerID:MCPeerID,withContextcontext:Data?,invitationHandler:@escaping(Bool,MCSession?)->Void){\nlog.info(&34;)\n}\n}
服务广告主有两种方法:一种是在广告主由于某种原因无法开始投放广告时调用,另一种是在我们收到其他玩家的邀请时调用。后者将再次在第2部分中实施!
最后但同样重要的是,我们需要实现MCNearbyServiceBrowserDelegate。
extensionRPSMultipeerSession:MCNearbyServiceBrowserDelegate{\nfuncbrowser(_browser:MCNearbyServiceBrowser,didNotStartBrowsingForPeerserror:Error){\n//TODO:Telltheusersomethingwentwrongandtryagain\nlog.error(&34;)\n}\n\nfuncbrowser(_browser:MCNearbyServiceBrowser,foundPeerpeerID:MCPeerID,withDiscoveryInfoinfo:[String:String]?){\nlog.info(&34;)\n//Addthepeertothelistofavailablepeers\n}\n\nfuncbrowser(_browser:MCNearbyServiceBrowser,lostPeerpeerID:MCPeerID){\nlog.info(&34;)\n//Removelostpeerfromlistofavailablepeers\n}\n}
此委托具有在以下情况下调用的方法:
浏览器由于某种原因无法开始浏览浏览器找到了一个附近的对等点,它正在宣传我们的serviceType浏览器丢失了一个附近的对等点,该对等点正在宣传我们的serviceType
现在我们已经设置好了代理,我们可以将它们应用到我们的会话、serviceAdvertiser和serviceBrowser。
session.delegate=self\nserviceAdvertiser.delegate=self\nserviceBrowser.delegate=self\n\nserviceAdvertiser.startAdvertisingPeer()\nserviceBrowser.startBrowsingForPeers()
在调用super.init()之后,我们将它添加到我们的init()中。这将分配代表并开始向/为同行做广告和浏览。
我们快完成了,但我们不能忘记告诉我们的广告商和浏览器在deinit()内部停止
deinit{\nserviceAdvertiser.stopAdvertisingPeer()\nserviceBrowser.stopBrowsingForPeers()\n}
现在我们已经完成了所有这些,我们的RPSMultipeerSession.swift文件应该如下所示:
//\n//RPSMultipeerSession.swift\n//RPS\n//\n//CreatedbyJoeDiragion7/28/22.\n//\n\nimportMultipeerConnectivity\nimportos\n\nenumMove:String,CaseIterable,CustomStringConvertible{\ncaserock,paper,scissors,unknown\n\nvardescription:String{\nswitchself{\ncase.rock:return&34;\ncase.paper:return&34;\ncase.scissors:return&34;\ndefault:return&34;\n}\n}\n}\n\nclassRPSMultipeerSession:NSObject,ObservableObject{\nprivateletserviceType=&34;\nprivatevarmyPeerID:MCPeerID\n\npublicletserviceAdvertiser:MCNearbyServiceAdvertiser\npublicletserviceBrowser:MCNearbyServiceBrowser\npublicletsession:MCSession\n\nprivateletlog=Logger()\n\n@PublishedvaravailablePeers:[MCPeerID]=[]\n@PublishedvarreceivedMove:Move=.unknown\n@PublishedvarrecvdInvite:Bool=false\n@PublishedvarrecvdInviteFrom:MCPeerID?=nil\n@Publishedvarpaired:Bool=false\n@PublishedvarinvitationHandler:((Bool,MCSession?)->Void)?\n\ninit(username:String){\nletpeerID=MCPeerID(displayName:username)\nself.myPeerID=peerID\n\nsession=MCSession(peer:peerID,securityIdentity:nil,encryptionPreference:.none)\nserviceAdvertiser=MCNearbyServiceAdvertiser(peer:peerID,discoveryInfo:nil,serviceType:serviceType)\nserviceBrowser=MCNearbyServiceBrowser(peer:peerID,serviceType:serviceType)\nsuper.init()\n\nsession.delegate=self\nserviceAdvertiser.delegate=self\nserviceBrowser.delegate=self\n\nserviceAdvertiser.startAdvertisingPeer()\nserviceBrowser.startBrowsingForPeers()\n}\n\ndeinit{\nserviceAdvertiser.stopAdvertisingPeer()\nserviceBrowser.stopBrowsingForPeers()\n}\n}\n\nextensionRPSMultipeerSession:MCSessionDelegate{\nfuncsession(_session:MCSession,peerpeerID:MCPeerID,didChangestate:MCSessionState){\nlog.info(&34;)\nswitchstate{\ncaseMCSessionState.notConnected:\n//Peerdisconnected\nbreak\ncaseMCSessionState.connected:\n//Peerconnected\nbreak\ndefault:\n//Peerconnectingorsomethingelse\nbreak\n}\n}\n\nfuncsession(_session:MCSession,didReceivedata:Data,fromPeerpeerID:MCPeerID){\nifletstring=String(data:data,encoding:.utf8),letmove=Move(rawValue:string){\n//Receivedmovefrompeer\n}else{\nlog.info(&34;)\n}\n}\n\npublicfuncsession(_session:MCSession,didReceivestream:InputStream,withNamestreamName:String,fromPeerpeerID:MCPeerID){\nlog.error(&34;)\n}\n\npublicfuncsession(_session:MCSession,didStartReceivingResourceWithNameresourceName:String,fromPeerpeerID:MCPeerID,withprogress:Progress){\nlog.error(&34;)\n}\n\npublicfuncsession(_session:MCSession,didFinishReceivingResourceWithNameresourceName:String,fromPeerpeerID:MCPeerID,atlocalURL:URL?,withErrorerror:Error?){\nlog.error(&34;)\n}\n\npublicfuncsession(_session:MCSession,didReceiveCertificatecertificate:[Any]?,fromPeerpeerID:MCPeerID,certificateHandler:@escaping(Bool)->Void){\ncertificateHandler(true)\n}\n}\n\nextensionRPSMultipeerSession:MCNearbyServiceAdvertiserDelegate{\nfuncadvertiser(_advertiser:MCNearbyServiceAdvertiser,didNotStartAdvertisingPeererror:Error){\nlog.error(&34;)\n}\n\nfuncadvertiser(_advertiser:MCNearbyServiceAdvertiser,didReceiveInvitationFromPeerpeerID:MCPeerID,withContextcontext:Data?,invitationHandler:@escaping(Bool,MCSession?)->Void){\nlog.info(&34;)\n}\n}\n\nextensionRPSMultipeerSession:MCNearbyServiceBrowserDelegate{\nfuncbrowser(_browser:MCNearbyServiceBrowser,didNotStartBrowsingForPeerserror:Error){\n//TODO:Telltheusersomethingwentwrongandtryagain\nlog.error(&34;)\n}\n\nfuncbrowser(_browser:MCNearbyServiceBrowser,foundPeerpeerID:MCPeerID,withDiscoveryInfoinfo:[String:String]?){\nlog.info(&34;)\n//Addthepeertothelistofavailablepeers\n}\n\nfuncbrowser(_browser:MCNearbyServiceBrowser,lostPeerpeerID:MCPeerID){\nlog.info(&34;)\n//Removelostpeerfromlistofavailablepeers\n}\n}
关注七爪网,获取更多APP/小程序/网站源码资源!
文章分享结束,游戏网站app源码分享和游戏公司网站源码的答案你都知道了吗?欢迎再次光临本站哦!
