如何在SpriteKit中使用UITextView?

时间:2015-04-07 11:42:40

标签: ios objective-c uiview sprite-kit

所以我在游戏中有这个 UITextView ,我希望通过添加 SKAction动画并让它与物理。前者我用一种 hacky 的方式做了一些我不太满意的方法,后者我还没有做,因为我不知道怎么做。

这就是我做SKActions的方式:

我做了几个伊娃:

- textViewContent(NSString)

- textViewSize(CGRect)

- textView(UITextView)

- fakeTextView(SKSpriteNode)

由didMoveToView调用:

-(void)createTextView {

    textViewContent = @"foo";
    textViewSize = CGRectMake(CGRectGetMidX(self.frame)-(self.frame.size.width/4),
                          CGRectGetMidY(self.frame)-(self.frame.size.height/4), self.frame.size.width/2, self.frame.size.height/2);


    textView = [[UITextView alloc]initWithFrame:textViewSize];

    textView.backgroundColor = [SKColor orangeColor];
    textView.text = textViewContent;
    textView.textColor = [SKColor whiteColor];
    textView.textAlignment = NSTextAlignmentLeft;
    textView.font = [UIFont fontWithName:@"Code-Pro-Demo" size:25];
    textView.layer.zPosition = -1;
    textView.alpha = 0;
    textView.editable = NO;


    fakeTextView = [SKSpriteNode spriteNodeWithColor:[SKColor orangeColor] size:CGSizeMake(self.frame.size.width/2, self.frame.size.height/2)];
    fakeTextView.position = CGPointMake((self.frame.size.width*1.5),CGRectGetMidY(self.frame));
    [self addChild:fakeTextView];
    [self textViewEntersScene];


}
-(void)textViewEntersScene{
    SKAction *wait = [SKAction waitForDuration:0.5];
    SKAction *moveIn = [SKAction moveToX:(self.frame.size.width/2) - 100 duration:0.3];
    SKAction *moveBackSlightly = [SKAction moveToX:self.frame.size.width/2 duration:0.2];

    SKAction *displayTextView = [SKAction runBlock:^{
        textView.alpha = 1;
}];

    SKAction *hideFakeTextView = [SKAction runBlock:^{
        fakeTextView.hidden = YES;
}];  

    [fakeTextView runAction:[SKAction sequence:@[wait,moveIn,moveBackSlightly,displayTextView,hideFakeTextView]]];


}

你可能会说,可能性非常有限。有没有更好的方法来实现这个或类似的东西?

1 个答案:

答案 0 :(得分:1)

我创建了一个类来显示和滚动文本。创建新的SKNode类后,您可以直接复制并粘贴.h和.m文件。

基本上,如果有超过1行,该类会显示SKLabelNodes并将其向上滚动。线条出现设定的时间,如果添加其他线条则向上移动然后淡出。

这是非常通用的东西,所以请随意使用和修改您想要的任何项目中的代码。

要使用该类,请导入标题并使用此代码(示例):

TextBubble *myBubble = [[TextBubble alloc] init];
[myBubble createBubbleWithText:@"Hello this is a very nice day to go fishing and have a cold beer." textSize:24 maxLineLength:20];
myBubble.position = CGPointMake(300, 300);
[self addChild:myBubble];

TextBubble标题文件

#import <SpriteKit/SpriteKit.h>

@interface TextBubble : SKNode

-(instancetype)init;
-(void)createBubbleWithText:(NSString *)textString textSize:(int)textSize maxLineLength:(int)maxLineLength;

@end

TextBubble实施文件

#import "TextBubble.h"

@implementation TextBubble {
    NSMutableArray *linesArray;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        linesArray = [[NSMutableArray alloc] init];
    }
    return self;
}

