Cocos2d开发系列(四)

本文详细介绍了Cocos2d游戏开发中如何使用多场景和Layer进行游戏设计,包括场景间的切换、过渡场景的创建及Layer的合理运用,帮助读者掌握游戏开发中的关键技巧。

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               

 

Learn IPhone andiPad Cocos2d Game Delevopment》的第5章。

一、使用多场景

 

很少有游戏只有一个场景。这个例子是这个样子的:

 

这个Scene中用到了两个Layer,一个Layer位于屏幕上方,标有”Herebe your Game Scores etc“字样的标签,用于模拟游戏菜单。一个Layer位于屏幕下方,一块绿色的草地上有一些随机游动的蜘蛛和怪物,模拟了游戏的场景。

1、加入新场景

一个场景是一个Scene类。加入新场景就是加入更多的Scene类。

有趣的是场景之间的切换。使用[CCDirectorreplaceScene]方法转场时,CCNode有3个方法会被调用:OnEnter、OnExit、 onEnterTransitionDidFinish。

覆盖这3个方法时要牢记,始终要调用super的方法,避免程序的异常(比如内存泄露或场景不响应用户动作)。

-(void)onEnter {

// node的 init方法后调用.

// 如果使用CCTransitionScene方法,在转场开始后调用.

[superonEnter];

}

-(void )onEnterTransitionDidFinish {

// onEnter方法后调用.

// 如果使用CCTransitionScene方法,在转场结束后调用.

[superonEnterTransitionDidFinish];

}

-(void)onExit

{

// node的dealloc 方法前调用.

// 如果使用CCTransitionScene方法,在转场结束时调用.

[superonExit];

}

当场景变化时,有时候需要让某个node干点什么,这时这3个方法就派上用场了。

与在node的init方法和dealloc方法中做同样的事情不同,在onEnter方法执行时,场景已经初始化了;而在onExit方法中,场景的node仍然是存在的。

这样,在进行转场时,你就可以暂停动画或隐藏用户界面元素,一直到转场完成。这些方法调用的先后顺序如下(使用replaceScene 方法):

1. 第2个场景的 scene方法

2. 第2个场景的 init方法

3. 第2个场景的 onEnter方法

4. 转场

5. 第1个场景的 onExit方法

6. 第2个场景的 onEnterTransitionDidFinish方法

7. 第1个场景的 dealloc方法

二、请稍候⋯⋯

切换场景时,如果场景的加载是一个比较耗时的工作,有必要用一个类似“Loading,please waiting…”的场景来过渡一下。用于在转场时过渡的场景是一个“轻量级”的Scene类,可以显示一些简单的提示内容:

typedef enum

{

TargetSceneINVALID = 0,

TargetSceneFirstScene,

TargetSceneOtherScene,

TargetSceneMAX,

} TargetScenes;

 

@interface LoadingScene : CCScene

{

TargetScenes targetScene_;

}

 

+(id)sceneWithTargetScene:(TargetScenes)targetScene;

-(id)initWithTargetScene:(TargetScenes)targetScene;

 

@end

#import "LoadingScene.h"

#import "FirstScene.h"

#import "OtherScene.h"

 

 

@interface LoadingScene(PrivateMethods)

-(void) update:(ccTime)delta;

@end

 

@implementation LoadingScene

 

+(id)sceneWithTargetScene:(TargetScenes)targetScene;

{

return [[[self alloc]initWithTargetScene:targetScene] autorelease];

}

 

-(id)initWithTargetScene:(TargetScenes)targetScene

{

if ((self = [super init]))

{

targetScene_ = targetScene;

 

CCLabel* label = [CCLabellabelWithString:@"Loading ..." fontName:@"Marker Felt" fontSize:64];

CGSize size = [[CCDirectorsharedDirector] winSize];

label.position =CGPointMake(size.width / 2, size.height / 2);

[self addChild:label];

[self scheduleUpdate];

}

return self;

}

 

-(void) update:(ccTime)delta

{

[selfunscheduleAllSelectors];

switch (targetScene_)

{

case TargetSceneFirstScene:

[[CCDirector sharedDirector] replaceScene:[FirstScene scene]];

break;

case TargetSceneOtherScene:

[[CCDirector sharedDirector] replaceScene:[OtherScene scene]];

break;

default:

// NSStringFromSelector(_cmd) 打印方法名

NSAssert2(nil, @"%@: unsupported TargetScene %i", NSStringFromSelector(_cmd), targetScene_);

break;

}

}

 

-(void) dealloc

{

CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);

[super dealloc];

}

 

@end

