How to use native Textview (View) in Andengine Game Activity - android

I want to know is there any way to use native TextView or any other layout of android inside BaseAndEngine Activity.
My application is using Andengine for one of its whole screen. This screen is extended from BaseAndEngine and I need to use some native view like textview inside that screen. Because Andengine does not work fine for Arabic text and I need to show some Arabic text on gaming screen.
OR if possible how to show Arabic text in changeable text in Andengine. As changeable text write Arabic from left to right in reverse order.

Of course you can.
Check this code out - basically you override onSetContentView, then you can set whatever you want.
#Override
protected void onSetContentView() {
final FrameLayout frameLayout = new FrameLayout(this);
final FrameLayout.LayoutParams frameLayoutLayoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT, FrameLayout.LayoutParams.FILL_PARENT);
this.mRenderSurfaceView = new RenderSurfaceView(this);
mRenderSurfaceView.setRenderer(mEngine);
final FrameLayout.LayoutParams surfaceViewLayoutParams = new FrameLayout.LayoutParams(super.createSurfaceViewLayoutParams());
frameLayout.addView(this.mRenderSurfaceView, surfaceViewLayoutParams);
//Create any other views you want here, and add them to the frameLayout.
this.setContentView(frameLayout, frameLayoutLayoutParams);
}
(This method goes to your subclass of BaseGameActivity.)
You could also do it through xml, but I think this method is more clear.

You can use Andengine for Arabic and Persian fonts too. But in a different manner. to do that you need to create a Sprite and add a bitmap to it. before that you draw your text on that bitmap.
the following code is an example that draw the Persian/Arabians text and attach it to a sprite. so we can attach the sprite to our scene.
this is an example to show how we can do that, so you can adjust the bitmap and text size by yourself.
if your device support Persian/Arabians, this code will work properly. if the text does not appear in your scene, change its position, it is out of screen
the example code function will print the "Persian Golf" in Persian/Arabians.
private void persianGolfPrinter(){
BitmapTextureAtlas mBitmapTextureAtlas = new BitmapTextureAtlas(ResourceManager.getInstance().gameActivity.getTextureManager(), 400, 800, TextureOptions.BILINEAR);
ITextureRegion mDecoratedBalloonTextureRegion;
final IBitmapTextureAtlasSource baseTextureSource = new EmptyBitmapTextureAtlasSource(400, 800);
final IBitmapTextureAtlasSource decoratedTextureAtlasSource = new BaseBitmapTextureAtlasSourceDecorator(baseTextureSource) {
#Override
protected void onDecorateBitmap(Canvas pCanvas) throws Exception {
this.mPaint.setColor(Color.BLACK);
this.mPaint.setStyle(Style.FILL);
this.mPaint.setTextSize(32f);
this.mPaint.setTextAlign(Align.CENTER);
pCanvas.drawText("خلیج فارس", 150, 150, this.mPaint);
}
#Override
public BaseBitmapTextureAtlasSourceDecorator deepCopy() {
throw new DeepCopyNotSupportedException();
}
};
mDecoratedBalloonTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromSource(mBitmapTextureAtlas, decoratedTextureAtlasSource, 0, 0);
mBitmapTextureAtlas.load();
Sprite test = new Sprite(0,0,mDecoratedBalloonTextureRegion,ResourceManager.getInstance().engine.getVertexBufferObjectManager());
this.attachChild(test);
}
don't use android textview... it makes your game ugly ....

You cannot use them directly in AndEngine, because the objects in Andengine are OpenGL objects. But you can use android OS to draw a bitmap of any standard view, and then create a texture and a sprite from that view. This is less than optimum for a case such as arabic text, but it will work. Be careful about memory leaks as you create the bitmaps of your views.

Related

Table in native app and WCAG 2,0

