[泰然翻译] cocos2d programming guide 场景和菜单

本文详细介绍了使用Cocos2d框架理解游戏场景的概念及场景之间的转换方法,包括如何创建和使用菜单场景进行交互。涵盖了场景的基本使用、场景之间的动画转换、菜单系统的构建以及具体实现步骤,旨在帮助开发者掌握Cocos2d中场景管理和菜单设计的核心技能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:http://www.cocos2d-iphone.org/wi ... 3._menus_and_scenes

cocos2d programming guide系列由sile(泰然翻译组)翻译本系列其他文章传送门:http://ityran.com/thread-149-1-1.html

在这节里,你将会学习到cocos2d是怎么帮助你理解场景的和怎么在场景与场景之间进行转换。转换场景是很简单的,我们只要覆盖CCMenu和相关的类就可以了,这个方法就跟创建菜单场景一样简单。

场景

cocos2d里的场景就一个可见的特殊结点扮演着其它父结点的角色。你可以用你喜欢的方式来使用它,典型的用法可能是在游戏中创建一个可玩的部分,页面场景,高分榜等等,一个场景代表着CCScene类。如果一个场景是可见的、有正在运行的动作,表示它是运行的状态。任何时间片内只能有一个场景在运行。不过可能会把一个其它的场景压入到正在运行场景的上层,那么就要终止当前的场景以运行新的场景。当把这个新压入的场景运行完后就继续运行先前的场景。或者可以这么理解,有一个全新的场景代替了其它的(自从它占用了更少的内存后变得更加完美)。压入和弹出或者代替操作直接有导演对象(CCCDirector)控制。这会找到程序托管(即AppDelegate.m文件)。在applicationDidFinishLaunching方法的底部,你会发现一行如下的代码:

[[CCDirector sharedDirector] runWithScene: [HelloWorldscene]];

它的作用是告诉导演对象开始运行被给出的场景。用来替换场景的另外一种方法,举例来说,当用户点击play按钮或者当游戏结束你想退回到主菜单时,直接调用replaceScene在导演层:

[[CCDirector sharedDirector] replaceScene: [SomeOtherScenescene]];

它的作用是终止当前场景,开始下一个。你可以等运行完后重启先前的场景通过再一次调用replaceScene。如果你仅仅想终止当前的场景,请通过pushScence方法来代替replaceScene方法,然后你可以调用popScene来终止新的场景或者继续继续旧的。但是请注意一点,在iphone里内存是有限的,所有在栈里存在的场景都是需要消耗内存的。所以要让导演对象做手头的事情,比如中止/继续当前的场景,详情请看CCDirector reference


Fancy转换(动画转换)

CC*Transition支持很多场景之间的Fancy转换:

[[CCDirectorsharedDirector] replaceScene:[CCTransitionFadetransitionWithDuration:0.5f scene:[SomeOtherScenescene]]];

一些相同的转换:

CCTransitionFade

CCTransitionFlipAngular

CCTransitionShrinkGrow

CCTransitionMoveInB

CCTransitionMoveInT

CCTransitionMoveInL

CCTransitionMoveInR

CCTransitionFadeTR

CCTransitionFadeUp

CCTransitionFlipX

CCTransitionFlipY

CCTransitionPageTurn

CCTransitionCrossFade

查看API文档可以看到更多的转换类型。

菜单

菜单提供一种方式让用户通过按钮来与游戏进行交互。人们通过按钮来直接控制场景的转换,它们也经常被用户当作一种方便灵活的方式来控制游戏

创建一个简单的菜单实例

CCMenu *myMenu = [CCMenu menuWithItems:nil];

它是一个空的菜单里面没有任何按钮,为了让菜单有用,你将需要往里面添加一些菜单项。

这里有一些经典的菜单项:

CCMenuItemAtlasFont

CCMenuItemFont

CCMenuItemImage

CCMenuItemLabel

CCMenuItemSprite

CCMenuItemToggle

单独的菜单项之间有着微妙的不同,但是基本上当按钮被触摸了后他们允许你选择一个被调用的目标和选择器

最简单的菜单项是创建CCMenuItemImage,选择一个指定的图片作为触摸区域里的菜单项

CCMenuItemImage *menuItem1 = [CCMenuItemImageitemFromNormalImage:@"myFirstButton.png"

               selectedImage: @"myFirstButton_selected.png"

               target:self

               selector:@selector(doSomething:)];

itemFromNormalImage是你用来作为菜单项的图片

selectedImage是作为按钮被触控使用时的图片

target是指当菜单项被按后哪个对象需要响应。在这个例子中,当菜单被创建后self指向了这个场景

selector作为目标方法被调用

注意:这里的@selector(doSomething) 和@selector(doSomething:)是不同的(注意额外的冒号)。有冒号时,菜单项被传递给方法。这是非常有用的如果你想在方法被调用的时候传递额外的数据。你可以用菜单项tag来决定如何进行。你也许会选择MenuItemType的子类来存储额外的可以使用doSomething:的信息。一旦你创建了你的菜单项,你可以用相通的方式把事例添加到任意的CCNode。

[myMenu addChild:menuItem1];

其次,你可以一次创建几个菜单项并把它们添加到menuWithItems控制器里像下面的样子(在这个例子里,请记得nil terminate控制器)
CCMenu *myMenu = [CCMenu menuWithItems:menuItem1, menuItem2, menuItem3, nil];
CCMenu也提供一些方便的方法来设置你的菜单,像alignitemsVertically和alignitemsInRows:
[myMenu alignItemsVertically];
然后像下面一样把它们合并到一起


