Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Well i have found a tutorial how to make a bitmap font from an image. (http://devlinslab.blogspot.com/2007/11/using-custom-fonts-or-bitmap-fonts-part.html).

So I have used this code in my game and the problem is that the rest of the graphics which should be seen on the screen like rectangles and etc. is invisible.

Before the newly added code

http://i47.tinypic.com/30wt5ad.jpg

After

http://i48.tinypic.com/3581k44.jpg

A GameCanvas class play.java

  public void start() {

    try {
        map = Image.createImage("/mapas.png");
        human = Image.createImage("/players.png");
        ingame = Image.createImage("/ingame.png");
        items = Image.createImage("/items.png");
        atkPav = Image.createImage("/ingamee.PNG");
    } catch (IOException ioex) {
        System.out.println(ioex);
    }
            // f is the newly added class where is methods drawString() drawChar()                    and etc.
    f = new f();
    f.load("/chatfont.PNG");

         // sprites and etc.
       }
         // method which is called from a Thread (while loop)
 private void createBackground(Graphics g) {
       // some graphics an xp line showing how much xp left to level up and etc.
            g.setColor(0x000000);
    g.fillRect(0, 0, getWidth(), 28);
    g.fillRect(0, getHeight() - 15, getWidth(), 15);

    // xp
    g.setColor(0x9F81F7);

    if (level == 0) {
        g.fillRect(0, 25, getWidth() * xp / 200, 2);
    } else {
        g.fillRect(0, 25, getWidth()
                * (xp - (200 * level + (level * (level - 1)) / 2 * 200))
                / (200 * (level + 1)), 2);
    }
    g.setColor(0xAAAAAA);
    g.fillRect(getWidth() - 24, 0, 24, 24);

    g.setColor(0x000000);
    g.fillRect(getWidth() - 22, 2, 20, 20);

    g.setColor(0xffffff);


            // here`s the statement
    f.drawString(g, "HP: " + humanHp + "/" + maxHumanHp, 5, 0);



     }

the f.java a bit modified then the original

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

 public class f {

// tarpas tarp raidziu
public int charS = 1;

// image width 99 height 17
// max kirpimo matmenys
public int screenW = 176;
public int screenH = 208;

// flag: set to true to use the Graphics.drawString() method
// this is just used as a fail-safe
public boolean useDefault = false;

// height of characters
public int charH = 5;
// lookup table for character widths
public int charW = 4;

// the bitmap font image
private Image imgFont;

/** Creates a new instance of clsFont */
public f() {
}

public boolean load(String imagePath) {
    useDefault = false;
    try {
        // load the bitmap font
        if (imgFont != null) {
            imgFont = null;
        }
        imgFont = Image.createImage(imagePath);
    } catch (Exception ex) {
        // oohh we got an error then use the fail-safe
        useDefault = true;
    }
    return (!useDefault);

}

public void unload() {
    // make sure the object get's destroyed
    imgFont = null;
}

public void drawChar(Graphics g, int cIndex, int x, int y, int w, int h) {
    // non printable characters don't need to be drawn

    // neither does the delete character

    int cx = 0;



    // getting characters from an Image (cx - coordinate which will be used          for clipRect())
    if (cIndex > 64 && cIndex < 91) {
        cx = (cIndex - 65) * 5;
    } else if (cIndex > 96 && cIndex < 123) {
        cx = (cIndex - 97) * 5;
    } else if (cIndex > 47 && cIndex < 58) {
        cx = (cIndex - 48) * 5 + 135;
    } else if (cIndex == 32) {
        cx = 130;
    } else if (cIndex == 46) {
        cx = 184;
    } else if (cIndex == 58) {
        cx = 189;
    } else if (cIndex == 44) {
        cx = 194;
    } else if (cIndex == 59) {
        cx = 199;
    } else if (cIndex == 63) {
        cx = 204;
    } else if (cIndex == 33) {
        cx = 209;
    } else if (cIndex == 40) {
        cx = 214;
    } else if (cIndex == 41) {
        cx = 219;
    } else if (cIndex == 43) {
        cx = 224;
    } else if (cIndex == 44) {
        cx = 229;
    } else if (cIndex == 42) {
        cx = 234;
    } else if (cIndex == 47) {
        cx = 239;
    } else if (cIndex == 61) {
        cx = 244;
    } else if (cIndex == 96) {
        cx = 249;
    } else if (cIndex == 95) {
        cx = 254;
    } else if (cIndex == 92) {
        cx = 259;
    } else if (cIndex == 35) {
        cx = 264;
    } else if (cIndex == 91) {
        cx = 269;
    } else if (cIndex == 93) {
        cx = 274;
    } else if (cIndex == 38) {
        cx = 279;
    }



    // reset the clipping rectangle
    g.setClip(0, 0, screenW, screenH);

    // resize and reposition the clipping rectangle
    // to where the character must be drawn
    g.clipRect(x, y, w, h);

    // draw the character inside the clipping rectangle
    g.drawImage(imgFont, x - cx, y, Graphics.TOP | Graphics.LEFT);
}

public void drawString(Graphics g, String sTxt, int x, int y) {
    // get the strings length
    int length = sTxt.length();

    // set the starting position
    int cx = x;

    // if nothing to draw return
    if (length == 0) {
        return;
    }

    // our fail-safe
    if (useDefault) {
        g.drawString(sTxt, x, y, Graphics.TOP | Graphics.LEFT);
        return;
    }

    // loop through all the characters in the string
    for (int i = 0; i < length; i++) {

        // get current character
        char c = sTxt.charAt(i);

        // get ordinal value or ASCII equivalent
        int cIndex = (int) c;

        // lookup the width of the character
        int w = charW; // cIndex

        // draw the character
        drawChar(g, cIndex, cx, y, w, charH);

        // go to the next drawing position
        cx += (w + charS);
    }
}

public void drawInt(Graphics g, int num, int x, int y) {
    drawString(g, Integer.toString(num), x, y);
}
   }
share|improve this question
    
We're gonna need a bit more info than this :). How are you rendering the stuff that has disappeared? Have you tried commenting parts of your code out to see if it re-appears? –  Roy T. Sep 11 '12 at 19:42
    
if i comment the new code ive added the stuff re appears again. i added statement NewClass.drawString(g,"text"10,10); and other graphics will be not drawn. Its something with the new class PS if i comment this part of code the graphics will be seen again. –  user1494517 Sep 12 '12 at 4:30
    
Ca you post relevant parts of your code? It's probably something device state related. Maybe you have to set some render settings back to their original values right after NewClass.drawString(). –  Roy T. Sep 12 '12 at 7:45

1 Answer 1

up vote 1 down vote accepted

The penultimate line of f.drawChar sets the clip to a tiny rectangle. If you reset the clip after rendering the character, you'll probably find that the problem is fixed.


In fact, there's room for some optimisation, and it's a good idea to restore the clip afterwards:

private int clipX, clipY, clipW, clipH;

private void storeClip(Graphics g) {
    clipX = g.getClipX();
    clipY = g.getClipY();
    clipW = g.getClipWidth();
    clipH = g.getClipHeight();
}

private void restoreClip(Graphics g) {
    g.setClip(clipX, clipY, clipW, clipH);
}

public void drawChar(Graphics g, int cIndex, int x, int y) {
    storeClip(g);
    drawCharInner(g, cIndex, x, y)
    restoreClip(g);
}

// Returns the advance
private int drawCharInner(Graphics g, int cIndex, int x, int y) {
    // lookup the width of the character
    int w = charW;

    int cx = 0;
    // getting characters from an Image (cx - coordinate which will be used for clipRect())
    if (cIndex > 64 && cIndex < 91) {
        cx = (cIndex - 65) * 5;
    } etc // There must be a better way of doing this

    // resize and reposition the clipping rectangle to where the character must be drawn
    // NB Two steps here to work around some buggy implementations
    g.setClip(0, 0, screenW, screenH);
    g.clipRect(x, y, w, h);

    // draw the character inside the clipping rectangle
    g.drawImage(imgFont, x - cx, y, Graphics.TOP | Graphics.LEFT);

    return w + charS;
}

public void drawString(Graphics g, String sTxt, int x, int y) {
    // get the strings length
    int length = sTxt.length();

    // set the starting position
    int cx = x;

    // if nothing to draw return
    if (length == 0) {
        return;
    }

    // our fail-safe
    if (useDefault) {
        g.drawString(sTxt, x, y, Graphics.TOP | Graphics.LEFT);
        return;
    }

    storeClip(g);

    // loop through all the characters in the string
    for (int i = 0; i < length; i++) {

        // get current character
        char c = sTxt.charAt(i);

        // draw the character and go to the next drawing position
        cx += drawCharInner(g, c, cx, y);
    }

    restoreClip(g);
}

One final thought, which would require changes outside this class: when you use an image with lots of small sprites, as in this case, it's better to lay them out vertically rather than horizontally. The reason is that memory storage of images tends to be row-major, so keeping the image width to one sprite means that the memory which makes up a sprite is contiguous, which is good for cache performance.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.