I would like to work out what is required to make a simple standard table in a native android app compliant to WCAG 2.0.
I thinking about the requirement 1.3.1 Info and Relationships: Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text. (Level A)
I habe specially poblems with the requirememt of having headers in tables. I even don't know whether it is possible to reach this aim.
For a example of a simple table I took this one https://developer.android.com/guide/topics/ui/layout/grid.html
Thanks in advance.
Best regards
Petra Ritter, accessibility consultant, Foundation access for all
http://www.access-for-all.ch/en/
It is very simple.
Declare a Popupwindow and View as below.
PopupWindow layoutWindow;
View javaLayoutView;
JavaClassName _activity = this;
Write a Java Void method.
In this method add code below.
below will increase speed. if PopupWindow has a somthing method will not go longer else will go further.
if(layoutWindow != null)
return;
Assiggn Activity to this thread.
_activity = this;
Calling the method from Native side will not run directly because our activity is Native Activity since. So it will execute in Ui Thread.
this.runOnUiThread(new Runnable(){
#Override
public void run(){
// Make a Inflator Layout. Our XML Layout will work on this.
LayoutInflater lF =
(LayoutInflator)getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE);
javaLayoutView = lF.inflate(R.layout.layoutfile, null);
layoutWindow = new PopupWindow( javaLayoutView, LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
LinearLayout mainLayout = new LinearLayout(_activity);
MarginLayoutParams params = new
MarginLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.setMargin(0, 0, 0, 0);
_activity.setContentView(mainLayout, params);
layoutWindow.showAtLocation(mainLayout, Gravity.TOP, 0, 0);
layoutWindow.update();
}
});
Here your layout file will be executed on LinearLayout doesn't matter what layout you used in XML. Here by changing LayoutParams.MATCH_PARENT you can change the width and height.
The line layoutWindow.showAtLocation(mainLayout, Gravity.TOP, 0, 0); will make render your layout over Native Activity,
Remember that If you change anything after layoutWindow.update() must recall it to take effect.
This will damn sure work !!!

Precise position of widgets for libGDX scene2d

I want to layout a set off press-able piano keys in my libGDX app, something like the following:
When a key is pressed, I need to change it from the up to down position (this is easy using an image button).
What I'm struggling with is how to layout all of the buttons such that they for something that resembles a piano keyboard. The white piano key images are rectangular, but a black piano key needs to be placed on top of it. Below shows what one of my white piano key images looks like, there is dead space in the top corner where I intend to put a black note.
Using a Table won't work, as tables layout everything side-by-side, which would leave me with gaps. I've seen you can use a Stack, but that just lays every child directly on top of the last, so that doesn't seem to help either.
If it helps, my code is something like this:
Skin skin;
Stage stage;
SpriteBatch batch;
private TextButton button1;
private TextButton button2;
#Override
public void create () {
batch = new SpriteBatch();
stage = new Stage();
Gdx.input.setInputProcessor(stage);
createSkin();
Table table = new Table();
table.setFillParent(true);
stage.addActor(table);
// Create a button with the "default" TextButtonStyle. A 3rd parameter can be used to specify a name other than "default".
button1 = new TextButton("First note", skin);
button1.getLabel().setFontScale(5);
button2 = new TextButton("Second note", skin);
button2.getLabel().setFontScale(5);
table.add(button1).width(500).height(500);
table.add(button2).width(500).height(200);
}
#Override
public void render () {
super.render();
Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
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);
}
#Override
public void dispose () {
stage.dispose();
skin.dispose();
}
private void createSkin() {
skin = new Skin();
Pixmap pixmap = new Pixmap(1, 1, Pixmap.Format.RGBA8888);
pixmap.setColor(Color.WHITE);
pixmap.fill();
skin.add("white", new Texture(pixmap));
skin.add("default", new BitmapFont());
TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle();
textButtonStyle.up = skin.newDrawable("white", Color.DARK_GRAY);
textButtonStyle.down = skin.newDrawable("white", Color.BLUE);
textButtonStyle.checked = skin.newDrawable("white", Color.DARK_GRAY);
textButtonStyle.over = skin.newDrawable("white", Color.DARK_GRAY);
textButtonStyle.font = skin.getFont("default");
skin.add("default", textButtonStyle);
}
Which renders this:
There's no way to overlap things as far as I can tell using table, but I can't find another way of doing it. Is doing this possible using scene2d?
The simpliest solution seems to be to create second Stage with same viewport (stages needs to behave in the same way in case of resizing) and place it over your current one. You need to create same table but fullfill it only with black notes (your current stage would contains only white ones of course).
Notice that you will need to use InputMultiplexer to get event from both stages - you can read here about how to use it.
Add all the Buttons that represent keys to the stage directly without putting them in a Table. Set their positions manually. Should be pretty easy to do manually since piano keys have a clear pattern. Add the black keys after adding the white keys. Then you don't have to worry about the white keys being non-rectangular because the black keys will get prioritized for receiving input.

LibGDX - How do I get my screen to display "LEVEL COMPLETE"?