首先,定义了一个枚举。这个技巧使LoadingScene能用于多个场景的转场,而不是固定地只能在某个场景的切换时使用。继续扩展这个枚举的成员,使LoadingScene能适用与更多目标Scene的转场。

sceneWithTargetScene 方法中返回了一个autorelease的对象。在coco2d自己的类中也是一样的,你要记住在每个静态的初始化方法中使用autorelease

在 方法中,构造了一个CCLabel,然后调用 scheduleUpdate 方法。 scheduleUpdate 方法会在下一个时间(约一帧)后调用update方法。在update方法中,我们根据 sceneWithTargetScene 方法中指定的枚举参数,切换到另一个scene。在这个scene的加载完成之前,LoadingScene会一直显示并且冻结用户的事件响应。

我们不能直接在初始化方法 initWithTargetScene 中直接切换scene,这会导致程序崩溃。记住,在一个Node还在初始化的时候,千万不要在这个scene上调用CCDirectorreplaceScene方法。

LoadingScene的使用很简单,跟一般的scene一样:

CCScene* newScene = [LoadingScene sceneWithTargetScene:TargetSceneFirstScene];

[[CCDirector sharedDirector] replaceScene:newScene];

三、使用Layer

Layer类似Photoshop中层的概念,在一个scene中可以有多个Layer:

typedef enum

{

LayerTagGameLayer,

LayerTagUILayer,

} MultiLayerSceneTags;

 

typedef enum

{

ActionTagGameLayerMovesBack,

ActionTagGameLayerRotates,

}MultiLayerSceneActionTags;

 

@class GameLayer;

@class UserInterfaceLayer;

 

@interface MultiLayerScene :CCLayer

{

bool isTouchForUserInterface;

}

 

+(MultiLayerScene*) sharedLayer;

 

@property (readonly) GameLayer* gameLayer;

@property (readonly) UserInterfaceLayer*uiLayer;

 

+(CGPoint) locationFromTouch:(UITouch*)touch;

+(CGPoint) locationFromTouches:(NSSet *)touches;

 

+(id) scene;

 

@end

@implementation MultiLayerScene

 

static MultiLayerScene* multiLayerSceneInstance;

 

+(MultiLayerScene*) sharedLayer

{

NSAssert(multiLayerSceneInstance != nil, @"MultiLayerScenenot available!");

return multiLayerSceneInstance;

}

-(GameLayer*) gameLayer

{

CCNode* layer = [self getChildByTag:LayerTagGameLayer];

NSAssert([layer isKindOfClass:[GameLayer class]], @"%@: not aGameLayer!", NSStringFromSelector(_cmd));

return (GameLayer*)layer;

}

 

-(UserInterfaceLayer*) uiLayer

{

CCNode* layer = [[MultiLayerScene sharedLayer] getChildByTag:LayerTagUILayer];

NSAssert([layer isKindOfClass:[UserInterfaceLayer class]], @"%@: not aUserInterfaceLayer!", NSStringFromSelector(_cmd));

return (UserInterfaceLayer*)layer;

}

 

+(CGPoint) locationFromTouch:(UITouch*)touch

{

CGPoint touchLocation = [touchlocationInView: [touch view]];

return [[CCDirector sharedDirector] convertToGL:touchLocation];

}

 

+(CGPoint) locationFromTouches:(NSSet*)touches

{

return [self locationFromTouch:[touches anyObject]];

}

 

+(id) scene

{

CCScene* scene = [CCScene node];

MultiLayerScene* layer = [MultiLayerScene node];

[scene addChild:layer];

return scene;

}

 

-(id) init

{

if ((self = [super init]))

{

NSAssert(multiLayerSceneInstance == nil, @"anotherMultiLayerScene is already in use!");

multiLayerSceneInstance = self;

GameLayer* gameLayer = [GameLayer node];

[self addChild:gameLayer z:1 tag:LayerTagGameLayer];

UserInterfaceLayer* uiLayer = [UserInterfaceLayer node];

[self addChild:uiLayer z:2 tag:LayerTagUILayer];

}

return self;

}

 

-(void) dealloc

{

CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);

[super dealloc];

}

@end

MultiLayerScene 中使用了多个Layer:一个GameLayerh 和一个UserInterfaceLayer

MultiLayerScene 使用了静态成员 multiLayerSceneInstance 来实现单例。 MultiLayerScene也是一个Layer,其node方法实际上调用的是实例化方法init——在其中,我们加入了两个Layer,分别用两个枚举LayerTagGameLayerLayerTagUILayer 来检索,如属性方法gameLayer和uiLayer所示。

uiLayer是一个UserInterfaceLayer,用来和用户交互,在这里实际上是在屏幕上方放置一个菜单,可以把游戏的一些统计数字比如:积分、生命值放在这里:

