Iphone 如何获得塞尔达文字效果?

Iphone 如何获得塞尔达文字效果?,iphone,c,Iphone,C,我在iPhone上有一个基于2D瓷砖的OpenGL ES小游戏,当与游戏中的角色对话时,屏幕上会出现一个对话框。我想知道如何逐步显示文本(位图字体),而不是一次显示整个字符串,而是在Zelda游戏中如何做到,一个字母一个字母地显示,文本前面有一个小命令提示下划线……有人知道我在说什么吗 另外,我目前使用一种名为-drawStringAtPoint(AngelCode位图字体库)的方法,通过位图字体在屏幕上获取字符串。但我不知道如何做多行或显示文本一点一点 //From AngelCodeFont

我在iPhone上有一个基于2D瓷砖的OpenGL ES小游戏,当与游戏中的角色对话时,屏幕上会出现一个对话框。我想知道如何逐步显示文本(位图字体),而不是一次显示整个字符串,而是在Zelda游戏中如何做到,一个字母一个字母地显示,文本前面有一个小命令提示下划线……有人知道我在说什么吗

另外,我目前使用一种名为-drawStringAtPoint(AngelCode位图字体库)的方法,通过位图字体在屏幕上获取字符串。但我不知道如何做多行或显示文本一点一点

//From AngelCodeFont.m

