Skip to content

Commit

Permalink
Alternative implementation using UIKit (TextBoxView)
Browse files Browse the repository at this point in the history
  • Loading branch information
crocodella committed Oct 5, 2011
1 parent e7d71bb commit d0d9a09
Show file tree
Hide file tree
Showing 9 changed files with 266 additions and 43 deletions.
11 changes: 11 additions & 0 deletions Classes/HelloWorldScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,27 @@
// When you import this file, you import all the cocos2d classes
#import "cocos2d.h"
#import "TextBoxLayer.h"
#import "TextBoxView.h"

// HelloWorld Layer
@interface HelloWorld : CCLayer <TextBoxDelegate>
{
TextBoxLayer *textBox;
TextBoxView *textBoxView;

CCMenu *menu;

BOOL isLayer;
BOOL isView;
}

// returns a Scene that contains the HelloWorld as the only child
+(id) scene;

- (void)gameLoop:(ccTime) dT;

- (void)onLayer:(id)sender;

- (void)onView:(id)sender;

@end
64 changes: 51 additions & 13 deletions Classes/HelloWorldScene.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,29 @@ -(id) init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init] )) {

textBox = [[TextBoxLayer alloc] initWithColor:ccc4(0, 0, 255, 255) width:200 height:80 padding:10 text:@"This is a purposefully long text so as to test the wrapping functionality of the TextBoxLayer, as well as the multiple pages. That's it! This is the end, my only friend, the end."];

// ask director the the window size
isLayer = NO;
isView = NO;

// ask director the the window size
CGSize size = [[CCDirector sharedDirector] winSize];

// position the label on the center of the screen
textBox.position = ccp( size.width /2 , size.height/2 );


NSString *txt = @"This is a purposefully long text so as to test the wrapping functionality of the TextBoxLayer, as well as the multiple pages. That's it! This is the end, my only friend, the end.";

textBox = [[TextBoxLayer alloc] initWithColor:[UIColor blueColor] width:200 height:80 padding:10 text:txt];
textBox.position = ccp( size.width /2 , size.height/2 );
textBox.delegate = self;

// add the label as a child to this Layer
[self addChild: textBox];

textBoxView = [[TextBoxView alloc] initWithColor:[UIColor blueColor] width:200 height:80 padding:10 text:txt];
textBoxView.center = ccp( size.width /2 , size.height/2 );
textBoxView.delegate = self;

CCMenuItemFont *itemLayer = [CCMenuItemFont itemFromString:@"Layer" target:self selector:@selector(onLayer:)];
CCMenuItemFont *itemView = [CCMenuItemFont itemFromString:@"View" target:self selector:@selector(onView:)];

menu = [CCMenu menuWithItems:itemLayer, itemView, nil];
[menu alignItemsHorizontallyWithPadding:20];
menu.position = ccp( size.width /2 , size.height/2 );
[self addChild:menu];
}
return self;
}
Expand All @@ -59,16 +70,43 @@ - (void) dealloc
// in this particular example nothing needs to be released.
// cocos2d will automatically release all the children (Label)
[textBox release];
[textBoxView release];
// don't forget to call "super dealloc"
[super dealloc];
}

- (void)gameLoop: (ccTime) dT {
[textBox update:dT];
if (isLayer) {
[textBox update:dT];
}

if (isView) {
[textBoxView update:dT];
}
}

- (void)onLayer:(id)sender {
[self addChild:textBox];
isLayer = YES;
[menu removeFromParentAndCleanup:YES];
}

- (void)onView:(id)sender {
[[CCDirector sharedDirector].openGLView addSubview:textBoxView];
isView = YES;
[menu removeFromParentAndCleanup:YES];
}

