How to erase some part of Texture with Rectangle? - java

I have a Texture that needed to be erase on some point of game. I think its best to clarify my question with picture.
Below is the actual texture.
It is place inside an actor and being call inside the draw after adding to stage.
Below is the partial code of the texture
#Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
batch.draw(trLine,position.x,position.y);
}
I wanted to erase some part of the texture using a Rectangle with x,y,width And height.And also its can be more than one time. How do I achieve this?
Added: I have found a article that use pixmap to load the texture and modifying it using mask. below is the code, but unfortunately , it draw nothing.
Pixmap mask = new Pixmap(trLine.getRegionWidth(), trLine.getRegionWidth(), Pixmap.Format.Alpha);
mask.setBlending(Pixmap.Blending.None);
mask.setColor(0,0,0,0);
mask.fillRectangle((int)rec.x,(int)rec.y,(int)rec.width,(int)rec.height);
Pixmap fg = new Pixmap(trLine.getRegionWidth(), trLine.getRegionWidth(), Pixmap.Format.RGBA8888);
for (int x = 0; x < trLine.getRegionWidth(); x++) {
for (int y = 0; y < trLine.getRegionHeight(); y++) {
int colorInt = fg.getPixel(trLine.getRegionX() + x, trLine.getRegionY() + y);
fg.drawPixel(colorInt,trLine.getRegionX() + x , trLine.getRegionY() + y);
}
}
fg.drawPixmap(mask, fg.getWidth(), fg.getHeight());
mask.setBlending(Pixmap.Blending.SourceOver);
trBlendedLine=new Texture(fg);

Related

Processing - Zoom on clicked area then click again to zoom back out

I have a picture then used a flashlight type of light to only show where the mouse is hovering over. That part of the code works, but now I want to use if/else statements to zoom in on the selected area and then click again to zoom back out. Any other way to zoom in on specific area then back out of that area also helps. Really any help will be appreciated!
PImage ispy;
void setup () {
size(1024,768);
ispy = loadImage("ispy2.jpeg");
}
void draw () {
loadPixels();
ispy.loadPixels();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int loc = x+y*width;
float r = red(ispy.pixels[loc]);
float g = green(ispy.pixels[loc]);
float b = blue(ispy.pixels[loc]);
float d = dist(mouseX, mouseY, x, y); //
float factor = map(d, 0, 200, 2, 0);
pixels[loc] = color(r*factor, g*factor, b*factor);
}
}
updatePixels();
}
Here is my interpretation of what you are talking about. We store a isClicked boolean to store the state of whether we should zoom in or not. When we are going to draw the image, we translate() to the mouse, then we scale(), then we translate() back the same amount that we moved before, but in the opposite direction. What this does is it does the scale transform around the mouse position.
One thing that I couldn't find a way around way your way of updating the pixels directly from the image and the flashlight effect. What the program is doing instead is using your method to make a mask image and applying that to a PGraphics object. Another thing that I noticed is that when just rendering straight to the screen, there is considerable lag from the scaling. Instead, I have moved the drawing to a PGraphics object. This improves the performance.
In the end, to render, the program is drawing everything on the PGraphics object, then applying the mask to that object to get the flashlight effect.
Here is the code that I have:
PImage ispy, distMask;
boolean isClicked = false;
PGraphics renderer;
void createDistanceMask(PImage distMask){ //Takes image and changes its pixels to "alpha" for the PGraphics renderer
distMask.loadPixels();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int loc = x+(height-y-1)*width;
float d = dist(mouseX, mouseY, x, y); //
int factor = int(map(d, 0, 200, 400, 0)); //Pixel data will be between 0 and 255, must scale down later.
if (factor > 255)
factor = 255;
distMask.pixels[loc] = color(factor,factor,factor);
}
}
distMask.updatePixels();
}
void setup () {
size(1024,768, P2D);
ispy = loadImage("ispy2.jpeg");
distMask = new PImage(width,height);
renderer = createGraphics(width,height,P2D);
mouseX = width/2; //Not necessary, but will have black screen until mouse is moved
mouseY = height/2;
}
void draw () {
background(0);
pushMatrix();
createDistanceMask(distMask);
renderer.beginDraw(); //Starts processing stuff into PGraphics object
renderer.background(0);
if(isClicked){ //This is to get the zoom effect
renderer.translate(mouseX, mouseY);
renderer.scale(2);
renderer.translate(-mouseX, -mouseY);
}
renderer.image(ispy,0,0); //Render Image
renderer.endDraw();
renderer.mask(distMask); //Apply Distance mask for flashlight effect
image(renderer,0,0); //Draw renderer result to screen
popMatrix();
}
void mouseClicked(){
isClicked = !isClicked;
}
In my comment, I asked about having the screen move to the mouse, which is what this is doing. If you want to "freeze" the screen in one position, what you can do is store a lastMouseClickPosition PVector or simply just ints. Then, when translating, translate to the position instead of the PVector.
Here's the code that would change:
PVector lastClickPos = new PVector(); //Make the position
if(isClicked){ //When Rendering
renderer.translate(lastClickPos.x, lastClickPos.y);
renderer.scale(scalingFactor);
renderer.translate(-lastClickPos.x, -lastClickPos.y);
}
void mouseClicked(){ //At the bottom
isClicked = !isClicked;
lastClickPos.set(mouseX, mouseY);
}

How to rotate a pixmap by 90º to draw to a texture in libgdx?

