What does parameter targetWidth exactly means here and what it has to do with wrap parameter?
public GlyphLayout (BitmapFont font, CharSequence str, Color color, float targetWidth, int halign, boolean wrap) {
setText(font, str, color, targetWidth, halign, wrap);
}
From doc :
targetWidth : The width used for alignment, line wrapping, and truncation. May be zero if those features are not used.
wrap : If true then (a word or unit of text) to be carried over to a new line automatically as the margin is reached, or to fit around embedded features.
If false, the text will only wrap where it contains newlines (\n).
EDIT
Test code : Practical demonstration, how targetWidth and wrap works in GlyphLayout constructor.
public class MyGdxGame extends ApplicationAdapter {
private GlyphLayout glyphLayout[];
private BitmapFont bitmapFont;
private float targetWidth=250;
private ShapeRenderer shapeRenderer;
private SpriteBatch spriteBatch;
private float xPos[]={450,450,450,30,450,880};
private float yPos[]={550,480,410,340,340,340};
#Override
public void create () {
spriteBatch=new SpriteBatch();
shapeRenderer=new ShapeRenderer();
shapeRenderer.setAutoShapeType(true);
bitmapFont=new BitmapFont(Gdx.files.internal("skin/poet.fnt"));
glyphLayout=new GlyphLayout[6];
glyphLayout[0]=new GlyphLayout(bitmapFont, "LOADING SCREENsssssssssssssssssssssssssssssssssssss", Color.BLACK, targetWidth, Align.left, false);
glyphLayout[1]=new GlyphLayout(bitmapFont, "LOADING SCREENsssssssssssssssssssssssssssssssssssss", Color.BLACK, targetWidth, Align.right, false);
glyphLayout[2]=new GlyphLayout(bitmapFont, "LOADING SCREENsssssssssssssssssssssssssssssssssssss", Color.BLACK, targetWidth, Align.center, false);
glyphLayout[3]=new GlyphLayout(bitmapFont, "LOADING SCREENsssssssssssssssssssssssssssssssssssss", Color.BLACK, targetWidth, Align.left, true);
glyphLayout[4]=new GlyphLayout(bitmapFont, "LOADING SCREENsssssssssssssssssssssssssssssssssssss", Color.BLACK, targetWidth, Align.right, true);
glyphLayout[5]=new GlyphLayout(bitmapFont, "LOADING SCREENsssssssssssssssssssssssssssssssssssss", Color.BLACK, targetWidth, Align.center, true);
}
#Override
public void render() {
Gdx.gl.glClearColor(1f, 0f, 0f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.begin();
for (int i=0;i<glyphLayout.length;i++) {
bitmapFont.draw(spriteBatch, glyphLayout[i], xPos[i], yPos[i]);
}
spriteBatch.end();
shapeRenderer.begin();
shapeRenderer.setColor(Color.BLUE);
shapeRenderer.set(ShapeRenderer.ShapeType.Filled);
for (int i=0;i<glyphLayout.length;i++) {
shapeRenderer.rectLine(xPos[i], yPos[i], xPos[i] + targetWidth, yPos[i], 3f);
}
shapeRenderer.end();
}
#Override
public void dispose () {
bitmapFont.dispose();
shapeRenderer.dispose();
spriteBatch.dispose();
}
}
Output :
Target width is the lenient maximum width that the text will be before it is wrapped, truncated or otherwise altered from being a single line.
e.g. Consider a string of width 500 (when drawn). With a target width of 250, it will be wrapped at ~250 into 2 lines (if wrap is true).
Related
I have a difficult situation.
I'm making a 2D game and I'm on the step
of integrating box2Dlights part.
But when i'm rendering my RayHandler, I have a black screen.
Here is another image, where I don't render my lights. There is no lights now.
I need to have collision of Box2D and Box2Dlights mixed together.
Please note:
All my boxes are made in units, equal to 1, so that one room is 16 squares length.
All entire world is zoomed by setToOrtho((16 - 1.875f) / Gdx.graphics.getHeight()), where 16 is tile size.
If I scaled my tile size, I would like to have this stuff work.
All code is complicated so I send the only GameScreen and GameMap classes for now:
#Override
public void show() {
InstanceVars inst = InstanceVars.getInstance();
inst.world = new World(new Vector2(0, 0f), true);
inst.engine = new Engine();
inst.handler = new RayHandler(inst.world);
LevelCreator creator = new LevelCreator("level_def.cfg");
try {
gameWorld = creator.createNewLevel();
gameWorld.start();
} catch (FileCorruptedException e) {
e.printStackTrace();
}
}
#Override
public void render(float delta) {
gameWorld.render();
}
#Override
public void resize(int width, int height) {
gameWorld.resize(width, height);
}
#Override
public void dispose() {
gameWorld.dispose();
InstanceVars.getInstance().dispose();
}
for the GameScreen.java
and
private World physWorld = InstanceVars.getInstance().world;
private Box2DDebugRenderer physRender = new Box2DDebugRenderer();
private OrthographicCamera cam = new OrthographicCamera();
private RayHandler lights = new RayHandler(physWorld);
private PlayerController controls;
private float STD_ZOOM = ((float) CELL_SIZE + 16) / Gdx.graphics.getHeight();
private Body playerBody;
public GameMap() {
cam.zoom = STD_ZOOM;
}
public void start() {
GameObject player = (GameObject) getProperties().get("ent_player");
playerBody = player.getComponent(PhysicsComponent.class).getBody();
controls = new PlayerController();
Gdx.input.setInputProcessor(controls);
physWorld.setContactListener(new CollisionInteractor(InstanceVars.getInstance().engine));
PointLight light = new PointLight(lights, 1000, Color.GOLDENROD, 500, playerBody.getPosition().x, playerBody.getPosition().y);
}
public void render() {
updatePlayer();
physWorld.step(1/60f, 8, 2);
updateCamera();
physRender.render(physWorld, cam.combined);
// lights.updateAndRender();
}
private void updatePlayer() {
if (controls.up) playerBody.setLinearVelocity(playerBody.getLinearVelocity().x, -controls.speed);
else playerBody.setLinearVelocity(playerBody.getLinearVelocity().x, controls.down ? controls.speed : 0);
if (controls.down) playerBody.setLinearVelocity(playerBody.getLinearVelocity().x, controls.speed);
else playerBody.setLinearVelocity(playerBody.getLinearVelocity().x, controls.up ? -controls.speed : 0);
if (controls.left) playerBody.setLinearVelocity(-controls.speed, playerBody.getLinearVelocity().y);
else playerBody.setLinearVelocity(controls.right ? controls.speed : 0, playerBody.getLinearVelocity().y);
if (controls.right) playerBody.setLinearVelocity(controls.speed, playerBody.getLinearVelocity().y);
else playerBody.setLinearVelocity(controls.left ? -controls.speed : 0, playerBody.getLinearVelocity().y);
}
public void resize(float width, float height) {
STD_ZOOM = ((float) CELL_SIZE - 1.875f) / Gdx.graphics.getHeight();
cam.setToOrtho(true, width, height);
}
private void updateCamera() {
cam.position.set(playerBody.getPosition(), 0);
cam.update();
}
public void dispose() {
super.dispose();
physWorld.dispose();
physRender.dispose();
}
for GameMap.java.
If you need more details, don't be afraid to ask.
I cannot solve the problem on my own.
I'm trying to show a label on the Stage with virtual 16:9 size:
public class MyGdxGame extends ApplicationAdapter {
private Stage stage;
#Override
public void create () {
stage = new Stage(new FillViewport(16, 9));
Label label = new Label("What's wrong with labels?",
new Label.LabelStyle(new BitmapFont(), Color.WHITE));
label.setBounds(0, 0, 16, 9);
stage.addActor(label);
Gdx.input.setInputProcessor(stage);
}
#Override
public void render () {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
stage.draw();
}
#Override
public void dispose () {
stage.dispose();
}
}
The font looks huge and can't fit screen bounds:
Then I try to set font scale and word wrapping:
stage = new Stage(new FillViewport(16, 9));
Label label = new Label("What's wrong with labels?",
new Label.LabelStyle(new BitmapFont(), Color.WHITE));
label.setBounds(0, 0, 16, 9);
label.setFontScale(0.1f);
label.setWrap(true);
stage.addActor(label);
And getting messed completely:
Tried settings viewport size in pixels, like 1080:1920. In this case label is shown small, as expected. But I'd like to have my world size (16:9) work with labels. Can you suggest me how to scale down the font properly?
How to render Hindi text in libgdx using mangal.ttf or any other font.
Square boxes are coming when try to print hindi text.
Try FreeTypeFont, FreetypeFont is available in maven repository so you can easily inject dependency through gradle in your project and use in your code.
public class MyGdxGame extends Game {
SpriteBatch spriteBatch;
BitmapFont font;
OrthographicCamera camera;
GlyphLayout glyphLayout,glyphLayout1;
String text,text1;
#Override
public void create() {
camera=new OrthographicCamera();
camera.setToOrtho(false,400,640);
spriteBatch = new SpriteBatch();
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("Mangal.ttf"));
FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
parameter.color = Color.WHITE;
parameter.magFilter = Texture.TextureFilter.Linear; // used for resizing quality
parameter.minFilter = Texture.TextureFilter.Linear;
//ँंंःअआइईउऊऋएऐऑओऔकखगघचछजझञटठडढणतथदधनपफबभमयरलवशषसह़ािीुूृॅेैॉोौ्
parameter.characters = "शुभ प्रभात आप का स्वागत है"; //The characters the font should contain
parameter.size=15;
font=generator.generateFont(parameter);
font.getRegion().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
font.setColor(1.0f, 0.0f, 0.0f, 1.0f);
generator.dispose();
text="शुभ प्रभात";
text1="आप का स्वागत है";
glyphLayout=new GlyphLayout(font,text);
glyphLayout1=new GlyphLayout(font,text1);
}
#Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearColor(1,1,0,1);
spriteBatch.setProjectionMatrix(camera.combined);
spriteBatch.begin();
font.draw(spriteBatch,text,camera.viewportWidth*.5f-glyphLayout.width/2f,camera.viewportHeight*.5f);
font.draw(spriteBatch,text1,camera.viewportWidth*.5f-glyphLayout1.width/2f,camera.viewportHeight*.4f);
spriteBatch.end();
}
#Override
public void resize(int width, int height) {
camera.setToOrtho(false,width,height);
}
#Override
public void dispose() {
font.dispose();
spriteBatch.dispose();
}
}
Output looks like this :
We can use "Chanakya" font for render the Hindi Text in correct way. Download the chanyaka.ttf from hera :
http://indiatyping.com/index.php/download/199-chanakya-font
After installing the font . You should encode your Hindi text using the coverter :
http://indiatyping.com/index.php/font-converter/unicode-to-chanakya-font-converter
Once converted the text, simply copy it to your destination and you should be good to go!
Enjoy :)
I save an image in a String, then when I open it it's always 300x150
Why is the image truncated?
Where does 300x150 come from?
The code is what you see. Just 2 buttons.
The first one saves the image in "png", and the other reads the image from "png"
Button save = new Button("copy");
save.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
ImageElement imageElement = ImageElement.as(image.getElement());
Canvas canvasTmp = Canvas.createIfSupported();
Context2d context = canvasTmp.getContext2d();
context.drawImage(imageElement, 0.0, 0.0, imageElement.getWidth(), imageElement.getHeight());
png = canvasTmp.toDataUrl("image/png");
}
});
Button open = new Button("open");
open.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
final Image image = new Image(png);
vp.add(image);
image.addLoadHandler(new LoadHandler() {
#Override
public void onLoad(LoadEvent event)
{
Window.alert("ok");
}
});
image.addErrorHandler(new ErrorHandler() {
#Override
public void onError(ErrorEvent event) {
Window.alert("error");
}
} );
}
});
The canvas has a default width of 300 pixels and a default height of 150 pixels. After creating the canvas and before drawing the image, consider doing this:
int width = imageElement.getWidth()
int height = imageElement.getHeight()
canvasTmp.setWidth(width + "px");
canvasTmp.setHeight(height + "px");
canvasTmp.setCoordinateSpaceWidth(width);
canvasTmp.setCoordinateSpaceHeight(height);
I've written an app that custom draws everything inside paint() based on fixed pixel positions. Then I disabled resize of the frame so its always visible.
However, now I would like to be able to resize it but I dont want to change my drawling code. I was hoping I could grab the 300x300 square of the Graphics g object and resize it to the JFrame current size after all of my drawling code, but I have no idea what I'm doing.
Here sample code. In this I want the 100x100 square to remain in the middle, proportionate to the resized JFrame:
package DrawAndScale;
import java.awt.Color;
import java.awt.Graphics;
public class DASFrame extends javax.swing.JFrame {
public DASFrame() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
this.setSize(300, 300);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new DASFrame().setVisible(true);
}
});
}
#Override
public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.fill3DRect(100, 100, 100, 100, true);
}
}
Thanks.
Assuming you rename your method that paints for 300x300 as paint300, define a buffered image:
#Override public void paint(Graphics g) {
Image bufferImage = createImage(300, 300); // empty image
paint300(bufferImage.getGraphics()); // fill the image
g.drawImage(bufferImage, 0, 0, null); // send the image to graphics device
}
Above is when you want to draw at full size (300x300).
If your window is resized:
#Override public void paint(Graphics g) {
Image bufferImage = createImage(300, 300);
paint300(bufferImage.getGraphics());
int width = getWidth();
int height = getHeight();
CropImageFilter crop =
new CropImageFilter((300 - width)/2, (300 - height)/2 , width, height);
FilteredImageSource fis = new FilteredImageSource(bufferImage, crop);
Image croppedImage = createImage(fis);
g.drawImage(croppedImage, 0, 0, null);
}
The new classes are from from java.awt.image.*.
I didn't test this code. It's just to send you in the right direction.
if you want to painting Custom paint then look for JLabel or JPanel and including Icon/ImageIcon inside, simple example about that
import java.awt.*;
import javax.swing.*;
public class MainComponentPaint extends JFrame {
private static final long serialVersionUID = 1L;
public MainComponentPaint() {
setTitle("Customize Preffered Size Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void display() {
add(new CustomComponent());
pack();
setMinimumSize(getSize());
setPreferredSize(getSize());
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
setVisible(true);
}
});
}
public static void main(String[] args) {
MainComponentPaint main = new MainComponentPaint();
main.display();
}
}
class CustomComponent extends JComponent {
private static final long serialVersionUID = 1L;
#Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
int w = getWidth();
int h = getHeight();
for (int i = 0; i < Math.max(w, h); i += 20) {
g.drawLine(i, 0, i, h);
g.drawLine(0, i, w, i);
}
}
}
Not an expert, but you could just scale the Graphics2D object (the passed Graphics is in fact a Graphics2D instance), where the x and y ratios are the ratios of the fixed size you chose to draw and the actual size of the frame.
See http://download.oracle.com/javase/6/docs/api/java/awt/Graphics2D.html#scale%28double,%20double%29
You could do this with some math.
public void paint(Graphics g){
int height = 100;
int width = 100;
int x = (this.getWidth() / 2) - (width / 2);
int y = (this.getHeight() / 2) - (height / 2);
g.setColor(Color.BLACK);
g.fill3DRect(x, y, width, height, true);
}
Or if you wanted to keep the width and height of the box with the same proportion, use int width = this.getWidth() / 3; and int height = this.getHeight() / 3.
The other option is to use Graphics2D.scale(), as JB pointed out, the passed Graphics object is actually a Graphics2D object.