// Changed 07/05/09 to add kerning
- (void)drawStringAt:(CGPoint)point text:(NSString*)text {

    // TODO: Add error if string is too long using NSASSERT
    //NSAssert(1>0, @"WARNING: Text to be rendered is too long");

    // Reset the number of quads which are going to be drawn
    int currentQuad = 0;

    // Enable those states necessary to draw with textures and allow blending
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);

    // Setup how the text is to be blended
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // Bind to the texture which was generated for the spritesheet image used for this font.  We only
    // need to bind once before the drawing as all characters are on the same texture.
    if([[image texture] name] != [_director currentlyBoundTexture]) {
        [_director setCurrentlyBoundTexture:[[image texture] name]];
        glBindTexture(GL_TEXTURE_2D, [[image texture] name]);
    }   

    // Set up the previous character and kerning amount vars
    unichar previousChar = -1;
    int kerningAmount = 0;

    // Loop through all the characters in the text
    for(int i=0; i<[text length]; i++) {

        // Grab the unicode value of the current character
        unichar charID = [text characterAtIndex:i];

        // Look up the kerning information for the previous char and this current char
        kerningAmount = [self kerningAmountForFirst:previousChar second:charID];

        // Move x based on the kerning info
        point.x += kerningAmount * scale;

        // Only render the current character if it is going to be visible otherwise move the variables such as currentQuad and point.x
        // as normal but don't render the character which should save some cycles
        if(point.x > 0 - ([charsArray[charID] width] * scale) || point.x < [[UIScreen mainScreen] bounds].size.width || point.y > 0 - ([charsArray[charID] height] * scale) || point.y < [[UIScreen mainScreen] bounds].size.height) {

            // Using the current x and y, calculate the correct position of the character using the x and y offsets for each character.
            // This will cause the characters to all sit on the line correctly with tails below the line etc.
            CGPoint newPoint = CGPointMake(point.x, 
                                           point.y - ([charsArray[charID] yOffset] + [charsArray[charID] height]) * [charsArray[charID] scale]);

            // Create a point into the bitmap font spritesheet using the coords read from the control file for this character
            CGPoint pointOffset = CGPointMake([charsArray[charID] x], [charsArray[charID] y]);

            // Calculate the texture coordinates and quad vertices for the current character
            [[charsArray[charID] image] calculateTexCoordsAtOffset:pointOffset subImageWidth:[charsArray[charID] width] subImageHeight:[charsArray[charID] height]];
            [[charsArray[charID] image] calculateVerticesAtPoint:newPoint subImageWidth:[charsArray[charID] width] subImageHeight:[charsArray[charID] height] centerOfImage:NO];

            // Place the calculated texture coordinates and quad vertices into the arrays we will use when drawing our string
            texCoords[currentQuad] = *[[charsArray[charID] image] textureCoordinates];
            vertices[currentQuad] = *[[charsArray[charID] image] vertices];

            // Increment the Quad count
            currentQuad++;
        }

        // Move x based on the amount to advance for the current char
        point.x += [charsArray[charID] xAdvance] * scale;

        // Store the character just processed as the previous char for looking up any kerning info
        previousChar = charID;
    }

    // Now that we have calculated all the quads and textures for the string we are drawing we can draw them all
    glVertexPointer(2, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
    glColor4f(colourFilter.red, colourFilter.green, colourFilter.blue, colourFilter.alpha * [_director globalAlpha]);
    glDrawElements(GL_TRIANGLES, currentQuad*6, GL_UNSIGNED_SHORT, indices);
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
}
//来自AngelCodeFont.m
//2009年5月7日更改为添加紧排
-(void)drawStringAt:(CGPoint)点文本:(NSString*)文本{
//TODO:如果使用NSASSERT的字符串太长,则添加错误
//NSAssert(1>0,@“警告:要呈现的文本太长”);
//重置要绘制的四边形数
int currentQuad=0;
//启用使用纹理绘制所需的状态并允许混合
glEnable(GL_纹理_2D);
glEnable(GL_混合物);
glEnableClientState(GL_纹理_坐标_阵列);
glEnableClientState(GL_顶点_数组);
//设置如何混合文本
glBlendFunc(GL_SRC_ALPHA,GL_ONE_减去GL_SRC_ALPHA);
//绑定到为用于此字体的精灵表图像生成的纹理。我们仅
//需要在绘制之前绑定一次,因为所有字符都位于同一纹理上。
如果([[image texture]name]!=[\u director currentlyBoundTexture]){
[_directorsetCurrentlyBoundTexture:[[image texture]name]];
glBindTexture(GL_TEXTURE_2D,[[图像纹理]名称]);
}   
//设置上一个字符和紧排量变量
unichar previousChar=-1;
int-kerningAmount=0;
//循环浏览文本中的所有字符

对于(inti=0;i,只需将文本绘制几次,每次在字符串中再包含一个字符

在伪代码中:

n = string length
for i=0 to n-1 {
    draw_text(substring from 0 to i + the underscore character)
    wait a couple of milliseconds
}
draw_text(entire string without the underscore character)

显然,等待“几毫秒”自然会使一切停止,因此这必须在单独的线程中发生,或者作为游戏循环中的一个滴答声发生。

为i=0而做->n-1{draw text}表示在渲染文本时不会发生任何其他情况。请像设置其他动画一样设置键入文本效果的动画,使用绘制之间的滴答数增加动画状态,以获得与帧率无关的动画速度

struct FancyText
{
  char *text;
  double cps; // chars per second
  double len = 0;
}

void render(CGpoint* point, FancyText *fancy, double delta)
{
  fancy->index += delta * cps;

  drawStringAt(point, fancy->text, floor(index));
}

void drawStringAt(CGpoint *point, char *text)
{
  drawStringAt(point, text, strlen(text));
}

void drawStringAt(CGPoint *point, char *text, int len)
{
  // your drawstring code
  // using for i = 0 -> len - 1 instead of strlen(text)
}

但是,这在标准的游戏循环中不起作用,我认为Krypes的答案更适合于此。这是伪代码,说明了一般的想法。Krypes的答案很好,但时间步进有一个问题——想象一下,如果帧率突然下降,会发生什么。然后文本将以抖动的方式出现。:-)delta==两个值之间的差值;主要用于两个刻度之间的时间。例如:1分钟30秒…时间流逝…1分钟31秒=>delta:1秒。查看“修复您的时间步长”: