Reputation: 61
I am trying to get my paddles from white to gradient (linear) and the ball to have a radial gradient. Thanks for your help!You can find the code for the paddles in void drawPaddle.
This is my code:
//Ball
int ballX = 500;
int ballY = 350;
int ballHeight = 35;
int ballWidth = 35;
int speedX = 4;
int speedY = 4;
int directionX = 1;
int directionY = 1;
//Paddles
int player1X = 30;
int player2X = 830;
int player1Y = 350;
int player2Y = 350;
//Healthbars
int bar1X = 100;
int bar1Y = 20;
int player1health = 100;
int bar1colour = #22E515;
int bar2X = 700;
int bar2Y = 20;
int player2health = 100;
int bar2colour = #22E515;
//Movements
boolean upX = false;
boolean downX = false;
boolean upY = false;
boolean downY = false;
void setup() {
size(900, 700);
}
void draw() {
background(55, 68, 120);
drawPaddle();
//EmptySpace**
fill(55, 68, 120);
noStroke();
rect(player1X, player1Y, 40, 140);
rect(player2X, player2Y, 40, 140);
//Healthbars
fill(bar1colour);
rect(bar1X, bar1Y, player1health, 15);
fill(bar2colour);
rect(bar2X, bar2Y, player2health, 15);
//Ball
fill(194, 16, 0);
ellipse(ballX, ballY, ballHeight, ballWidth);
moveCircle();
movePaddle();
moveCollisions();
}
void drawPaddle() {
fill(255);
noStroke();
rect(30, 0, 40, 1000);
rect(830, 0, 40, 1000);
}
void moveCircle() {
ballX = ballX + speedX * 1;
ballY = ballY + speedY * 1;
if (ballX > width- ballWidth +20 || ballX < ballWidth) {
speedX *= -1;
}
if (ballY > height- ballHeight +20 || ballY < ballHeight) {
speedY *= -1;
}
}
void movePaddle() {
//key movements
if (upX == true) {
player1Y = player1Y - 5;
}
if (downX == true) {
player1Y = player1Y + 5;
}
if (upY == true) {
player2Y = player2Y - 5;
}
if (downY == true) {
player2Y = player2Y + 5;
}
//Wrap around
if (player1Y > 700) {
player1Y = 0;
} else if (player1Y + 140 < 0) {
player1Y = 700;
}
if (player2Y > 700) {
player2Y = 0;
} else if (player2Y + 140 < 0) {
player2Y = 700;
}
}
void moveCollisions() {
//Collisions
if ((ballX - ballWidth / 2 < player1X + 40) && ((ballY - ballHeight / 2 > player1Y + 140) || (ballY + ballHeight / 2 < player1Y))) {
if (speedX < 0) {
player1health -= 20;
speedX = -speedX*1;
if (player1health == 20) {
bar1colour = #F51911;
}
}
} else if ((ballX + ballWidth / 2 > player2X) && ((ballY - ballHeight / 2 > player2Y + 140) || (ballY + ballHeight/2 < player2Y))) {
if (speedX > 0) {
player2health -= 20;
bar2X += 20;
speedX = -speedX*1;
if (player2health == 20) {
bar2colour = #F51911;
}
}
}
}
void keyPressed() {
if (key == 'w' || key == 'W') {
upX = true;
} else if (key == 's' || key == 'S') {
downX = true;
} else if (keyCode == UP) {
upY = true;
} else if (keyCode == DOWN) {
downY = true;
}
}
void keyReleased() {
if (key == 'w' || key == 'W') {
upX = false;
} else if (key == 's' || key == 'S') {
downX = false;
} else if (keyCode == UP) {
upY = false;
} else if (keyCode == DOWN) {
downY = false;
}
}
Upvotes: 5
Views: 3709
Reputation: 51857
Nice question and great mycycle and void main's answers are great already. The PeasyGradients library looks great!
I would like to contribute a minor workaround: using the P2D
renderer to handle the gradient via shapes:
size(100,100,P2D);// render via OpenGL
noStroke();
// draw the rect by manually setting vertices
beginShape();
// gradient start
fill(#fef1a6);
vertex(0 , 0); // TL
vertex(100, 0); // TR
// gradient end
fill(#e28ab9);
vertex(100,100); // BR
vertex( 0,100); // BL
endShape();
For more complex shapes this could be used be used in conjuction with mask(). Not only PImage
can be masked, but also PGraphics
, since they inherit from PImage
:
PGraphics gradient;
PGraphics mask;
void setup() {
size(640, 360, P2D);
gradient = getGradientRect(width, height, #fef1a6, #e28ab9);
mask = getMaskRect(width, height);
}
void draw() {
background(#483b6c);
drawPongShapes();
// apply pong shapes mask to gradient
gradient.mask(mask);
// render masked gradient
image(gradient, 0, 0);
}
// draw white shapes (masks) on black background
void drawPongShapes(){
mask.beginDraw();
mask.background(0);
mask.ellipse(width * 0.5, height * 0.5, 60, 60);
mask.rect(width * .25, mouseY, 30, 150);
mask.rect(width * .75, height-mouseY, 30, 150);
mask.endDraw();
}
PGraphics getMaskRect(int w, int h) {
PGraphics layer = createGraphics(w, h, P2D);
layer.beginDraw();
layer.background(0);
layer.noStroke();
layer.fill(255);
layer.ellipseMode(CENTER);
layer.rectMode(CENTER);
layer.endDraw();
return layer;
}
PGraphics getGradientRect(int w, int h, color grad1, color grad2) {
PGraphics layer = createGraphics(w, h, P2D);
layer.beginDraw();
layer.noStroke();
// draw rect as shape quad
layer.beginShape();
// gradient start
layer.fill(grad1);
layer.vertex(0, 0); // TL
layer.vertex(w, 0); // TR
// gradient end
layer.fill(grad2);
layer.vertex(w, h); // BR
layer.vertex(0, h); // BL
layer.endShape();
layer.endDraw();
return layer;
}
Upvotes: 1
Reputation: 3820
I wrote a library just for this kind of purpose (drawing colour gradients in Processing) called PeasyGradients — download the .jar from the Github releases and drag-and-drop it onto your sketch. It renders 1D gradients as 2D spectrums into your sketch or a given PGraphics
object.
Here's an example of drawing linear and radial spectrums using your desired gradient:
PeasyGradients renderer;
PGraphics rectangle, circle, circleMask;
final Gradient pinkToYellow = new Gradient(color(227, 140, 185), color(255, 241, 166));
void setup() {
size(800, 800);
renderer = new PeasyGradients(this);
rectangle = createGraphics(100, 400);
renderer.setRenderTarget(rectangle); // render into rectangle PGraphics
renderer.linearGradient(pinkToYellow, PI/2); // gradient, angle
circle = createGraphics(400, 400);
renderer.setRenderTarget(circle); // render into circle PGraphics
renderer.radialGradient(pinkToYellow, new PVector(200, 200), 0.5); // gradient, midpoint, zoom
// circle is currently a square image of a radial gradient, so needs masking to be circular
circleMask = createGraphics(400, 400);
circleMask.beginDraw();
circleMask.fill(255); // keep white pixels
circleMask.circle(200, 200, 400);
circleMask.endDraw();
circle.mask(circleMask);
}
void draw() {
background(255);
image(rectangle, 50, 50);
image(circle, 250, 250);
}
Upvotes: 2
Reputation: 125
What you can try is make a PGraphics object for each rectangle you are drawing, fill it with gradient color using linear interpolation and then instead of using rect(x1, y1, x2, y2)
, in drawPaddle()
use image(pgraphic, x, y)
.
Here is how you can create a gradient effect using lerpColor()
in processing:
(x1, y1)
and end point say (x2, y2)
of the gradient.c1
and c2
.(x, y)
, calculate the distance between start point and P and divide it by the distance between the start point and and end point. This will be the 'amount' to lerp from start color and end color.
float t = dist(x1, y1, x, y) / dist(x1, x2, y1, y2)
lerpColor()
as lerpColor(c1, c2, value)
. This will give you the color for point P.Here's an example:
Note: here, i am taking t
which is the amount to be lerped as the distance between the starting point of gradient divided by the distance between the start and end point of gradient, as it will always be a value in between 0 and 1.
PGraphics g = createGraphics(50, 200); // set these values to the size(width, height) of paddle you want
color startColor = color(255, 25, 25); // color of start of the gradient
color endColor = color(25, 25, 255); // color of end of the gradient
g.beginDraw(); //start drawing in this as you would draw in the screen
g.loadPixels();//load pixels, as we are going to set the color of this, pixel-by-pixel
int x1 = g.width/2;
int y1 = 0;
int x2 = g.width/2;
int y2 = g.height;
// (x1, y1) is the start point of gradient
// (x2, y2) is the end point of gradient
// loop through all the pixels
for (int x=0; x<g.width; x++) {
for (int y=0; y<g.height; y++) {
//amout to lerp, the closer this is to (x2, y2) it will get closer to endColor
float t = dist(x1, y1, x, y) / dist(x1, y1, x2, y2);
// you need to convert 2D indices to 1D, as pixels[] is an 1D array
int index = x + y * g.width;
g.pixels[index] = lerpColor(startColor, endColor, t);
}
}
g.updatePixels(); // update the pixels
g.endDraw(); // we are done drawing into this
// Now, you can draw this using image(g, x, y);
Here is the result when i created this in the global scope and then drew it in draw()
using image(g, width/2 ,height/2)
:
Now, you can modify everything to your preference.
Please mark this as answer if it helped you in any way.
Upvotes: 1