cocos2d-x 调用iOS摄像头 c++ 和 OC混编
来源:互联网 发布:淘宝自动打款时间 编辑:程序博客网 时间:2024/05/29 19:36
这几天在研究cocos2d-x中调用摄像头的功能。
cocos2d-x本身没有这个功能,只能调用原声代码实现。这就涉及到了c++和OC混编码。网上找了好久,都没有什么靠谱的例子。大多数都是下面这种
-(id) init{ if( (self=[super init] )) { CCMenuItem *menuItem1 = [CCMenuItemImage itemFromNormalImage:@"phone_nor.png" selectedImage:@"phone_pre.png" target:self selector:@selector(getPhoto:)]; CCMenu *menu = [CCMenu menuWithItems:menuItem1,nil]; [menu setPosition(40, 40)]; [self addChild:menu]; } return self; }-(void)getPhoto:(UIImagePickerControllerSourceType)sourceType{ UIImagePickerController *picker = [[UIImagePickerController alloc]init]; picker.delegate = self; picker.sourceType = UIImagePickerControllerSourceTypeCamera; picker.wantsFullScreenLayout = YES; [picker presentModalViewController:picker animated:YES]; [[[CCDirector sharedDirector] openGLView] addSubview:picker.view];}
写的不清不楚。最重要的就是这条
picker.delegate = self;这个self不是坑爹么。按照我的理解,这个代码绝对是要写到cocos2d的scene或者layer类中。self就是node的子类。怎么可能做代理?????
后来好不容易找到http://www.cnblogs.com/hanhongmin/p/3498102.html这个教程,才算是豁然开朗。
下面详细记录下我的代码。争取让大部分新手也可以看懂
首先看文件结构
注意,这个HelloWorldScene必须是.mm后缀的,因为只有.mm后缀的文件,才可以既写cpp的代码,又写oc的代码
我们主要关注HelloWorldScene和PickerDelegate这两个类
HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"class HelloWorld : public cocos2d::Layer{public: static cocos2d::Scene* createScene(); virtual bool init(); CREATE_FUNC(HelloWorld); static void showCamera();};#endif // __HELLOWORLD_SCENE_H__
注意这个showCamera方法,这里面是实现调用摄像头的代码,我尝试过非静态方法,结果报错,不知道为什么,以后有时间研究下。
还有一点。因为是混编。所以很多cocos2d的类,比如Scene和之后的Size等,都要写成cocos2d::Scene的形式。不这么写会怎么样?报错呗。为什么要这么写?这个,亲,你实在太基础了。我教不了你了。回去看看编程入门的书籍吧还是。
PickerDelegate.h
#ifndef RonDemo_PickerDelegate_h#define RonDemo_PickerDelegate_h#import <Foundation/Foundation.h>@interface PickerDelegate : NSObject<UINavigationControllerDelegate,UIImagePickerControllerDelegate>@end#endif
这个就是我们最重要的代理类的头文件了。就像我之前说的那个坑爹的问题
picker.delegate = self;这个self就可以换成我们的代理类了。注意,代理类继承的可是NSObject,不是cocos2d的Node或者其他什么东西。这样才可以做代理用。
至于
<UINavigationControllerDelegate,UIImagePickerControllerDelegate>这两个协议是什么?好吧,我承认,我也不知道。反正写不写都正常运行。UINavigationControllerDelegate应该是真的不用。另外一个肯定是跟摄像头有关的代理了。只是目前我仅仅把摄像头调用出来,没做其他事情,所以没有发现而已,后期我会去研究的。
PickerDelegate.m
#import "PickerDelegate.h"@implementation PickerDelegate-(id) init{ if(self = [super init]) { } return self;}- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ //处理数据 UIImage* image = [info valueForKey:UIImagePickerControllerOriginalImage]; [picker dismissModalViewControllerAnimated: YES];}- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{ [picker dismissModalViewControllerAnimated: YES];}@end
这里因为是纯oc代码,所以后缀只用.m就可以了
[picker dismissModalViewControllerAnimated: YES];这句话的意思是关闭摄像头,否则你会发现照完相,或者点击cancel以后,没有任何反应,摄像头还是打开状态。
UIImage* image = [info valueForKey:UIImagePickerControllerOriginalImage];至于这句话,照完相总归要保存照片吧?这里就是干这个用了。当然,我这次的代码他实际上没有任何用处。这里只是怕大家不知道照下来的照片怎么获得才保留了。
HelloWorldScene.mm
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)#include "PickerDelegate.h"#endif#include "HelloWorldScene.h"USING_NS_CC;Scene* HelloWorld::createScene(){ auto scene = Scene::create(); auto layer = HelloWorld::create(); scene->addChild(layer); return scene;}bool HelloWorld::init(){ if ( !Layer::init() ) { return false; } cocos2d::Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); auto listener1 = EventListenerTouchOneByOne::create(); listener1->setSwallowTouches(true); listener1->onTouchBegan = [](Touch* touch, Event* event){ auto target = static_cast<Sprite*>(event->getCurrentTarget()); cocos2d::Point locationInNode = target->convertToNodeSpace(touch->getLocation()); cocos2d::Size s = target->getContentSize(); cocos2d::Rect rect = cocos2d::Rect(0, 0, s.width, s.height); if (rect.containsPoint(locationInNode)) { HelloWorld::showCamera(); return true; } return false; }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener1, this); return true;}void HelloWorld::showCamera() { CCLOG("have camera"); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) if([UIImagePickerController isCameraDeviceAvailable:UIImagePickerControllerCameraDeviceFront]) { NSLog(@"有摄像头"); UIImagePickerController* imagePicker = [[UIImagePickerController alloc] init]; [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera]; PickerDelegate* delegate = [[PickerDelegate alloc] init]; imagePicker.delegate = delegate; [[UIApplication sharedApplication].keyWindow.rootViewController presentModalViewController:imagePicker animated:YES]; } #endif}
最重要的一个类了
1˜3行。判断是不是ios设备。如果是的话,则引用我们上面写的代理类
5˜26行。实在没什么说的。都是cocos2d-x的基本用法。
28˜45行。为了偷懒,我直接写的点击当前屏幕,就调用静态方法showCamera()来打开摄像头。
50˜64行。打开摄像头的代码。53行,主要用来判断当前设备是否有摄像头
55行,初始化代码
56行,设置我们要打开摄像头,而不是相册或者其他什么东西
58,59行。这个就是我们的代理了。之前一直就是被这里坑了好久。
61行
UIApplication sharedApplication用来获取当前设备的句柄
keyWindow网上有好多解释,我觉得最合理的就是“当前活动窗口”
rootViewController顾名思义,根节点视图控制器
presentModalViewController
最后通过模态弹出摄像头,反正我看到的大多数例子,都是这么弹的。
到此,如果没有什么意外的话,运行你的代码点击屏幕,会报错。为什么呢?因为摄像头必须是坑爹的竖屏的。然后不明白的同学百度一下cocos2d-x怎么把ios设备改为竖屏。改好后,运行代码,点击屏幕,此时完美弹出摄像头。
- cocos2d-x 调用iOS摄像头 c++ 和 OC混编
- iOS javascrip和oc混编 互相调用
- iOS C++/OC 混编
- cocos2d-x调用ios的摄像头
- OC和C混编
- ios-OC和Swift混编调用分类问题
- cocos2d-x 中调用oc和java
- iOS Swift和OC混编
- iOS开发之OC和C混编问题
- IOS-Swift混编 调用OC的Block
- cocos2d-x调用摄像头和相册并裁减图片
- C、C++、OC混编
- c,c++,oc混编
- OC 和 Swift 混编 OC 中调用 Swift
- OC 和 Swift 混编 之二 Swift 中调用 OC
- iOS 静态类库 打包 C,C++文件及和OC混编
- iOS 静态类库 打包 C,C++文件及和OC混编
- C++/OC 混编
- Ext 动态添加grid 列数
- 构造函数delete和default关键字分析
- String与StringBuffer的区别
- 数组
- 20-03-其他对象API(Math类)
- cocos2d-x 调用iOS摄像头 c++ 和 OC混编
- 骆驼命名法转小写分隔
- 语义分析的一些方法(三)
- 察看当前数据库被锁的对象
- 用c#编写爬虫在marinetraffic下载船只图片
- 20-04-其他对象API(Date类)
- 积跬步,聚小流------Bootstrap学习记录(3)
- 日经社説 20150811 粘り強く「イスラム国」掃討を
- nodejs 播放媒体文件