Is it possible to draw a transparent layer without using Image?-LibGdx - java

In my game, when I click a button, popup will come out.
At the same time,I want to draw a transparent layer over the screen except popup, to make an impression like while popup is active,background is disabled.
Something like this:
Is it possible to make an existing solid image to create a transparent overlay ?
or
I should use a transparent image itself to make the impression of transparent layer ?

Image is an Actor that can be drawn but you need transparency for your actor, use Actor.
Create an Actor as transparent layer and add in proper order so that you can disable touch for background actor only.
You should maintain order of Actors.
stage=new Stage();
Texture texture=new Texture("badlogic.jpg");
Image image=new Image(texture);
image.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
Gdx.app.log("TouchTest","Clicked on Image");
}
});
stage.addActor(image);
Actor actor=new Actor(); // this is your transparent layer
actor.setSize(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
stage.addActor(actor);
// Popup should on the top or your actor(touch layer)
Image image1=new Image(texture);
image.setPosition(100,100);
stage.addActor(image1);
Gdx.input.setInputProcessor(stage);
You can also manage touchability of your touch layer.
actor.setTouchable(Touchable.disabled); // when you want to disable touch on
In my suggestion you should use Dialog for your popup. Dialog is a modal window containing a content table.
EDIT
From your reference image it's seems that you need semi-transparent layer so use semiTL instead of Actor in above code.
Pixmap pixmap = new Pixmap(1,1, Pixmap.Format.RGBA8888);
pixmap.setColor(Color.BLACK);
pixmap.fillRectangle(0, 0, 1, 1);
Texture texture1=new Texture(pixmap);
pixmap.dispose();
Image semiTL=new Image(texture1);
semiTL.setSize(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());
semiTL.getColor().a=.8f;
stage.addActor(semiTL);

As Abhishek Aryan said, you can use Pixmap to create the sized foundation for your background. But instead of using an image, you can use sprite and sprite drawable like this
private Drawable getStageBackground() {
Pixmap stageBg = new Pixmap(
Gdx.graphics.getWidth(),
Gdx.graphics.getHeight(),
Pixmap.Format.RGB888);
Sprite image = new Sprite(new Texture(stageBg));
image.setColor(1, 1, 1, 0.7f);
return new SpriteDrawable(image);
}
And pass this drawable in your dialog window style with stageBackground property like this
Window.WindowStyle style = new Window.WindowStyle();
style.stageBackground = getStageBackground();

Related

Adding a Custom Image to a GUI based Game

I am in the process of programming a game and I would like to change the black background to a custom image. How can this be done?
setBackground(Color.BLACK);
I've tried to add this inside the method:
new ImageIcon("src/image/TheSnakeBody.png")
But it did not work.
Any suggestions?
Here's the code:
private void RunningBoard() {
addKeyListener(new KeysAdapter());
setBackground(Color.BLACK);
setFocusable(true);
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
Icons.IconsUsed();
RunningGame();
}
Well, there's actually no such thing as background in game development.
Games, as being rendered, aren't static/moving images on other image. The whole screen is being rendered many times a second.
So to achieve the "effect" of black background, you need to first draw a black rectangle on your screen, and then your other figutres.
setColor(Color.BLUE);
drawRect(0, 0, 1920, 1080); // or your screen size

Highlight Part of Image Icon on JLabel in Java

I have an image of a map. When the user clicks a button, I want to put a red square box as a highlight on a certain location of the map like this:
How do I highlight a portion like this?
Currently, I am achieving this by creating a new image which has this area highlight and loading that image when the user clicks on the button. However in this case I'll have to develop 66 images and load one for each button.
Extend the JLabel to do custom painting.
You would keep an ArrayList of Rectangles that you want to paint. When you click a button you add a Rectangle to the ArrayList. Then in the paintComponent(...) method you iterate through the ArrayList to paint each Rectangle.
So the basic changes to the extend the JLabel would be:
private ArrayList<Rectangle> rectangles = new ArrayList<Rectangle>();
...
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
for (Rectangle r: rectangles)
{
g.setColor( Color.RED );
g.drawRect(...);
}
}
public void addRectangle(Rectangle r)
{
rectangles.add( r );
}
For a working example of this approach check out the DrawOnComponent example found in Custom Painting Approaches.
Another option might be to use a JLayer to paint the Rectangles on the JLabel. Read the section from the Swing tutorial on How to Decorate Component With the JLayer Class for some working examples.
Either way you need to do custom painting. Try both approaches to see which you prefer.

Paint an image on parent component

