创建幻灯片是Cocos2d iPhone
cocos2d (4), iphone (5)I've beenslowly growing my Cocos2d iPhone related entries, and in this entry I want to display some real usable code to solve a general problem for iPhone game developers: how can I create a how-to guide that teaches new users to play my game?
b的代码elow implements a simple slideshow player, which will cycle through an arbitrary number of images and text labels, and then pop itself off the stack of scenes. Along the way we'll implement a full example of handling touch detection in Cocos2d, and see how quick and downrightpleasantCocos2d iPhonedevelopment can be.
Usage of theSlideShowLayer
class looks like this:
// Initialize scene and slide show layer.Scene*s=[Scenenode];SlideShowLayer*ssl=[SlideShowLayernode];// Set positions for the background and labels.// Generally you'll be using full screen backgrounds// (screenshots), and positioning them at the center.[sslsetBackgroundXPosition:100];[sslsetBackgroundYPosition:100];[sslsetDescriptionXPosition:200];[sslsetDescriptionYPosition:200];[sslsetDescriptionWidth:100];[sslsetDescriptionHeight:300];[sslsetFontName:@"Helvetica"];// optional[sslsetFontSize:24];// optional
// Add slides in order they appear.[ssladdSlideWithBackground:@"pic1.png"andDescription:@"Yada yada one."];[ssladdSlideWithBackground:@"pic2.png"andDescription:@"Yada yada two."];[ssladdSlideWithBackground:@"pic3.png"andDescription:@"Yada yada 3."];[ssladdSlideWithBackground:@"pic4.png"andDescription:@"Yada yada 4."];[ssladdSlideWithBackground:@"pic5.png"andDescription:@"Yada yada 5."];[ssladdSlideWithBackground:@"pic6.png"andDescription:@"Yada yada six."];
// Start and display the slide show.[ssldisplayFirstSlide];[sceneadd:ssl];[[DirectorsharedDirector]pushScene:scene];
Currently there are some limitations (all labels and images must be at the same location and all labels must be of the same height and width), but improving upon the code in that regard shouldn't be terriably difficult. Beyond that, it should be a fairly reusable and flexible tool for displaying the simplest of simple slide shows.
I'll be posting the code in its entirety as large chunks (one chunk forSlideShowLayer.h
and one chunk forSlideShowLayer.m
), to promote copy and pastability. Commentary will be inlined in the code as Objective-C comments.
FirstSlideShowLayer.h
.
/** SlideShowLayer by Will Larson and Luke Hatcher. 10/29/2008.* Released under MIT License.* Please check out from repository for full license detail.** Nothing too exiting happening here.* Apologies that it is not in Obj2.0* syntax, but I'm still ambivalent about* the ambiguousness of properties.*/#import #import "CocosNode.h"#import "Layer.h"#import "Label.h"#import "Sprite.h"
@interfaceSlideShowLayer:Layer{intslidePosition;intbackgroundXPosition;intbackgroundYPosition;intdescriptionXPosition;intdescriptionYPosition;intdescriptionHeight;intdescriptionWidth;intfontSize;NSStringfontName;NSMutableArraybackgrounds;NSMutableArraydescriptions;Spritebackground;CocosNode*description;}
/* This is the only method for adding slides to the slide show./-(void)addSlideWithBackground:(NSString)imageStringandDescription:(NSString)descString;/** Methods for advancing, retreating, and starting the slideshow.* There currently isn't a UI mechanism for retreating to already* seen slides, but you could rig something up if you tried hard* enough. ;)*/-(void)displayFirstSlide;-(void)displayNextSlide;-(void)displayPreviousSlide;-(void)displaySlide:(int)slideNumber;-(BOOL)hasPreviousSlide;-(BOOL)hasNextSlide;
/* Mutators and Accessors/-(NSMutableArray)backgrounds;-(NSMutableArray)descriptions;-(Sprite)background;-(void)setBackground:(Sprite)aSprite;-(CocosNode)description;-(void)setDescription:(CocosNode)aCocosNode;-(NSString)fontName;-(void)setFontName:(NSString)aFontName;-(int)fontSize;-(void)setFontSize:(int)anInt;-(int)slidePosition;-(void)setSlidePosition:(int)anInt;-(int)backgroundXPosition;-(void)setBackgroundXPosition:(int)anInt;-(int)backgroundYPosition;-(void)setBackgroundYPosition:(int)anInt;-(int)descriptionXPosition;-(void)setDescriptionXPosition:(int)anInt;-(int)descriptionYPosition;-(void)setDescriptionYPosition:(int)anInt;-(int)descriptionWidth;-(void)setDescriptionWidth:(int)anInt;-(int)descriptionHeight;-(void)setDescriptionHeight:(int)anInt;@end
And now forSlideShowLayer.m
.
/** SlideShowLayer by Will Larson and Luke Hatcher. 10/29/2008.* Released under MIT License.* Please check out from repository for full license detail.*/#import "SlideShowLayer.h"@implementationSlideShowLayer
-(id)init{self=[superinit];if(self){/** setting isTouchEnabled is the magic step that* allows the layer to be registered for UI events.* forgetting this step will lead to great confusion :-/*/isTouchEnabled=YES;slidePosition=-1;backgrounds=[[NSMutableArrayalloc]init];descriptions=[[NSMutableArrayalloc]init];[selfsetFontName:@"Helvetica"];[selfsetFontSize:24];}returnself;}
-(void)dealloc{[backgroundsrelease];backgrounds=nil;[descriptionsrelease];descriptions=nil;[backgroundrelease];background=nil;[descriptionrelease];description=nil;[fontSizerelease];fontSize=nil;[superdealloc];}
-(void)touchesEnded:(NSSet)toucheswithEvent:(UIEvent)event{/** We are using pushScene/popScene instead of replaceScene* (which has superior memory usage characteristics), because* it makes integrating SlideShowLayer much simpler, and helps* avoid binding the code to one application without requiring* us to use the delegate pattern.*/if([selfhasNextSlide])[selfdisplayNextSlide];
else[[DirectorsharedDirector]popScene];}
-(void)addSlideWithBackground:(NSString)imageStringandDescription:(NSString)descString{[[selfbackgrounds]addObject:imageString];[[selfdescriptions]addObject:descString];}
-(void)displayFirstSlide{if([[selfbackgrounds]count]>0){[selfsetSlidePosition:0];[selfdisplaySlide:[selfslidePosition]];}}
-(void)displayNextSlide{if([selfhasNextSlide]){[selfsetSlidePosition:[selfslidePosition]+1];[selfdisplaySlide:[selfslidePosition]];}}
-(void)displayPreviousSlide{if([selfhasPreviousSlide]){[selfsetSlidePosition:[selfslidePosition]-1];[selfdisplaySlide:[selfslidePosition]];}}
-(void)displaySlide:(int)slideNumber{/** Remove existing slide and description.*/if([selfbackground]){[selfremove:[selfbackground]];}if([selfdescription]){[selfremove:[selfdescription]];}
/*
* Retrieve and generate necessary details for next slide./NSStringbgString=[[selfbackgrounds]objectAtIndex:slideNumber];NSStringdescString=[[selfdescriptions]objectAtIndex:slideNumber];Spritebg=[SpritespriteWithFile:bgString];bg.position=cpv([selfbackgroundXPosition],[selfbackgroundYPosition]);CocosNode*desc=[LabellabelWithString:descStringdimensions:CGSizeMake([selfdescriptionWidth],[selfdescriptionHeight])alignment:UITextAlignmentCenterfontName:[selffontName]fontSize:[selffontSize]];desc.position=cpv([selfdescriptionXPosition],[selfdescriptionYPosition]);
// Add the background and desc to the layer. [self setBackground:bg]; [self setDescription:desc]; [self add:bg]; [self add:desc];
}
-(BOOL)hasNextSlide{return([selfslidePosition]+1<[[selfbackgrounds]count]);}
-(BOOL)hasPreviousSlide{return([selfslidePosition]>0);}
-(Sprite)background{returnbackground;}-(void)setBackground:(Sprite)aSprite{if(background)[backgroundrelease];background=[aSpriteretain];}
-(CocosNode)description{returndescription;}-(void)setDescription:(CocosNode)aCocosNode{if(description)[descriptionrelease];description=[aCocosNoderetain];}
-(NSMutableArray*)backgrounds{returnbackgrounds;}
-(NSMutableArray*)descriptions{returndescriptions;}
-(NSString*)fontName{returnfontName}
-(int)fontSize{returnfontSize;}
-(void)setFontSize:(int)anInt{fontSize=anInt;}
-(void)setFontName:(NSString*)aFontName{if(fontName)[fontNamerelease];fontName=[aFontNameretain];}
-(int)slidePosition{returnslidePosition;}
-(void)setSlidePosition:(int)anInt{slidePosition=anInt;}
-(int)backgroundXPosition{returnbackgroundXPosition;}
-(void)setBackgroundXPosition:(int)anInt{backgroundXPosition=anInt;}
-(int)backgroundYPosition{returnbackgroundYPosition;}
-(void)setBackgroundYPosition:(int)anInt{backgroundYPosition=anInt;}
-(int)descriptionXPosition{returndescriptionXPosition;}-(void)setDescriptionXPosition:(int)anInt{descriptionXPosition=anInt;}
-(int)descriptionYPosition{returndescriptionYPosition;}
-(void)setDescriptionYPosition:(int)anInt{descriptionYPosition=anInt;}
-(int)descriptionWidth{returndescriptionWidth;}
-(void)setDescriptionWidth:(int)anInt{descriptionWidth=anInt;}
-(int)descriptionHeight{returndescriptionHeight;}
-(void)setDescriptionHeight:(int)anInt{descriptionHeight=anInt;}
@end
Hopefully this is a starting point that you can work from, and use in your applications. I'll be cleaning this up and putting it into a repository in the near future. I'll post a link here afterwards.
Let me know if you have any questions or comments.