How to make a gradient ring in java for android? - java

I am trying to draw out a ring with a nice gradient effect in java for an android application. I am trying to use the RadialGradient class found in android.graphics.RadialGradient, but it doesn't really do a gradient effect. I feel like it is just sort of mixing the 2 colors I subbed in for the color parameter, but I would like it to start from the first color I gave it and slowly transition itself to the second color in whatever direction it wants. The below is the code snippet for what I have tried.
paint.setColor(color);
paint.setAntiAlias(true);
int[] colors = {Color.argb(255, 255, 255, 0), Color.argb(255, 219, 219, 7)};
Shader test = new RadialGradient(X, Y, radius, colors, null, Shader.TileMode.CLAMP);
paint.setShader(test);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(thickness);
Don't worry about the variables that I used that aren't shown how it was initialized. That part is not important.

Related

JAVA - swing - draw/fill with invert/negated colors of destination canvas

I cannot find any info on how to draw shapes on a graphic canvas, making sure what I draw is not the same color as the background
there are some solutions out there but they all use images drawing only with per pixel operations/loops or filters; I also tried different Composite operations, but none suit what I want
so lets say I do
g.setColor(color.white) // relevant in this case ? not sure
g.fillRect(...)
I want the rectangle to be in inverted colors of the background so it is always visible
sorry I cant provide more code, I really dont know how to achieve this
thanks
Your paint method could retrieve the current color, and search for its complementary color:
Color originalColor = g.getColor();
g.setColor(complementaryColor(originalColor));
g.fillRect(0, 0, 50, 50);
The complementaryColor method is inspired from this topic : Reverse opposing colors
Color complementaryColor(final Color bgColor) {
Color complement = new Color(255 - bgColor.getRed(),
255 - bgColor.getGreen(),
255 - bgColor.getBlue());
return complement;
}

Drawing subset of a gradient in libgdx

I know this question has been accessed before (like here), but I was wondering how to do the following. In my game, I have a scrolling background. There is for example a blue sky that is light blue at the bottom and gets darker the higher you go. This is not really possible with the suggested solution:
shapeRenderer.filledRect(x, y, width, height,
lightBlue, lightBlue, darkBlue, darkBlue);
since you can only give the colors that really will be shown. I would like to have a gradientPaint with at the top darkblue and the bottom lightblue that stretches out over for example 500 pixels. This, while I only draw only 200 pixels of it. With this, the color would still get darker when the background scrolls. Does anybody know how to do this with libgdx?
What you want is to see a smaller (say 200 pixel) window onto a larger (say 500 pixel) gradient. To do that you just need to compute the colors of four corners colors based on the location of your window in the overall gradient, and then draw just that. (So don't think about drawing the entire background, but about figuring out how to draw just the part that you need.)
Since you're just moving smoothly between the two colors (between 0 and 500), you're doing a "linear interpolation" (that is a straight-line estimation) between the colors based on where the Window is. Libgdx supports this via the lerp() methods on Color.
Assuming the window is travelling along the Y axis, something like this should give what you want:
Color baseColor = lightBlue;
Color topColor = darkBlue;
int skyHeight = 500;
int windowHeight = 200;
int windowLocation = ...; // something betweeen 0 and skyHeight - windowHeight;
Color windowBottomColor = baseColor.copy().lerp(topColor, windowLocation / skyHeight);
Color windowTopColor = baseColor.copy().lerp(topColor, (windowLocation + windowHeight) / skyHeight);
Now windowBottomColor and windowTopColor should be suitable for calling filledRect:
shapeRenderer.filledRect(x, y, width, height,
windowBottomColor, windowBottomColor, windowTopColor, windowTopColor);
Note that the "copy()" calls create a new Color object for each invocation, so you might want to optimize that to avoid the allocation.
Disclaimer: I haven't tried this code, so it probably has some stupid bugs in it, but hopefully it gives you the right idea.

How to apply gradient background in andengine

I've been looking around for awhile now, and can't seem to find out how to set a scene's background as a gradient... it's hard to find solid Andengine-related answers,
I guess my options are:
using a sprite from a gradient image I've created myself (which can't be the best way)
using a gradient xml resource (but I don't know how to create a sprite from a resId, and I'm confused on how to make the gradient fit the camera)
or some other andengine built-in method
Any help is appreciated.
The following code inside your activity class (onCreateScene or onPopulateScene) should set a red/blue gradient as your background.
Gradient g = new Gradient(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT, this.getVertexBufferObjectManager());
g.setGradient(Color.RED, Color.BLUE, 1, 0);
this.setBackground(new EntityBackground(g));

Blending problems using opengl (via lwjgl) when using a png texture