I need to rotate a Pixmap by 90 degrees. I have seen an answer that achieves a flipped Pixmap. I need to rotate images that are in portrait orientation to landscape already on the Pixmap-level to later create textures out of them.
similar to the flip pixmap method I achieved a 90º rotated Pixmap like this:
private Pixmap rotatePixmap (Pixmap srcPix){
final int width = srcPix.getWidth();
final int height = srcPix.getHeight();
Pixmap rotatedPix = new Pixmap(height, width, srcPix.getFormat());
for (int x = 0; x < height; x++) {
for (int y = 0; y < width; y++) {
rotatedPix.drawPixel(x, y, srcPix.getPixel(y, x));
}
}
srcPix.dispose();
return rotatedPix;
}
Note that also width & height get swapped after the 90º rotation

Trouble flipping images in Java

So I have to use java.awt.color to flip some imported images.
Here is my primary method to achieve flipping an image over the vertical axis:
public void execute (Pixmap target)
{
Dimension bounds = target.getSize();
// TODO: mirror target image along vertical middle line by swapping
// each color on right with one on left
for (int x = 0; x < bounds.width; x++) {
for (int y = 0; y < bounds.height; y++) {
// new x position
int newX = bounds.width - x - 1;
// flip along vertical
Color mirrorVert = target.getColor(newX, y);
target.setColor(x, y, new Color (mirrorVert.getRed(),
mirrorVert.getGreen(),
mirrorVert.getBlue()));
}
}
}
However, when this executes, instead of the image, flipping, I get something like this:
Original:
"Flipped":
Thank y'all for the help
// flip along vertical
Color mirrorVert = target.getColor(newX, y);
target.setColor(x, y, new Color (mirrorVert.getRed(),
mirrorVert.getGreen(),
mirrorVert.getBlue()));
target.setColor(newX, y , new Color(255,255,255));
}
This should work in theory. Basically the idea is to set the Colors on the right side to white, while copying it over to the left side.
Actually this will not work... So what you could do is to save the new colors in an array. Then you can make everything white and put the swapped colors back.
for (int i=0;i<image.getWidth();i++)
for (int j=0;j<image.getHeight();j++)
{
int tmp = image.getRGB(i, j);
image.setRGB(i, j, image.getRGB(i, image.getHeight()-j-1));
image.setRGB(i, image.getHeight()-j-1, tmp);
}
That one looks promising.

LIBGDX TiledMapTileLayer index out of range layer?

just trying to load a layer from my tilemap in for collision detection, but having problems. Apparently it tells me my layer is out of range.
private void getTiles(int startX, int startY, int endX, int endY, Array<Rectangle> tiles) {
TiledMapTileLayer layer = (TiledMapTileLayer)map.getLayers().get("layer2");
rectPool.freeAll(tiles);
tiles.clear();
for(int y = startY; y <= endY; y++) {
for(int x = startX; x <= endX; x++) {
Cell cell = layer.getCell(x, y);
if(cell != null) {
Rectangle rect = rectPool.obtain();
rect.set(x, y, 1, 1);
tiles.add(rect);
}
}
}
}
I've also tried putting just the integer in as well, same result, only one that works is 0. My .tmx map in Tiled has two layers, "layer1" and "layer2". The map displays fine, so I know I've loaded the .tmx correctly (used the TmxLoader to create a TiledMap called "map"). Not sure what's going on.

Converting an Ellipse2D to Polygon

I have a Java swing application where I can draw hot spots. I am allowing user to draw Rectangle , Polygon and Circle.
For Circle I am using Ellipse2D
Ellipse2D.Double ellipseDouble = new Ellipse2D.Double(x,y,width,height);
g.draw(ellipseDouble);
Above works fine and it does draw an ellipse/circle.
Now the problems when I want the region to be used in HTML Image map.
Html Image map doesn't support Ellipse so I was thinking to use polygon for Ellipse2D but really don't know how would I convert it.
Does anyone know how would I go about it converting an Ellipse2D to Polygon ponits?
Use FlatteningPathIterator.
See e.g. http://java-sl.com/tip_flatteningpathiterator_moving_shape.html where point moves following custom Shape.
You can get list of Points and create Polygon.
Maybe someone will find this one useful: this is pdfbox ellipse or circle (width=height) draw function inside rectangle, it make ellipse as polygon initially to draw.
Code based on math function of ellipse at poin [0 , 0]: x^2/a^2 + y^2/b^2 = 1
private PdfBoxPoligon draw_Ellipse_or_Circle_as_poligon_with_PDFBOX (
PDPageContentStream content, float bottomLeftX, float bottomLeftY,
float width, float height, boolean draw) throws IOException {
PdfBoxPoligon result = new PdfBoxPoligon();
float a = width/2;
float b = height/2;
int points = (int) (a*b/20);
if (DEBUG) {
System.out.println("points=" + points);
}
//top arc
for (float x = -a; x < a; x = x + a / points) {
result.x.add(bottomLeftX + a + x);
float y = (float) Math.sqrt((1-(x*x)/(a*a))*(b*b));
result.y.add(bottomLeftY+b+y);
}
//bottom arc
for (float x = a; x >= -a; x = x - a / points) {
result.x.add(bottomLeftX + a + x);
float y = -(float) Math.sqrt((1-(x*x)/(a*a))*(b*b));
result.y.add(bottomLeftY+b+y);
}
result.x.add(result.x.get(0));
result.y.add(result.y.get(0));
if (draw) {
for (int i=1; i < result.x.size(); i++) {
content.addLine(result.x.get(i-1), result.y.get(i-1), result.x.get(i), result.y.get(i));
}
}
return result;
}

Categories