-(void)createBubbleWithText:(NSString *)textString textSize:(int)textSize maxLineLength:(int)maxLineLength {

    NSMutableString *passedText = [[NSMutableString alloc] initWithString:textString];
    NSMutableString *currentLine = [[NSMutableString alloc] init];
    unsigned long characterCounter = 0;
    BOOL keepGoing = true;

    while (keepGoing) {

        NSRange whiteSpaceRange = [passedText rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet]];

        if(whiteSpaceRange.location != NSNotFound) {
            characterCounter += whiteSpaceRange.location+1;

            if(characterCounter <= maxLineLength) {
                [currentLine appendString:[passedText substringWithRange:NSMakeRange(0, whiteSpaceRange.location+1)]];
                [passedText setString:[passedText substringWithRange:NSMakeRange(whiteSpaceRange.location+1, [passedText length]-whiteSpaceRange.location-1)]];
            } else {
                [currentLine setString:[currentLine substringWithRange:NSMakeRange(0, [currentLine length]-1)]];

                SKLabelNode *myNode = [SKLabelNode labelNodeWithFontNamed:@"Arial-BoldMT"];
                myNode.text = [NSString stringWithString:currentLine];
                myNode.fontSize = textSize;
                myNode.fontColor = [SKColor blueColor];
                myNode.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
                myNode.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
                myNode.zPosition = 0;
                [linesArray addObject:myNode];

                characterCounter = 0;
                [currentLine setString:@""];
            }
        } else {
            [currentLine appendString:passedText];

            SKLabelNode *myNode = [SKLabelNode labelNodeWithFontNamed:@"Arial-BoldMT"];
            myNode.text = [NSString stringWithString:currentLine];
            myNode.fontSize = textSize;
            myNode.fontColor = [SKColor blueColor];
            myNode.horizontalAlignmentMode = SKLabelHorizontalAlignmentModeCenter;
            myNode.verticalAlignmentMode = SKLabelVerticalAlignmentModeCenter;
            myNode.zPosition = 0;
            [linesArray addObject:myNode];

            keepGoing = false;
        }
    }

    if([linesArray count] == 1) {
        SKAction *block0 = [SKAction runBlock:^{
            SKLabelNode *myNode = [linesArray objectAtIndex:0];
            myNode.alpha = 0.0;
            [self addChild:myNode];
            [myNode runAction:[SKAction fadeAlphaTo:1.0 duration:0.5]];
        }];

        SKAction *wait1 = [SKAction waitForDuration:2.5];

        SKAction *block1 = [SKAction runBlock:^{
            SKLabelNode *myNode = [linesArray objectAtIndex:0];
            [myNode runAction:[SKAction fadeAlphaTo:0.0 duration:0.5]];
        }];

        SKAction *wait2 = [SKAction waitForDuration:0.5];

        SKAction *block2 = [SKAction runBlock:^{
            [[linesArray objectAtIndex:0] removeFromParent];
        }];

        [self runAction:[SKAction sequence:@[block0, wait1, block1, wait2, block2]]];
    }

    if([linesArray count] == 2) {
        float heightCounter = 0.0;

        for (int i = 0; i<[linesArray count]; i++) {

            SKAction *wait0 = [SKAction waitForDuration:(2.0 * i)];

            SKAction *block0 = [SKAction runBlock:^{
                SKLabelNode *myNode = [linesArray objectAtIndex:i];
                myNode.alpha = 0.0;
                myNode.position = CGPointMake(0, 0);
                [self addChild:myNode];
                [[linesArray objectAtIndex:i] runAction:[SKAction fadeAlphaTo:1.0 duration:0.5]];
            }];

            SKAction *wait1 = [SKAction waitForDuration:1.5];

            heightCounter += 30;

            SKAction *block1 = [SKAction runBlock:^{
                [[linesArray objectAtIndex:i] runAction:[SKAction moveToY:heightCounter duration:0.5]];
            }];

            SKAction *block2 = [SKAction runBlock:^{
                [[linesArray objectAtIndex:i] runAction:[SKAction fadeAlphaTo:0.0 duration:0.5]];
            }];

            SKAction *wait2 = [SKAction waitForDuration:0.5];

            SKAction *block3 = [SKAction runBlock:^{
                [[linesArray objectAtIndex:i] removeFromParent];
            }];

            [self runAction:[SKAction sequence:@[wait0, block0, wait1, block1, wait1, block2, wait2, block3]]];

            heightCounter = 0;
        }
    }

    if([linesArray count] >= 3) {
        float heightCounter = 0.0;

        for (int i = 0; i<[linesArray count]; i++) {

            SKAction *wait0 = [SKAction waitForDuration:(1.5 * i)];

            SKAction *block0 = [SKAction runBlock:^{
                SKLabelNode *myNode = [linesArray objectAtIndex:i];
                myNode.alpha = 0.0;
                myNode.position = CGPointMake(0, 0);
                [self addChild:myNode];
                [[linesArray objectAtIndex:i] runAction:[SKAction fadeAlphaTo:1.0 duration:0.5]];
            }];

            SKAction *wait1 = [SKAction waitForDuration:1.5];

            heightCounter += 30;

            SKAction *block1 = [SKAction runBlock:^{
                [[linesArray objectAtIndex:i] runAction:[SKAction moveToY:heightCounter duration:0.5]];
            }];

            heightCounter += 30;

            SKAction *block5 = [SKAction runBlock:^{
                [[linesArray objectAtIndex:i] runAction:[SKAction moveToY:heightCounter duration:0.5]];
            }];

            SKAction *block2 = [SKAction runBlock:^{
                [[linesArray objectAtIndex:i] runAction:[SKAction fadeAlphaTo:0.0 duration:0.5]];
            }];

            SKAction *wait2 = [SKAction waitForDuration:0.5];

            SKAction *block3 = [SKAction runBlock:^{
                [[linesArray objectAtIndex:i] removeFromParent];
            }];

            [self runAction:[SKAction sequence:@[wait0, block0, wait1, block1, wait1, block5, wait1, block2, wait2, block3]]];

            heightCounter = 0;
        }
    }
}

@end