ios Scenekit三维开发以及外接SpriteKit二维界面开发
来源:互联网 发布:linux 创建www用户 编辑:程序博客网 时间:2024/06/03 10:10
1.File->New ->Project...
2.选择Game模板工程,然后点击Next;
3.设置工程名,GameTechnology选择Scenekit,此为三维模板基类;SpriteKit为二维游戏的基础模板;语言选择的是ObejectC,当然了,好多人是选择swift的,这个好开发嘛;点击Next,选择工程保存位置;OK,工程建好了。
4.然后运行查看效果,是一个支持手势操作的旋转的飞机。下方有一个统计面板。方便开发时候查看性能,发布的时候可以代码关闭。
5.接下来说一些技术:
5.1 加载obj文件方法
NSString* resPath = [[NSBundle mainBundle] resourcePath]; NSString * str2 = @"/art.scnassets/car/yjjcar.obj"; NSString *string = [resPath stringByAppendingString:str2]; NSURL* nsurl = [NSURL fileURLWithPath:string]; MDLAsset *asset = [[MDLAsset alloc] initWithURL:nsurl]; carnode = [SCNNode nodeWithMDLObject:[asset objectAtIndex:0]]; carnode.scale = SCNVector3Make(0.01, 0.01, 0.01); [self.scene.rootNode addChildNode:carnode];
5.2 模型旋转
floorNode.transform = SCNMatrix4Rotate(floorNode.transform, M_PI/2, 1, 0, 0); [self.scene.rootNode addChildNode:floorNode];
5.3 计时器
[NSTimer scheduledTimerWithTimeInterval:0.15 target:self selector:@selector(actionTimer:) userInfo:nil repeats:YES];
- (void)actionTimer:(NSTimer *)timer{}
5.4 添加手势操作
初始化的时候
[selfaddGesture];
addGesture定义
- (void)addGesture{ //一指拖拽手势 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePan:)]; pan.minimumNumberOfTouches = 1; pan.maximumNumberOfTouches = 1; pan.delegate = self; [self.view addGestureRecognizer:pan]; UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scale:)]; UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotatePiece:)]; [pinchRecognizer setDelegate:self]; [self.view addGestureRecognizer:pinchRecognizer]; [self.view addGestureRecognizer:rotationGesture];}
- (void)handlePan:(UITapGestureRecognizer *)gestureRecognizer{ static float previousX,previousY; CGPoint p = [gestureRecognizer locationInView:self.sceneView]; if (gestureRecognizer.state == UIGestureRecognizerStateEnded) { }else if (gestureRecognizer.state == UIGestureRecognizerStateBegan) { }else if (gestureRecognizer.state == UIGestureRecognizerStateChanged) { float dx = p.x - previousX; float dy = p.y - previousY; [self transCamera:dx dy:dy]; } previousX = p.x;previousY = p.y;}
-(void)scale:(UIPinchGestureRecognizer*)sender { //当手指离开屏幕时,将lastscale设置为1.0 if([sender state] == UIGestureRecognizerStateEnded) { lastScale = 1.0; return; } CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]); [self ScaleCamera:scale]; lastScale = [sender scale];}
5.5 直接根据顶点数据绘制线条
-(void) drawArea{// //三角形网格场地 SCNGeometrySource *vertexSource = [SCNGeometrySource geometrySourceWithVertices:&g_Vertices[0] count:g_Vertices.size()]; NSData *indexData = [NSData dataWithBytes:&g_Indices[0] length:g_Indices.size()*4]; SCNGeometryElement *element = [SCNGeometryElement geometryElementWithData:indexData primitiveType:SCNGeometryPrimitiveTypeTriangles primitiveCount:g_Indices.size()/3 bytesPerIndex:sizeof(int)]; SCNGeometry *triangles = [SCNGeometry geometryWithSources:@[vertexSource] elements:@[element]]; SCNMaterial* myMaterial = [SCNMaterial new]; [myMaterial setDoubleSided:true]; myMaterial.diffuse.contents =[UIColor colorWithRed:0.336 green:0.336 blue:0.336 alpha:1]; triangles.firstMaterial = myMaterial; SCNNode *trianglesNode = [SCNNode nodeWithGeometry:triangles];// [self.scene.rootNode addChildNode:trianglesNode]; //白色场地边线绘制 SCNGeometrySource *vertexSource2 = [SCNGeometrySource geometrySourceWithVertices:&m_whiteLineVertices[0] count:m_whiteLineVertices.size()]; NSData *indexData2 = [NSData dataWithBytes:&m_whiteLineIndices[0] length:m_whiteLineIndices.size()*4]; SCNGeometryElement *element2 = [SCNGeometryElement geometryElementWithData:indexData2 primitiveType:SCNGeometryPrimitiveTypeLine primitiveCount:m_whiteLineIndices.size()/2 bytesPerIndex:sizeof(int)]; SCNGeometry *line = [SCNGeometry geometryWithSources:@[vertexSource2] elements:@[element2]]; SCNNode *lineNode = [SCNNode nodeWithGeometry:line]; [self.scene.rootNode addChildNode:lineNode]; //黄色场地边线绘制 SCNGeometrySource *vertexSourceYellow = [SCNGeometrySource geometrySourceWithVertices:&m_yellowLineVertices[0] count:m_yellowLineVertices.size()]; NSData *indexDataYellow = [NSData dataWithBytes:&m_yellowLineIndices[0] length:m_yellowLineIndices.size()*4]; SCNGeometryElement *elementYellow = [SCNGeometryElement geometryElementWithData:indexDataYellow primitiveType:SCNGeometryPrimitiveTypeLine primitiveCount:m_yellowLineIndices.size()/2 bytesPerIndex:sizeof(int)]; SCNGeometry *lineYellow = [SCNGeometry geometryWithSources:@[vertexSourceYellow] elements:@[elementYellow]]; SCNMaterial* MaterialYellow = [SCNMaterial new]; [MaterialYellow setDoubleSided:true]; MaterialYellow.diffuse.contents =[UIColor colorWithRed:1 green:1 blue:0 alpha:1]; lineYellow.firstMaterial = MaterialYellow; SCNNode *lineYellowNode = [SCNNode nodeWithGeometry:lineYellow]; [self.scene.rootNode addChildNode:lineYellowNode]; }
这里需要注意:点顺序要一致,绘制线条要尽量少用图元,图元多了性能会下降很明显。
5.6 添加相机节点并控制
//添加摄像机节点 nodeCarema = [SCNNode node]; SCNCamera* ccCamera = [SCNCamera camera]; ccCamera.xFov = 3; ccCamera.yFov = 6; nodeCarema.camera = ccCamera; SCNVector3 defaultPos = [dataPool getCenterOfArea]; nodeCarema.position = SCNVector3Make(defaultPos.x, defaultPos.y, first_height); [mEyeBaseNode addChildNode:nodeCarema];
控制:
-(void) transCamera:(float)dx dy:(float)dy{ SCNVector3 vvv = mEyeBaseNode.position; if (isEntered) { switch (mOperaMode) { case HEIGHT_ZOOM: nodeCarema.transform = SCNMatrix4Translate(nodeCarema.transform, -dx/800, dy/800, 0); break; case ROTATE_VIEW: break; case FREE_VIEW: if(dy>0&&xRotate<=M_PI_4) { xRotate+=0.01; mEyeBaseNode.transform = SCNMatrix4Mult(eyeBaseTransMatrix, SCNMatrix4MakeRotation(xRotate, 1, 0, 0)); } else if(dy<0 && xRotate>=0){ xRotate-=0.01; mEyeBaseNode.transform = SCNMatrix4Mult(eyeBaseTransMatrix, SCNMatrix4MakeRotation(xRotate, 1, 0, 0)); } if(dx>0) eyeRoot.transform = SCNMatrix4Mult(eyeRoot.transform, SCNMatrix4MakeRotation(-0.04, 0, 0, 1)); else eyeRoot.transform = SCNMatrix4Mult(eyeRoot.transform, SCNMatrix4MakeRotation(0.04, 0, 0, 1)); break; default: break; } }}-(void) ScaleCamera:(float)dz{ SCNVector3 vvv = nodeCarema.position; if (isEntered) { switch (mOperaMode) { case HEIGHT_ZOOM: if(dz>1.0 && vvv.z>3) nodeCarema.position = SCNVector3Make(vvv.x, vvv.y, vvv.z-0.3); else if(dz<1.0 && vvv.z<7) nodeCarema.position = SCNVector3Make(vvv.x, vvv.y, vvv.z+0.3); break; case ROTATE_VIEW: if(dz>1.0 && vvv.z>3) nodeCarema.position = SCNVector3Make(vvv.x, vvv.y, vvv.z-0.3); else if(dz<3.0 && vvv.z<7) nodeCarema.position = SCNVector3Make(vvv.x, vvv.y, vvv.z+0.3); break; case FREE_VIEW: if(dz>1.0 && vvv.z>3) nodeCarema.position = SCNVector3Make(vvv.x, vvv.y, vvv.z-0.3); else if(dz<1.0 && vvv.z<7) nodeCarema.position = SCNVector3Make(vvv.x, vvv.y, vvv.z+0.3); break; default: break; } }}
5.7 关闭自带的控制面板
self.sceneView.showsStatistics =NO;
6 Spritekit开发
1>导入SpriteKit.Framework
点击工程名,选择General,点击Linked Frameworks and Library,点击下面的+号,选择SpriteKit.Framework,添加到当前工程中去。
2>新建一个SpriteKit类
#import <SpriteKit/SpriteKit.h>@interface AAPLOverlayScene : SKScene{ SKShapeNode* lhPanel; //离合节点 SKShapeNode* ymPanel; //油门节点 SKShapeNode* scPanel; //刹车节点 SKNode *fangxiangpan; //方向盘节点 SKNode *fxpCenter; //方向盘旋转中心节点 SKLabelNode* qsLabel; //圈数}@property (readonly) SKNode *speedNeedle;-(void)setPanelValueWithAngle:(float)angle YM:(float)ym LH:(float)lh SC:(float)sc;@end
#import "AAPLOverlayScene.h"@implementation AAPLOverlayScene{ float commonScale;}-(id)initWithSize:(CGSize)size { commonScale = 0.4; if (self = [super initWithSize:size]) { //setup the overlay scene self.anchorPoint = CGPointMake(0.5, 0.5); //automatically resize to fill the viewport self.scaleMode = SKSceneScaleModeResizeFill; //make UI larger on iPads BOOL iPad = ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad); float scale = iPad ? 1.5 : 1; //add the speed gauge SKSpriteNode *myImage = [SKSpriteNode spriteNodeWithImageNamed:@"panel3x.png"]; myImage.anchorPoint = CGPointMake(0, 0); CGSize imgSize = myImage.size; myImage.position = CGPointMake(-imgSize.width*0.5*commonScale, -size.height*0.5); myImage.xScale = commonScale * scale; myImage.yScale = commonScale * scale; [self addChild:myImage]; SKLabelNode *myLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"]; myLabel.text = @"Blood, Error!"; myLabel.fontSize = 45; myLabel.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)); myLabel.fontColor = [UIColor colorWithRed:1.0 green:0 blue:0 alpha:1];// [self addChild:myLabel]; //add the needed fangxiangpan = [SKNode node]; SKSpriteNode *needle = [SKSpriteNode spriteNodeWithImageNamed:@"fangxiangpan3x.png"]; needle.anchorPoint = CGPointMake(0.5, 0.5); needle.zRotation = 0; fangxiangpan.position = CGPointMake(140,26*4); [fangxiangpan addChild:needle]; [myImage addChild:fangxiangpan]; qsLabel = [SKLabelNode labelNodeWithFontNamed:@"quanshu"]; qsLabel.name = @"quanshu"; qsLabel.text = @"aaaaaa"; qsLabel.fontSize = 22; qsLabel.fontColor = [SKColor whiteColor]; qsLabel.position = CGPointMake(280,100); [myImage addChild:qsLabel]; UIBezierPath* bkBezierPath = [[UIBezierPath alloc] init]; [bkBezierPath moveToPoint:CGPointMake(0.0, 0.0)]; [bkBezierPath addLineToPoint:CGPointMake(0.0, 114.0)]; [bkBezierPath addLineToPoint:CGPointMake(15, 114.0)]; [bkBezierPath addLineToPoint:CGPointMake(15.0, 0.0)]; UIBezierPath* BezierPath = [[UIBezierPath alloc] init]; [BezierPath moveToPoint:CGPointMake(0.0, 0.0)]; [BezierPath addLineToPoint:CGPointMake(0.0, 114)]; [BezierPath addLineToPoint:CGPointMake(9.0, 114)]; [BezierPath addLineToPoint:CGPointMake(9.0, 0.0)]; SKShapeNode* ymPanel_bk = [SKShapeNode node]; ymPanel_bk.path = bkBezierPath.CGPath; ymPanel_bk.lineWidth = 1.0; ymPanel_bk.fillColor = [UIColor grayColor]; ymPanel_bk.antialiased = NO; ymPanel_bk.position = CGPointMake(383, 50); [myImage addChild:ymPanel_bk]; ymPanel = [SKShapeNode node]; ymPanel.position =CGPointMake(3, 0); ymPanel.path = BezierPath.CGPath; ymPanel.lineWidth = 1.0; ymPanel.fillColor = [UIColor blueColor]; ymPanel.antialiased = NO; ymPanel.yScale = 1; [ymPanel_bk addChild:ymPanel]; SKLabelNode* ymLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"]; ymLabel.name = @"myCounterLabel"; ymLabel.text = @"油门"; ymLabel.fontSize = 20; ymLabel.fontColor = [SKColor whiteColor]; ymLabel.position = CGPointMake(ymPanel_bk.position.x+7.5,18); [myImage addChild:ymLabel]; SKShapeNode* scPanel_bk = [SKShapeNode node]; scPanel_bk.position =CGPointMake(448, 50); scPanel_bk.path = bkBezierPath.CGPath; scPanel_bk.lineWidth = 1.0; scPanel_bk.fillColor = [UIColor grayColor]; scPanel_bk.antialiased = NO; [myImage addChild:scPanel_bk]; scPanel = [SKShapeNode node]; scPanel.position =CGPointMake(3, 0); scPanel.path = BezierPath.CGPath; scPanel.lineWidth = 1.0; scPanel.fillColor = [UIColor redColor]; scPanel.antialiased = NO; scPanel.yScale = 0.5; [scPanel_bk addChild:scPanel]; SKLabelNode* scLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"]; scLabel.name = @"myCounterLabel"; scLabel.text = @"刹车"; scLabel.fontSize = 20; scLabel.fontColor = [SKColor whiteColor]; scLabel.position = CGPointMake(scPanel_bk.position.x+7.5,18); [myImage addChild:scLabel]; SKShapeNode* lhPanel_bk = [SKShapeNode node]; lhPanel_bk.position =CGPointMake(514, 50); lhPanel_bk.path = bkBezierPath.CGPath; lhPanel_bk.lineWidth = 1.0; lhPanel_bk.fillColor = [UIColor grayColor]; lhPanel_bk.antialiased = NO; [myImage addChild:lhPanel_bk]; lhPanel = [SKShapeNode node]; lhPanel.position =CGPointMake(3, 0); lhPanel.path = BezierPath.CGPath; lhPanel.lineWidth = 1.0; lhPanel.fillColor = [UIColor greenColor]; lhPanel.antialiased = NO; lhPanel.yScale = 0.5; [lhPanel_bk addChild:lhPanel]; SKLabelNode* lhLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"]; lhLabel.name = @"Cluster"; lhLabel.text = @"离合"; lhLabel.fontSize = 20; lhLabel.fontColor = [SKColor whiteColor]; lhLabel.position = CGPointMake(lhPanel_bk.position.x+7.5,18); [myImage addChild:lhLabel]; } return self;}-(void)setPanelValueWithAngle:(float)angle YM:(float)ym LH:(float)lh SC:(float)sc{ lhPanel.yScale = lh/100; scPanel.yScale = sc/100; ymPanel.yScale = ym/99; fangxiangpan.zRotation = angle/180*M_PI; NSString* strRoll; int s = (int)angle>>31; if(s == 0) { strRoll = @"左"; }else{ strRoll = @"右"; } const int n = abs(angle); qsLabel.text = strRoll;// NSLog(@"%@@",strRoll); }@end
3>将建好的二维面板导入到Scenekit中去,算是合并场景吧
@property (nonatomic,strong)AAPLOverlayScene *panelView;
_panelView = [[AAPLOverlayScene alloc] initWithSize:self.view.bounds.size]; self.sceneView.overlaySKScene = _panelView; self.sceneView.showsStatistics = NO; [self.view addSubview:self.sceneView];
ok! 三维中有了二维面板了。
模糊效果图如下:
阅读全文
0 0
- ios Scenekit三维开发以及外接SpriteKit二维界面开发
- iOS开发- SceneKit
- iOS SpriteKit/SceneKit/Metal浅析
- iOS开发- 游戏屏幕适配(SpriteKit)
- 使用spritekit开发iOS游戏 【第一章 入门】
- SpriteKit与SceneKit
- ios 3D引擎 SceneKit 开发(1) --起始篇
- ios 3D引擎 SceneKit 开发(1) --起始篇
- ios 3D引擎 SceneKit 开发(2) --贴图篇
- ios 3D引擎 SceneKit 开发(6) --SCNAction
- ios 3D引擎 SceneKit 开发(8) --SCNShape 的使用
- SpriteKit快速入门和新时代iOS游戏开发指南
- 【Swift】SpriteKit开发iOS游戏——场景切换
- SpriteKit快速入门和新时代iOS游戏开发指南
- SpriteKit快速入门和新时代iOS游戏开发指南
- ios 3D引擎 SceneKit 开发(3) --使用3dmax导出DAE文件
- ios 3D引擎 SceneKit 开发(4) --关于旋转的几点问题(1)
- ios 3D引擎 SceneKit 开发(5) --关于旋转的几点问题(2)
- 细数云计算产品和技术
- java运算符中自增和自减问题
- Java 编程题目 第十七题
- Android源码编译第三方app(Android studio编写项目)如何写Android.mk
- Java 编程题目 第十八题
- ios Scenekit三维开发以及外接SpriteKit二维界面开发
- Python2的function cache实现
- HTML 5 Web 存储
- fiddler抓包软件模拟GET和POST的使用
- linux下xdebug安装
- Java 编程题目 第十九题
- rtmp在ffmpeg中的连接流程
- 北京编程简介
- Java 编程题目 第二十题