-(void) textBox:(TextBoxLayer *)tbox didFinishAllTextWithPageCount:(int)pc {
[self removeChild:textBox cleanup:YES];
-(void) textBox:(id<TextBox>)tbox didFinishAllTextWithPageCount:(int)pc {
if (isLayer) {
[self removeChild:textBox cleanup:YES];
isLayer = NO;
}

if (isView) {
[textBoxView removeFromSuperview];
isView = NO;
}
}

@end
33 changes: 33 additions & 0 deletions Classes/TextBox.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//
// TextBox.h
// TextBoxLayerSample
//
// Created by Fabio Rodella on 04/10/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>

#define TEXT_SPEED 60
#define TEXT_FONT_FILE @"arial16.fnt"

@protocol TextBox <NSObject>

- (id) initWithColor:(UIColor *)color
width:(CGFloat)w
height:(CGFloat)h
padding:(CGFloat)padding
text:(NSString *)txt;

- (void)update:(float)dt;

@end

@protocol TextBoxDelegate <NSObject>

- (void)textBox:(id<TextBox>)tbox didFinishAllTextWithPageCount:(int)pc;

@optional
- (void)textBox:(id<TextBox>)tbox didMoveToPage:(int)p;

@end
27 changes: 2 additions & 25 deletions Classes/TextBoxLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,9 @@

#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "TextBox.h"

#define TEXT_SPEED 60
#define TEXT_FONT_FILE @"arial16.fnt"

@class TextBoxLayer;

@protocol TextBoxDelegate <NSObject>

- (void)textBox:(TextBoxLayer *)tbox
didFinishAllTextWithPageCount:(int)pc;

@optional
- (void)textBox:(TextBoxLayer *)tbox didMoveToPage:(int)p;

@end


@interface TextBoxLayer : CCLayerColor {
@interface TextBoxLayer : CCLayerColor <TextBox> {

CCLabelBMFont *textLabel;

Expand All @@ -47,14 +32,6 @@

@property (readwrite,assign) id<TextBoxDelegate> delegate;

- (id) initWithColor:(ccColor4B)color
width:(GLfloat)w
height:(GLfloat)h
padding:(GLfloat)padding
text:(NSString *)txt;

- (void)update:(float)dt;

- (NSString *)nextPage;

- (int)calculateStringSize:(NSString *)txt;
Expand Down
24 changes: 20 additions & 4 deletions Classes/TextBoxLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,24 @@ @implementation TextBoxLayer

@synthesize delegate;

- (id) initWithColor:(ccColor4B)color width:(GLfloat)w height:(GLfloat)h padding:(GLfloat)padding text:(NSString *)txt {
if ((self = [super initWithColor:color width:w + (padding * 2) height:h + (padding * 2)])) {
- (id) initWithColor:(UIColor *)color width:(CGFloat)w height:(CGFloat)h padding:(CGFloat)padding text:(NSString *)txt {

int numComponents = CGColorGetNumberOfComponents(color.CGColor);

CGFloat r = 0, g = 0, b = 0, a = 1;

if (numComponents == 4)
{
const CGFloat *components = CGColorGetComponents(color.CGColor);
r = components[0];
g = components[1];
b = components[2];
a = components[3];
}

ccColor4B col = ccc4((GLubyte) r * 255 , (GLubyte) g * 255, (GLubyte) b * 255, (GLubyte) a * 255);

if ((self = [super initWithColor:col width:w + (padding * 2) height:h + (padding * 2)])) {

self.isTouchEnabled = YES;

Expand Down Expand Up @@ -156,7 +172,7 @@ -(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
}

if ([delegate respondsToSelector:@selector(textBox:didMoveToPage:)]) {
[delegate textBox:self didMoveToPage:currentPageIndex];
[delegate textBox:(id<TextBox>) self didMoveToPage:currentPageIndex];
}

} else {
Expand All @@ -165,7 +181,7 @@ -(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
ended = YES;

if ([delegate respondsToSelector:@selector(textBox:didFinishAllTextWithPageCount:)]) {
[delegate textBox:self didFinishAllTextWithPageCount:totalPages];
[delegate textBox:(id<TextBox>) self didFinishAllTextWithPageCount:totalPages];
}
}
}
Expand Down
30 changes: 30 additions & 0 deletions Classes/TextBoxView.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//
// TextBoxView.h
// TextBoxLayerSample
//
// Created by Fabio Rodella on 04/10/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "TextBox.h"

@interface TextBoxView : UIView <TextBox> {

CGFloat width;
CGFloat height;

UILabel *label;
NSString *text;
float progress;

int currentPage;

NSMutableArray *pages;

id<TextBoxDelegate> delegate;
}

@property (readwrite,assign) id<TextBoxDelegate> delegate;

@end
110 changes: 110 additions & 0 deletions Classes/TextBoxView.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//
// TextBoxView.m
// TextBoxLayerSample
//
// Created by Fabio Rodella on 04/10/11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//

#import "TextBoxView.h"


@implementation TextBoxView

@synthesize delegate;

- (id) initWithColor:(UIColor *)color width:(CGFloat)w height:(CGFloat)h padding:(CGFloat)padding text:(NSString *)txt {

if ((self = [super initWithFrame:CGRectMake(0, 0, w + (padding * 2), h + (padding * 2))])) {
self.backgroundColor = color;

width = w;
height = h;

currentPage = 0;
text = [txt retain];

label = [[UILabel alloc] initWithFrame:CGRectMake(padding, padding, w, h)];
label.text = @"";
label.backgroundColor = [UIColor clearColor];
label.numberOfLines = 0;
[self addSubview:label];
[label release];

NSArray *words = [txt componentsSeparatedByString:@" "];

NSString *curText = [words objectAtIndex:0];
int i = 1;

pages = [[NSMutableArray alloc] init];

while (i < [words count]) {

NSString *nextText = [curText stringByAppendingFormat:@" %@",[words objectAtIndex:i]];
CGSize size = [nextText sizeWithFont:label.font constrainedToSize:CGSizeMake(w, 99999) lineBreakMode:UILineBreakModeWordWrap];

if (size.height > h) {
[pages addObject:curText];
curText = [words objectAtIndex:i];
} else {
curText = nextText;
}
i++;
}
[pages addObject:curText];
}
return self;
}


- (void)dealloc
{
[pages release];
[text release];
[super dealloc];
}

- (void)update:(float)dt {

NSString *page = [pages objectAtIndex:currentPage];

progress += (dt * TEXT_SPEED);

int visible = progress;
if (visible > [page length]) {
visible = [page length];
}

NSString *newTxt = [page substringToIndex:visible];

label.text = newTxt;
label.frame = CGRectMake(label.frame.origin.x, label.frame.origin.y, width, height);
[label sizeToFit];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

NSString *page = [pages objectAtIndex:currentPage];

int visible = progress;
if (visible >= [page length]) {

if (currentPage == [pages count] - 1) {
if ([delegate respondsToSelector:@selector(textBox:didFinishAllTextWithPageCount:)]) {
[delegate textBox:(id<TextBox>) self didFinishAllTextWithPageCount:[pages count]];
}
} else {
currentPage++;
progress = 0;

if ([delegate respondsToSelector:@selector(textBox:didMoveToPage:)]) {
[delegate textBox:(id<TextBox>) self didMoveToPage:currentPage];
}
}

} else {
progress = [page length];
}
}

@end
2 changes: 1 addition & 1 deletion README
Original file line number Diff line number Diff line change
@@ -1 +1 @@
CCLayer subclass designed to handle RPG-like text boxes. More information: http://www.crocodella.com.br/2011/01/rpg-like-text-box-with-cocos2d/
CCLayer subclass designed to handle RPG-like text boxes. Also included is an alternative implementation using UIKit instead. More information: http://www.crocodella.com.br/2011/01/rpg-like-text-box-with-cocos2d/
Loading

0 comments on commit d0d9a09

Please sign in to comment.