I'm developing an application that has to draw a map.
I have a JPanel grid that contains a 2D array of JPanel cells.
I'm using this:
public class myCell extends JPanel {
...
#Override
public void paint(Graphics g){
super.paint(g);
if (imageForeground != null) {
g.drawImage(imageForeground, 0, 0, this);
}
}
#Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(imageBackground, 0, 0, this);
}
}
This draws my background image, and my foreground image on top of it.
I want to draw an image in a cell, that will be displayed on TOP of the OTHER cells, ie, draw an image bigger than the cell, FROM the cell, something like:
#Override
public void paint(Graphics g){
super.paint(g);
super.drawImage(imageForeground, 0, 0, this);
or
g.drawImage(imageForeground, 0, 0, this, overflowFromPanel == true);
}
or if it's possible, tell the image that it CAN be bigger than my Cell.
For more informations:
The background cells are all 1*1 in size. The foreground image must be drawn over ALL the background images it spread over.
For example, if I draw a 3*3 hours at the [1,1] square, it must be over the [1,1], [1,2], [1,3], [2,1], etc...
Custom painting is done by overriding the paintComponent() method, not paint().
I'm developing an application that has to draw a map.
So the background image is the map and covers the entire panel. The house would then be painted on top of the map.
So in the parent component you override paintComponent() and paint the background image
Then in the CellPanel, you override paintComponent() and paint the foreground image. Although, why don't you just use a JLabel with an ImageIcon so you don't need to do custom painting?
if I draw a 3*3 hours at the [1,1] square,
Then you need to add your house image to 9 cells .
The other option is to forget about defining your map into cells. Instead you create a custom object with two properties:
Point - a point on the background map
Image - the image to paint at that point.
Then you add this custom Object to an ArrayList. Then in the paintCompont() method of the main panel you iterate through this ArrayList and paint each image at its specified location.
#Overide
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(...); // paint the background
for (each item in the ArrayList)
{
Point p = item.getPoint();
Image image = item.getImage();
g.drawImage(...);
}
}
Edit:
On a side note: the background is a different image for every cell.
Why are you using cells? It sounds like you have a fixed size grid. So you can just paint the individual cell images to a larger BufferedImage that makes a single background image for all the cells. Then you can just paint houses over top of the background.
Another option is to use the OverlayLayout. It allows you to stack two panels on top of one another.
So the logic would be something like:
JPanel panel = new JPanel();
panel.setLayout( new OverlayLayout(panel) );
panel.add( foregroundPanel );
panel.add( backgroundPanel );
You would need to:
Set the "foregroundPanel" transparent.
Both panels would override the paintComponent(...) method to do the custom painting.
Set the size of both panels to be the same.
Or you could use a JLayeredPane.

How to create a button in Libgdx?

I want to create a button that changes when the user hovers it, or clicking it.
I created the following variable
Button buttonPlay = new Button();
I don't know what to do now, how to load the images? How to write text into the button? How to implement the events / effects (hover, click)?
It would be very helpful if someone could write some example code for a button.
A button is simply an actor in libgdx. To render an actor you use a stage that contains all the actors of the screen, renders them and updates them. I assume you want a button with text, so you should use the class TextButton and add it to a stage. A TextButton takes a string to render and a ButtonStyle, in this case a TextButtonStyle, which is basically a class that contains all the information about the button (font, drawable to render while not pressed, drawable to render while pressed etc).
public class ButtonExample extends Game{
Stage stage;
TextButton button;
TextButtonStyle textButtonStyle;
BitmapFont font;
Skin skin;
TextureAtlas buttonAtlas;
#Override
public void create() {
stage = new Stage();
Gdx.input.setInputProcessor(stage);
font = new BitmapFont();
skin = new Skin();
buttonAtlas = new TextureAtlas(Gdx.files.internal("buttons/buttons.pack"));
skin.addRegions(buttonAtlas);
textButtonStyle = new TextButtonStyle();
textButtonStyle.font = font;
textButtonStyle.up = skin.getDrawable("up-button");
textButtonStyle.down = skin.getDrawable("down-button");
textButtonStyle.checked = skin.getDrawable("checked-button");
button = new TextButton("Button1", textButtonStyle);
stage.addActor(button);
}
#Override
public void render() {
super.render();
stage.draw();
}
}
So whats happening here? I am creating a stage, a font and a textureatlas with all the textures for the buttons in "buttons.pack". Then I initialize an empty TextButtonStyle and
and i add the font and the textures for the up, down and checked states. font, up, down and checked are all static variables of type Drawable so you can really pass it any kind of Drawable (texture, 9-patch etc). Then simply add the button to the Stage.
Now in order to do something when the button is actually clicked, you have to add a listener to the button, a ChangeListener.
button.addListener(new ChangeListener() {
#Override
public void changed (ChangeEvent event, Actor actor) {
System.out.println("Button Pressed");
}
});
Of course instead of adding the button directly to the Stage you should add it to a Table and add the Table to the Stage but I didn't want to make this post too confusing. Here is a good tutorial on tables in libgdx.
This is how you do it without adding any skin
TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle();
textButtonStyle.font = yourCustomFont;
textButtonStyle.fontColor = Color.WHITE;
stage.add(new TextButton("Custom Btn ", textButtonStyle));
buttons.pack is the file generated from the libgdx texture packer, texture packer is the tool which can used to generate the texture atlas , That is multiple images you can loaded to the GUI using a single file . it also help to save some memory please refer this link`https://code.google.com/p/libgdx-texturepacker-gui/downloads/list,
https://github.com/libgdx/libgdx/wiki/Texture-packer

SWT drag and drop custom Control displayed next to cursor

How do i display some custom Controls or widgets next to cursor when dragging in SWT?
Like Button or Tree or Table not Image.
If it is not possible - how do i render such a Button into Image?
I've found the way of rendering arbitrary Control (widget) into Image using GC (canvas) class. Here is how:
dragSource.addDragListener(new DragSourceListener() {
#Override
public void dragStart(DragSourceEvent dragSourceEvent) {
// getting control widget - Composite in this case
Composite composite = (Composite) ((DragSource) dragSourceEvent.getSource()).getControl();
// Getting dimensions of this widget
Point compositeSize = composite.getSize();
// creating new GC
GC gc = new GC(composite);
// Creating new Image
Image image = new Image(Display.getCurrent(),compositeSize.x,compositeSize.y);
// Rendering widget to image
gc.copyArea(image,0,0);
// Setting widget to DnD image
dragSourceEvent.image = image;
}
... other overriden methods ...
}
You could use an undecorated Shell that follows the mouse position, and in that Shell have the widget(s) you want to display.

Categories