I want the game screen on the Android device to change to a screen that displays "LEVEL COMPLETE". I made a .png file with this message in the middle and want to basically load it on top of the current screen (like a Fragment i guess?) when Player collides with Flag (both are modelled as rectangles for the sake of collision detection). This is my Flag class
public class Flag extends GameObject {
private Sprite spr;
private Rectangle playerRect;
private boolean isOverlapping;
Player player;
private Rectangle flagRect;
public Flag(Sprite spr, float xPos, float yPos) {
super(spr, xPos, yPos);
player = Player.getInstance(null);
setxPos(xPos);
setyPos(yPos);
flagRect = new Rectangle(getxPos(), getyPos(), getSprite().getWidth(),
getSprite().getHeight());
}
public void update() {
playerRect = new Rectangle(player.getxPos(), player.getyPos(), player
.getSprite().getWidth(), player.getSprite().getHeight());
isOverlapping = playerRect.overlaps(flagRect);
if(isOverlapping) {
...
}
}
}
I put levelComplete.png in my assets folder and am a little unsure where to go from here. Any suggestions? Would be highly appreciated
All you need to do is make a Texture from your image and draw it on your screen using SpriteBatch. This can be achieved with something like this:
public Texture levelComplete = new Texture(Gdx.files.internal("assets/imageName.png"));
public SpriteBatch batch = new SpriteBatch();
public render(){
batch.begin();
if(isOverlapping){
batch.draw(levelComplete, x, y);
}else{
// render game
}
batch.end();
}
Note that you might want to put some timer and stop drawing the Texture after like 5 seconds or put some sort of "ok" button. Otherwise you will be stuck with the same Texture.
Instead of creating an image that contain your text "Level Complete " you can use BitmapFont to write it down on your screen with any font you like
first choose your font (you can generate any font you want using tools like Hiero)
put them on assets file and load them using this line of code
textFont = new BitmapFont(Gdx.files.internal("nameFont.fnt"), gdx.files.internal("nameFont.png"), false);
then you have just to write your text in the position you want
textFont.draw(spritebatch, "Level Complete", x, y)
hope it will help !

Avoiding object allocations in onDraw() (StaticLayout)?

I have a custom view which I quickly learned to not do object allocations in and moved all my Paint allocations into a different method, fine.
I need to use a StaticLayout however for some text that had some spannable 'stuff' applied.
layoutBpm = new StaticLayout(bpmValue,
textPaintBPM, arcRadius, Layout.Alignment.ALIGN_NORMAL, 0, 1,
false);
layoutBpm.draw(canvas);
This seemed to make sense to me to have in onDraw but I am of course getting warned to avoid this. It is important to me that I do everything I can to avoid any performance issues so I am trying to do this properly.
I can't seem to find any documentation I can understand that explains what some of the parameters to StaticLayout actually do (float spacingmult? float spacingadd?), but the third one there I think is maximum width for the StaticLayout text which I can only get from onMeasure as it relates to my canvas size. This leaves me wanting to put the assignment in onMeasure or onDraw, neither of which it seems I am meant to do. Is it okay to put StaticLayout assignment in onDraw or is there a better way to do this?
Hope this makes sense, I am very new to this. Thank you for any help.
(edit: I assume putting this assignment in a method and calling from onDraw/onMeasure is just being silly and will stop Eclipse warning me but wont actually help?)
The reason for the warning is because, very often, you do not need to recreate an object multiple times in a draw operation. onDraw() could be called hundreds of times compared to other methods in a View. Most of the time, the objects being recreated are being recreated with the exact parameters. Other times, it's simply less overhead to change an object's state than it is to create a new object.
In the case of a StaticLayout, you only need to create a new one when the text changes or when you adjust the padding, spacing, or maxwidth. If the text changes often, then you may want to consider DynamicLayout which will remeasure itself every time. Remeasuring costs more overhead than creating a new object, but there's no way it's happening more often than onDraw() calls.
If the text doesn't change often and you absolutely MUST use a StaticLayout, then you can get away with something like this structure.
StaticLayout myLayout;
String textSource = defaultSource;
Paint textPaint = defaultPaint;
int textWidth = defaultWidth;
public CustomView(Context ctx) {
super(ctx);
createLayout();
}
public void setText(String text) {
textSource = text;
createLayout();
}
public void setWidth(int width) {
textWidth = width;
createLayout();
}
#Override
public void onDraw(Canvas canvas) {
myLayout.draw(canvas);
}
private void createLayout() {
myLayout = new StaticLayout(textSource, textPaint, textWidth, Layout.Alignment.ALIGN_NORMAL, 0, 1, false);
}
Basically, you only create a new layout when something changes. Else you just reuse the last object you created.
EDIT:
One way to skip a measure pass is to call View#measure on the newly resized view itself. So your createLayout() method would be something like this.
private void createLayout() {
myLayout = new StaticLayout(textSource, textPaint, textWidth, Layout.Alignment.ALIGN_NORMAL, 0, 1, false);
int textWidthSpec = MeasureSpec.makeMeasureSpec(maxLayoutWidth, MeasureSpec.AT_MOST);
int textHeightSpec = MeasureSpec.makeMeasureSpec(maxLayoutHeight, MeasureSpec.AT_MOST);
myLayout.measure(textWidthSpec, textHeightSpec);
forceLayout();
}
Basically what this does is tells the layout the maximum the View can be. It will measure itself and it's children. The forceLayout() will be invoked on the parent (your custom view) which will re-layout the other contents based on the new measurements.
I should note that I have never done this with a StaticLayout so I have no idea what will happen. It seems like this type of measurement might already be handled when the View is created, but maybe not.
I hope this helps.