I have a (hopefully) small problem when using blending in OpenGL.
Currently I use LWJGL and Slick-Util to load the Texture.
The texture itself is a 2048x2048 png graphic, in which I store tiles of a size of 128x128 so that I have 16 sprites per row/column.
Since glTexCoord2f() uses normalized Coordinates, I wrote a little function to scale the whole image to only show the sprite I want to.
It looks like this:
private Rectangle4d getTexCoord(int x, int y) {
double row = 0, col = 0;
if(x > 0)
row = x/16d;
if(y > 0)
col = y/16d;
return new Rectangle4d(row, col, 1d/16d, 1d/16d);
}
(Rectangle4d is just a type to store x, y, width and height as double coords)
Now the problem is, once I use these coords, the sprite displays correctly, the transparency works correctly too, just everything else becomes significantly darker (well more correctly it becomes transparent I guess, but since the ClearColor is black). The sprite itself however is drawn correctly. I already tried changing all the glColor3d(..) to glColor4d(..) and setting alpha to 1d, but that didn't change anything. The sprite is currently the only image, everything else are just colored quads.
Here is how I initialised OpenGL:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
And here is how I load the sprite (using slick-util):
texture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/sprites.png"));
And finally I render it like this (using the helper function getTexCoord() mentioned at the top):
texture.bind();
glColor4d(1, 1, 1, 1);
glBegin(GL_QUADS);
{
Rectangle4d texCoord = getTexCoord(0, 0);
glTexCoord2f((float)texCoord.getX(), (float)texCoord.getY());
glVertex2i((Game.WIDTH-PLAYERSIZE)/2, (Game.HEIGHT-PLAYERSIZE)/2);
glTexCoord2f((float)texCoord.getX()+(float)texCoord.getWidth(), (float)texCoord.getY());
glVertex2i((Game.WIDTH+PLAYERSIZE)/2, (Game.HEIGHT-PLAYERSIZE)/2);
glTexCoord2f((float)texCoord.getX()+(float)texCoord.getWidth(), (float)texCoord.getY()+(float)texCoord.getHeight());
glVertex2i((Game.WIDTH+PLAYERSIZE)/2, (Game.HEIGHT+PLAYERSIZE)/2);
glTexCoord2f((float)texCoord.getX(), (float)texCoord.getY()+(float)texCoord.getHeight());
glVertex2i((Game.WIDTH-PLAYERSIZE)/2, (Game.HEIGHT+PLAYERSIZE)/2);
}
glEnd();
The result is this (sprite is drawn correctly, just everything else is darker/transparent):
Without the texture (just a gray quad), it looks like this (now everything is correctly drawn except I don't have a sprite):
Thanks for everyone who bothers to read this at all!
Edit:
Some additional info, from my attempts to find the problem:
This is how it looks when I set the ClearColor to white (using glClearColor(1, 1, 1, 1) ):
Another thing I tried is enabling blending just before I draw the player and disable it again right after I finished drawing:
Its a bit better now, but its still noticeably darker. In this case it really seems to be "darker" not "more transparent" because it is the same when I use white as a clear color (while still only enabling blending when needed and disabling it right after) as seen here:
I read some related questions and eventually found the solution (Link). Apparantly I can't/shouldn't have GL_TEXTURE_2D enabled all the time when I want to render textureless objects (colored quads in this case)!
So now, I enable it only before I render the sprite and then disable it again once the sprite is drawn. It works perfectly now! :)

Curved sides of triangle path?

I am drawing a triangle on a Canvas, something like:
canvas.moveTo(0, 30);
canvas.lineTo(40, 0);
canvas.lineTo(40, 40);
canvas.lineTo(40, 40);
canvas.lineTo(0, 30);
And get proper triangle on my Canvas. But I need to curve the sides a little and fill that path with specific color. What is the easiest way to do this? Drawing arcs? But how to fill the object?
Thanks!
EDIT: I noticed you were using android's canvas, not HTML Canvas, sorry. The concept is exactly the same except you'll call quadTo() instead of quadraticCurveTo(), so my example should still get you going.
Also on android you use canvas.drawPath(path, paint) and pass in a paint that has its Paint.style set to FILL_AND_STROKE.
You will want to construct the path, fill() it, then stroke() it in order to get both a filled path with the stroke outline.
To get that particular shape, the easiest way is to draw two quadratic curves. A quadratic curve first needs a control point x,y then the end point x,y. The control point for both curves should be around the middle of your desired triangle. Here is an example:
ctx.fillStyle = "lightgray";
ctx.moveTo(0, 100);
ctx.quadraticCurveTo(50, 50, 50, 0);
ctx.quadraticCurveTo(50, 50, 100, 100);
ctx.lineTo(0, 100);
ctx.fill();
ctx.stroke();
Here is that example live for you.

Categories