I have an issue with libgdx BitMapFont, I display labels inside of a scene2d table, but the font is "cut" at some parts of the text (see below).
Here is my code :
For declaring the font :
font12 = new BitmapFont(Gdx.files.internal("fonts/text.fnt"));
font12.setUseIntegerPositions(false);
font12.getData().setScale(0.2f);
For declaring the table :
Table table = new Table();
table.top();
table.setFillParent(true);
LabelStyle lblStyle = new LabelStyle();
lblStyle.font = font12;
scoreLabel =new Label("SCORE", lblStyle);
timeLabel = new Label("TIME", lblStyle);
levelLabel = new Label("LEVEL", lblStyle);
Thank you for your help.
[EDIT]
Here is the code I tried using freetype but this doesn't look smooth :
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fonts/OpenSans-Regular.ttf"));
FreeTypeFontParameter parameter = new FreeTypeFontParameter();
parameter.size = 18;
parameter.color = Color.BLACK;
generator.scaleForPixelHeight(18);
parameter.minFilter = Texture.TextureFilter.Linear;
parameter.magFilter = Texture.TextureFilter.Linear;
parameter.mono = false;
parameter.gamma = 2f;
font12 = generator.generateFont(parameter); // font size 12 pixels
font12.setUseIntegerPositions(false);
font12.getRegion().getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
generator.dispose(); // don't forget to dispose to avoid memory leaks!
First thing, you should always avoid scaling fonts because the result is pixelated and looks really bad. You can generator fonts to the correct size that you need within your program using the FreeTypeFontGenerator:
https://github.com/libgdx/libgdx/wiki/Gdx-freetype
When adding components to a table the table sets the size on its child components. Essentially, the table will override the size of the label when the label is added to the table.
To make sure the label keeps the same size, set the size on the table's cell that is holding the label like this:
table.add(label).size(label.getWidth(), label.getHeight());
You can also apply a different size to the label when adding it to the table (if for example you wanted to have extra space around the label):
table.add(label).size(500, 100);
EDIT
This code works for me, give this a try.
private Stage stage;
#Override
public void create () {
stage = new Stage();
stage.setViewport(new ScreenViewport(stage.getViewport().getCamera()));
Table table = new Table();
table.setFillParent(true);
stage.addActor(table);
FreeTypeFontGenerator gen = new FreeTypeFontGenerator(Gdx.files.internal("internal/arialbd.ttf"));
FreeTypeFontGenerator.FreeTypeFontParameter param = new FreeTypeFontGenerator.FreeTypeFontParameter();
param.size = 18;
param.borderColor = new Color(Color.BLACK);
param.borderWidth = 1;
BitmapFont font = gen.generateFont(param);
gen.dispose();
Label.LabelStyle style = new Label.LabelStyle();
style.font = font;
Label label = new Label("Hello World", style);
table.add(label).size(label.getWidth(), label.getHeight());
}
#Override
public void render() {
Gdx.gl.glClearColor(0.6f, 0.8f, 0.8f, 1.0f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#Override
public void resize(int width, int height) {
stage.getViewport().update(width, height, true);
}
I am developing a game in which i am making a Game Over Screen but the components are not rearranging properly.
What i am Getting on 1024 * 720 screen is:
and what it should look like:
and the code is:
#Override
public void show() {
stage = new Stage(new ScreenViewport());
camera = new OrthographicCamera(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
Gdx.input.setInputProcessor(stage);
font = new BitmapFont(Gdx.files.internal("newfont.fnt"));
verysmallfont = new BitmapFont(Gdx.files.internal("verysmallfont.fnt"));
smallfont = new BitmapFont(Gdx.files.internal("smallfont.fnt"));
atlas = new TextureAtlas("ui/buttons.pack");//add atlas
skin = new Skin(atlas);
table = new Table(skin);
actiontable = new Table(skin);
actionbar = new Table(skin);
actionbar2 = new Table(skin);
table.setBounds(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
actiontable.setBounds(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
actionbar.setBounds(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
actionbar2.setBounds(0,0,Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
TextButton.TextButtonStyle buttonback = new TextButton.TextButtonStyle();
buttonback.up = skin.getDrawable("back");
buttonback.pressedOffsetX = 1;
buttonback.pressedOffsetY = -1;
buttonback.font = font;
buttonBack = new TextButton("",buttonback);
TextButton.TextButtonStyle lifebuttonstyle = new TextButton.TextButtonStyle();
lifebuttonstyle.up = skin.getDrawable("life");
lifebuttonstyle.pressedOffsetX = 1;
lifebuttonstyle.pressedOffsetY = -1;
lifebuttonstyle.font = font;
buttonlife = new TextButton("",lifebuttonstyle);
TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle();
textButtonStyle.up = skin.getDrawable("heart_game_continue");
textButtonStyle.pressedOffsetX = 1;
textButtonStyle.pressedOffsetY = -1;
textButtonStyle.font = font;
buttonPlay = new TextButton("",textButtonStyle);
TextButton.TextButtonStyle adsfreeStyle = new TextButton.TextButtonStyle();
adsfreeStyle.up = skin.getDrawable("Video");
adsfreeStyle.pressedOffsetX = 1;
adsfreeStyle.pressedOffsetY = -1;
adsfreeStyle.font = font;
buttonVideo = new TextButton("",adsfreeStyle);
TextButton.TextButtonStyle sharebuttonStyle = new TextButton.TextButtonStyle();
sharebuttonStyle.up = skin.getDrawable("Replay");
sharebuttonStyle.pressedOffsetX = 1;
sharebuttonStyle.pressedOffsetY = -1;
sharebuttonStyle.font = font;
buttonReplay = new TextButton("",sharebuttonStyle);
Label.LabelStyle headingstyle = new Label.LabelStyle(font,Color.WHITE);
label = new Label("Game Over",headingstyle);
label.setFontScale(1.7f);
Label.LabelStyle contstyle = new Label.LabelStyle(smallfont,Color.WHITE);
cont = new Label("Continue?",contstyle);
cont.setFontScale(2f);
Label.LabelStyle replaystyle = new Label.LabelStyle(verysmallfont,Color.WHITE);
replay = new Label("Replay",replaystyle);
shortVideo = new Label("(Short Video)",replaystyle);
replay.setFontScale(2f);
shortVideo.setFontScale(2f);
table.align(Align.top);
table.padTop(197f);
table.add(label);
table.getCell(label).spaceBottom(150f);
table.row();
table.add(cont);
table.getCell(cont).spaceBottom(80f);
table.row();
table.add(buttonPlay).size(200f,200f);
actiontable.add(buttonVideo).size(200f,200f);
actiontable.add(buttonReplay).size(200f,200f);
actiontable.align(Align.bottom);
actiontable.getCell(buttonVideo).spaceBottom(20f).padRight(100f);
actiontable.getCell(buttonReplay).spaceBottom(20f).padLeft(100f);
actiontable.row();
actiontable.add(shortVideo).padRight(100f);
actiontable.add(replay).padLeft(100f);
actiontable.padBottom(197f);
actiontable.setFillParent(true);
actionbar.align(Align.topLeft).setWidth(Gdx.graphics.getWidth());
actionbar.add(buttonBack).align(Align.left).size(90f,90f);
actionbar2.align(Align.topRight);
actionbar2.add(buttonlife).align(Align.right).size(90f,90f);
actionbar.getCell(buttonBack).pad(43f);
actionbar2.getCell(buttonlife).align(Align.right).pad(43f);
stage.addActor(actionbar2);
stage.addActor(actionbar);
stage.addActor(table);
stage.addActor(actiontable);
buttonPlay.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
((Game) Gdx.app.getApplicationListener()).setScreen(new Main(level,a,start,sweep,collide,innerarcs,out,mid,arcsleft,left,pointerColor));
};
});
buttonReplay.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
int total = out+mid+innerarcs;
((Game) Gdx.app.getApplicationListener()).setScreen(new Main(level,a,total,pointerColor));
}
});
buttonBack.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
((Game) Gdx.app.getApplicationListener()).setScreen(new Menu(level));
}
});
}
SpriteBatch batch;
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0.184f,0.184f,0.184f,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(delta);
stage.draw();
}
private OrthographicCamera camera;
#Override
public void resize(final int width, final int height) {
table.setTransform(true);
table.setSize(width,height);
actiontable.setTransform(true);
actiontable.setSize(width,height);
actionbar.setTransform(true);
actionbar.setSize(width,height);
}
I am new to libgdx please help i dont have any knowledge about how to use camera and viewports.
Thanks in advance..
€dit: sorry my bad - there's nothing like "stage.resize"
But I'll let the answer in, because it'll fix your problem, though not as fast as you wish, but in a more clear way.
(THE FOLLOWING TEXT IS NOT NECESSARRY FOR THE ANWSER AND ARE ONLY SUGGESTIONS)
(if you follow the following steps, you'll save yourself time & headaches in the future)
I'd suggest a viewport, because they'll kill many problems with scaling, and there are quite a few, from which you can choose, as you need.
LibGdx Viewports
A viewport takes care for different screen sizes with the help from different techniques (e.g. scaling, black bars)
Additionally a viewport is SUPER easy to implement.
You'll do the following(e.g. FitViewport(stretches content, if necessary)):
stage = new Stage();
OrthographicCamera cam = new OrthographicCamera();
cam.setToOrtho(false, 800, 600);
stage.setViewport(new FitViewport(800, 600, cam));
TADA. You implemented a viewport. Was not so hard.
(but make sure to call stage.getViewport().update(w, h) in the resize(w, h) method!! AND DON'T FORGET IT!!)
Second suggestion I'd do is:
Use a main table.
So you do following
Table myMothershipTable = new Table();
myMothershipTable.setFillParent(true);
myMothershipTable.add(add);
myMothershipTable.add(all);
myMothershipTable.add(content);
stage.addActor(myMothershipTable);
Now you've only one actor, which is the table, and you can be damned sure, that this table will fill the whole screen.
Your screen is 10999x3? yeah. the table will be 10999x3.
Good. If you've refactored your whole stuff into one table I'd suggest the next step:
stage.setDebugAll(true); //this will help you to see the actual buildup from your actors & elements
So heres the why:
The viewport takes care for your stage size
the single table makes sure, that your complete content will be within the screen ==> now you can add one item after another, and make sure with..
stage.setDebugAll(true).. that your content is placed properly.
If you follow this simple steps, you'll save yourself a lot of time and headache with designing the UI.
The page it is on is CarSelect.as, the aButton should take it to a page called AClass.as however it doesnt load it.
public static var aButton:MovieClip = new AButton();
addChild (aButton);
aButton.x = 65;
aButton.y = 154;
aButton.addEventListener(MouseEvent.MOUSE_DOWN, openAClass);
function openAClass(e:MouseEvent):void
{
Mercedes.AClass.visible = true;
}
//pulling in car actionscript pages
public var aClass:MovieClip = new AClass();
public var bClass:MovieClip = new BClass();
public var cClass:MovieClip = new CClass();
How can I instantiate a TabViewNavigator from actionscript for the playbook? Currently, I add the necessary spark frameworks and have this piece of code in the Main of my actionscript project:
[SWF(width="1024", height="600", backgroundColor="#ffffff", frameRate="30")]
public class Main extends Sprite
{
private var waitDialog:BaseDialog = new BaseDialog ();
public function Main()
{
super ();
var next:LabelButton = new LabelButton ();
next.label = "Next";
next.addEventListener(MouseEvent.CLICK,showTabs);
this.addChild(next);
}
private function showTabs (event:MouseEvent):void{
var temp:Stage = this.stage;
temp.removeChild(this);
var bar : TabbedViewNavigator = new TabbedViewNavigator();
var tab1:ViewNavigator = new ViewNavigator();
tab1.label = "Test";
bar.addItem(tab1);
temp.addChild(bar);
}
}
When the button is clicked, the button disappears as you would expect but the tab navigator is not added/does not appear. I tried without removing the Main class but that does not work either. What do I need to do to set up a tab interface. I can get similar code working through Flex and MXML but not in actionscript.
temp.removeChild(this); - this is the problem you just remove the movie clip form the stage. There is no sense in this row.
I need to make an auto complete component in flex that fetches the auto complete results from a remote database using a webservice. I have the webservice and querying part worked out. I've already made custom components in action script by extending VBoxes. However I cannot figure out how to generate the popup window that is supposed to show under the text input in my auto complete text box.
Currently I am using something like
PopUpManager.addPopUp(popup, parentComponent);
My popup class extends VBox and it extends the createChildren method as follows
protected override function createChildren():void
{
for (var i:int = 0; i < results.length; i++) {
var itemC:UIComponent =
factory.getComponent(results[i]);
addChild(itemC);
itemC.addEventListener(MouseEvent.CLICK,
getClickFunction(i));
}
private function getClickFunction(index:int):Function {
return function (event:MouseEvent):void
{
selectedIndex = index;
};
}
Unfortunately when the webservice retrieves its results and addPopUp is called, nothing shows up.
Currently the factory.getComponent method is executing this code
public function getComponent(user:Object):UIComponent
{
var email:Label = new Label();
email.text = user.email;
var name:Label = new Label();
name.text = user.displayName;
var vbox:VBox = new VBox();
vbox.addChild(name);
vbox.addChild(email);
return vbox;
}
I think you ought to look for someone who has already implemented this. While your issue is probably related to not positioning and sizing the component before calling addPopup() even if we helped you solve that you still have a lot more work todo. (BTW call super.createChildren in your override or else bad things will happen). Anyway, check this out:
http://www.adobe.com/cfusion/exchange/index.cfm?event=extensionDetail&extid=1047291
Finally I figured out how to use the List control and I stopped using a factory to generate components, instead I use the itemRenderer feature in the list control. I also used that to replace the custom popup class, and I added a positioning function to be called later. By combining these things I was able to get the drop down to display as expected. It appears that some components do not work well as pop ups.
Regardless, the working pop up code is
Inside my autocomplete component which extends HBox
dropDownList = new List();
dropDownList.itemRenderer = itemRenderer;
dropDownList.dataProvider = results;
dropDownList.labelFunction = labelFunction;
dropDownList.rowCount = results.length;
dropDownList.labelFunction = labelFunction==null ?
defaultLabelFunction : labelFunction;
dropDownList.tabFocusEnabled = false;
dropDownList.owner = this;
PopUpManager.addPopUp(IFlexDisplayObject(dropDownList), DisplayObject(this));
callLater(positionDropDownList);
Method in the autocomplete component (textInput is my text field)
public function positionDropDownList():void {
var localPoint:Point = new Point(0, textInput.y);
var globalPoint:Point = localToGlobal(localPoint);
dropDownList.x = globalPoint.x;
var fitsBelow:Boolean = parentApplication.height - globalPoint.y - textInput.height > dropDownList.height;
var fitsAbove:Boolean = globalPoint.y > dropDownList.height;
if (fitsBelow || !fitsAbove) {
dropDownList.y = globalPoint.y + textInput.measuredHeight;
} else {
dropDownList.y = globalPoint.y - dropDownList.height;
}
}
The position function was code that I borrowed from http://hillelcoren.com/flex-autocomplete/