【问题标题】:How can I use a UITextView in SpriteKit?如何在 SpriteKit 中使用 UITextView?
【发布时间】:2015-04-07 11:42:40
【问题描述】:

所以我的游戏中有这个 UITextView,我想通过添加 SKAction 动画 并让它与 physics 交互来使其更具动态性>。前者我以一种我不太满意的 hacky 方式完成,后者我没有完成,因为我不知道该怎么做。

这就是我执行 SKActions 的方式:

我做了几个 ivars:

-textViewContent (NSString)

-textViewSize (CGRect)

-文本视图(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]]];


}

如您所知,可能性非常有限。有没有更好的方法来实现这个或类似的东西?

【问题讨论】:

  • 有什么特别的原因为什么你不只是使用SKLabelNode?这个原生的 SpriteKit 类应该会更好地为您服务 UIKit 类UITextView
  • 因为我希望它可以滚动
  • 对你在这里问的到底是什么有点困惑。一个 SKLabelNode 可以有一个物理体,所以在那个级别上的交互是非常标准的。
  • 我知道,我想要一个可滚动的文本视图并且块需要交互

标签: ios objective-c uiview sprite-kit


【解决方案1】:

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

基本上,该类显示 SKLabelNodes 并在超过 1 行时向上滚动它们。线条会在设定的时间内出现,如果添加了额外的线条,则会向上移动,然后淡出。

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-12
    • 1970-01-01
    • 2015-06-16
    • 2018-10-19
    • 2019-10-30
    • 1970-01-01
    • 2015-02-26
    相关资源
    最近更新 更多