typedef enum

{

UILayerTagFrameSprite,

}UserInterfaceLayerTags;

 

@interface UserInterfaceLayer :CCLayer

{

 

}

 

-(bool) isTouchForMe:(CGPoint)touchLocation;

 

@end

 

@implementation UserInterfaceLayer

 

-(id) init

{

if ((self = [super init]))

{

CGSize screenSize = [[CCDirector sharedDirector] winSize];

 

CCSprite* uiframe = [CCSprite spriteWithFile:@"ui-frame.png"];

uiframe.position = CGPointMake(0, screenSize.height);

uiframe.anchorPoint = CGPointMake(0, 1);

[self addChild:uiframe z:0 tag:UILayerTagFrameSprite];

// Label模拟UI控件( 这个Label没有什么作用,仅仅是演示).

CCLabel* label = [CCLabel labelWithString:@"Here be yourGame Scores etc" fontName:@"Courier" fontSize:22];

label.color = ccBLACK;

label.position = CGPointMake(screenSize.width / 2, screenSize.height);

label.anchorPoint = CGPointMake(0.5f, 1);

[self addChild:label];

self.isTouchEnabled = YES;

}

return self;

}

 

-(void) dealloc

{

CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);

[super dealloc];

}

 

-(

【SCI复现】含可再生能源与储能的区域微电网最优运行:应对不确定性的解鲁棒性与非预见性研究(Matlab代码实现)内容概要:本文围绕含可再生能源与储能的区域微电网最优运行展开研究,重点探讨应对不确定性的解鲁棒性与非预见性策略,通过Matlab代码实现SCI论文复现。研究涵盖多阶段鲁棒调度模型、机会约束规划、需求响应机制及储能系统优化配置,结合风电、光伏等可再生能源出力的不确定性建模,提出兼顾系统经济性与鲁棒性的优化运行方案。文中详细展示了模型构建、算法设计(如C&CG算法、大M法)及仿真验证全过程,适用于微电网能量管理、电力系统优化调度等领域的科研与工程实践。; 适合人群:具备一定电力系统、优化理论和Matlab编程基础的研究生、科研人员及从事微电网、能源管理相关工作的工程技术人员。; 使用场景及目标:①复现SCI级微电网鲁棒优化研究成果,掌握应对风光负荷不确定性的建模与求解方法;②深入理解两阶段鲁棒优化、分布鲁棒优化、机会约束规划等先进优化方法在能源系统中的实际应用;③为撰写高水平学术论文或开展相关课题研究提供代码参考和技术支持。; 阅读建议:建议读者结合文档提供的Matlab代码逐模块学习,重点关注不确定性建模、鲁棒优化模型构建与求解流程,并尝试在不同场景下调试与扩展代码,以深化对微电网优化运行机制的理解。
个人防护装备实例分割数据集 一、基础信息 数据集名称:个人防护装备实例分割数据集 图片数量: 训练集:4,524张图片 分类类别: - Gloves(手套):工作人员佩戴的手部防护装备。 - Helmet(安全帽):头部防护装备。 - No-Gloves(未戴手套):未佩戴手部防护的状态。 - No-Helmet(未戴安全帽):未佩戴头部防护的状态。 - No-Shoes(未穿安全鞋):未佩戴足部防护的状态。 - No-Vest(未穿安全背心):未佩戴身体防护的状态。 - Shoes(安全鞋):足部防护装备。 - Vest(安全背心):身体防护装备。 标注格式:YOLO格式,包含实例分割的多边形坐标和类别标签,适用于实例分割任务。 数据格式:来源于实际场景图像,适用于计算机视觉模型训练。 二、适用场景 工作场所安全监控系统开发:数据集支持实例分割任务,帮助构建能够自动识别工作人员个人防护装备穿戴状态的AI模型,提升工作环境安全性。 建筑与工业安全检查:集成至监控系统,实时检测PPE穿戴情况,预防安全事故,确保合规性。 学术研究与创新:支持计算机视觉在职业安全领域的应用研究,促进AI与安全工程的结合。 培训与教育:可用于安全培训课程,演示PPE识别技术,增强员工安全意识。 三、数据集优势 精准标注与多样性:每个实例均用多边形精确标注,确保分割边界准确;覆盖多种PPE物品及未穿戴状态,增加模型鲁棒性。 场景丰富:数据来源于多样环境,提升模型在不同场景下的泛化能力。 任务适配性强:标注兼容主流深度学习框架(如YOLO),可直接用于实例分割模型开发,支持目标检测和分割任务。 实用价值高:专注于工作场所安全,为自动化的PPE检测提供可靠数据支撑,有助于减少工伤事故。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值