UI API for libgdx

Android and libgdx noob here.
Does anyone know anything about the recent UI API that was released for libgdx?
See blog post here: http://www.badlogicgames.com/wordpress/?p=2058
I am looking to create a basic menu system, and I was wondering if this UI API would make it easier.
Updated to reflect changes to the LibGDX
I am in a similar position, the following code worked for me to create a basic menu (A container of buttons). The code won't work as is, because it uses some of my classes, but what really matter is the content of the create method. This creates a centered title, then some buttons in a container that gets centered, then fps label in the lower left and an image in the lower right corner. The theme files and some of the images are from the LibGDX tests assets.
I've gotten this to work with the JOGL, LWJGL, and android application classes. I've run it on a Droid 2 and got it to run as it did on my desktop. Hopefully this should get you started.
public class MenuScreen extends Screen{
private Stage ui;
private Table window;
#Override
public void create(final Game game) {
super.create(game);
TextureRegion image = new TextureRegion(new Texture(Gdx.files.internal(Art.badlogicSmall)));
Label fps = new Label("fps: ", Art.sSkin.getStyle(LabelStyle.class),"fps");
ui = new Stage(Gdx.graphics.getWidth(),Gdx.graphics.getHeight(), true);
Gdx.input.setInputProcessor(ui);
window = new Table("window");
window.width = ui.width();
window.height = ui.height();
window.x = 0;
window.y = 0;
window.debug();
Label title = new Label("Title",Art.sSkin.getStyle(LabelStyle.class),"title");
Button newGame = new Button("New Game",Art.sSkin.getStyle(ButtonStyle.class),"new");
newGame.setClickListener(new ClickListener() {
#Override
public void click(Actor actor) {
game.setScreen(GameScreen.class);
}
});
Button optionMenu = new Button("Option",Art.sSkin.getStyle(ButtonStyle.class),"Options");
Button helpMenu = new Button("Help",Art.sSkin.getStyle(ButtonStyle.class),"Help");
Image libgdx = new Image("libgdx", image);
window.row().fill(false,false).expand(true,false).padTop(50).padBottom(50);
window.add(title);
Table container = new Table("menu");
container.row().fill(true, true).expand(true, true).pad(10, 0, 10, 0);
container.add(newGame);
container.row().fill(true, true).expand(true, true).pad(10, 0, 10, 0);
container.add(optionMenu);
container.row().fill(true, true).expand(true, true).pad(10, 0, 10, 0);
container.add(helpMenu);
window.row().fill(0.5f,1f).expand(true,false);
window.add(container);
Table extras = new Table("extras");
extras.row().fill(false,false).expand(true,true);
extras.add(fps).left().center().pad(0,25,25,0);
extras.add(libgdx).right().center().pad(0,0,25,25);
window.row().fill(true,false).expand(true,true);
window.add(extras).bottom();
ui.addActor(window);
}
#Override
public void render(float arg0) {
Gdx.gl.glClearColor(0.2f, 0.2f, 0.2f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
((Label)ui.findActor("fps")).setText("fps: " + Gdx.graphics.getFramesPerSecond());
ui.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
ui.draw();
Table.drawDebug(ui);
}
#Override
public void resize(int width, int height) {
ui.setViewport(width, height, true);
Log.d("Resize: "+width+", "+height);
}
Yes, the the new UI api is very easy to use. You can use the Skin object to create some Actor object, and then join them to the Stage object.
You can reference the UITest.java file in the libgdx source. It demonstrates how to use the basic UI elements.
From low level to see the libgdx new UI, it only include the following element:
NinePatch: the basic shape object for create the element could stretch up;
Region: the shape object for the fixed size element;
Font: the bitmapfont object for display text;
The high level element is composed by them, such as the Button object, include: ninepatch and font ojbect, and so on.
So, you can very easy to create the 2D UI use them. :)

Categories

Resources