// Create some menu items
CCMenuItemImage * menuItem1 = [CCMenuItemImage itemFromNormalImage:@"myfirstbutton.png"
                selectedImage: @"myfirstbutton_selected.png"
                target:self
                selector:@selector(doSomethingOne:)];

CCMenuItemImage * menuItem2 = [CCMenuItemImage itemFromNormalImage:@"mysecondbutton.png"
                 selectedImage: @"mysecondbutton_selected.png"
                 target:self
                 selector:@selector(doSomethingTwo:)];
  
CCMenuItemImage * menuItem3 = [CCMenuItemImage itemFromNormalImage:@"mythirdbutton.png"
                  selectedImage: @"mythirdbutton_selected.png"
                  target:self
                  selector:@selector(doSomethingThree:)];

// Create a menu and add your menu items to it
CCMenu * myMenu = [CCMenu menuWithItems:menuItem1, menuItem2, menuItem3, nil];

// Arrange the menu items vertically
[myMenu alignItemsVertically];

// add the menu to your scene
[self addChild:myMenu];


这里有6张图片你可以用来做例子:1.png2.png3.png4.png



下载它们并把它们添加到你的工程项目中的资源文件夹里(当你把它们下载后请重新命名它们,并区分它们的大小写)
你需要注意每个菜单按照上面的方法定义后必须有单独调用它们的方法,你必须添加一些内容

- (void) doSomethingOne: (CCMenuItem  *) menuItem
{
NSLog(@"The first menu was called");
}
- (void) doSomethingTwo: (CCMenuItem  *) menuItem
{
NSLog(@"The second menu was called");
}
- (void) doSomethingThree: (CCMenuItem  *) menuItem
{
NSLog(@"The third menu was called");
}


想了解更多的菜单并知道如何使用它们,请 CCMenu阅读文档
在学习完了前三节后你应该知道如何做了,但是请注意必要的换行和空格
//
//  HelloWorldLayer.m
//  Lesson1
//
// Import the interfaces
#import "HelloWorldScene.h"
#import "CCTouchDispatcher.h"

CCSprite *seeker1;
CCSprite *cocosGuy;

// HelloWorld implementation
@implementation HelloWorld

+(id) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];

// 'layer' is an autorelease object.
HelloWorld *layer = [HelloWorld node];

// add layer as a child to scene
[scene addChild: layer];

// return the scene
return scene;
}
// set up the Menus
-(void) setUpMenus
{

// Create some menu items
CCMenuItemImage * menuItem1 = [CCMenuItemImage itemFromNormalImage:@"myfirstbutton.png"
            selectedImage: @"myfirstbutton_selected.png"
                   target:self
                 selector:@selector(doSomethingOne:)];

CCMenuItemImage * menuItem2 = [CCMenuItemImage itemFromNormalImage:@"mysecondbutton.png"
            selectedImage: @"mysecondbutton_selected.png"
                   target:self
                 selector:@selector(doSomethingTwo:)];

CCMenuItemImage * menuItem3 = [CCMenuItemImage itemFromNormalImage:@"mythirdbutton.png"
            selectedImage: @"mythirdbutton_selected.png"
                   target:self
                 selector:@selector(doSomethingThree:)];

// Create a menu and add your menu items to it
CCMenu * myMenu = [CCMenu menuWithItems:menuItem1, menuItem2, menuItem3, nil];

// Arrange the menu items vertically
[myMenu alignItemsVertically];

// add the menu to your scene
[self addChild:myMenu];
}
// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init] )) {

// create and initialize our seeker sprite, and add it to this layer
        seeker1 = [CCSprite spriteWithFile: @"seeker.png"];
        seeker1.position = ccp( 50, 100 );
        [self addChild:seeker1];

        // do the same for our cocos2d guy, reusing the app icon as its image
        cocosGuy = [CCSprite spriteWithFile: @"Icon.png"];
        cocosGuy.position = ccp( 200, 300 );
        [self addChild:cocosGuy];

// schedule a repeating callback on every frame
        [self schedule:@selector(nextFrame:)];
[self setUpMenus];

// register to receive targeted touch events
        [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self
                                 priority:0
                                  swallowsTouches:YES];
}
return self;
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
// in this particular example nothing needs to be released.
// cocos2d will automatically release all the children (Label)

// don't forget to call "super dealloc"
[super dealloc];
}
- (void) nextFrame:(ccTime)dt {
    seeker1.position = ccp( seeker1.position.x + 100*dt, seeker1.position.y );
    if (seeker1.position.x > 480+32) {
        seeker1.position = ccp( -32, seeker1.position.y );
    }
}
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
return YES;
}
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint location = [touch locationInView: [touch view]];
CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];

[cocosGuy stopAllActions];
[cocosGuy runAction: [CCMoveTo actionWithDuration:1 position:convertedLocation]];   
}

- (void) doSomethingOne: (CCMenuItem  *) menuItem
{
NSLog(@"The first menu was called");
}
- (void) doSomethingTwo: (CCMenuItem  *) menuItem
{
NSLog(@"The second menu was called");
}
- (void) doSomethingThree: (CCMenuItem  *) menuItem
{
NSLog(@"The third menu was called");
}
@end
//菜单项也可以用单独的作用域来代替选择器
// Create some menu items
CCMenuItemLabel *mi1 = [CCMenuItemLabel
                                        itemWithLabel:someLabel
                                        block:^(id sender) {
                                            [theDirector pushScene:[SceneGame node];
                                          }
                                       ];


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值