My current code shows a circle that goes around the window once in a clockwise rotation, and then moves off the screen in the upper right corner when it's making its way around a second time. How can I edit my code, so the circle continues to go around the screen endlessly and never moves off the edge?
// cirlce radius
final int radius = 25;
// circle x position
int xPos = 15;
int yPos = 15;
int xDir = 4;
int yDir = 0;
void setup()
{
size(500, 500);
background(177, 237, 247);
}
void draw()
{
background(177, 237, 247);
ellipse(xPos, yPos, radius, radius);
xPos = xPos + xDir;
yPos = yPos + yDir;
if (xPos > width - 15) {
yDir = 4;
xDir = 0;
} if (yPos > height - 15) {
xDir = -4;
yDir = 0;
} if (xPos < width - 485) {
xDir = 0;
yDir = -4;
} if (yPos < height - 485) {
yDir = 0;
xDir = 4;
}
}
The 3rd and 4th argument of ellipse are the length of the axis, instead of the length of the semi axis. Therefore you need to multiple the radius by 2.
When the ellipse reaches an edge, you need to limit the position of the ellipse by the edge:
// cirlce radius
final int radius = 25;
// circle x position
int xPos = radius;
int yPos = radius;
int xDir = 4;
int yDir = 0;
void setup() {
size(500, 500);
background(177, 237, 247);
}
void draw()
{
background(177, 237, 247);
ellipse(xPos, yPos, radius*2, radius*2);
xPos = xPos + xDir;
yPos = yPos + yDir;
if (xPos > width - radius) {
xPos = width - radius;
yDir = 4;
xDir = 0;
}
if (yPos > height - radius) {
yPos = height - radius;
xDir = -4;
yDir = 0;
}
if (xPos < radius) {
xPos = radius;
xDir = 0;
yDir = -4;
}
if (yPos < radius) {
yPos = radius;
yDir = 0;
xDir = 4;
}
}
Related
I was working on a brick breaker game in proccessing, and was trying to create the collision system for the game. I was able to identify when a collision happens between the ball and the brick, but I was not able to to make the brick dissapear when it gets hit by the ball. How do I do this? I would also appreciate a explanation, as I am a beginner.
Thanks.
color black = color(0,0,0);
color red = color(255,0,0);
color white = color(255,255,255);
float ballx = 412.5, bally = 600, balld = 20, ballr = balld/2, paddleX = 362.5, paddleY = 650;
float paddleW = 100, paddleH = 15;
float ballspdX, ballspdY;
boolean ball_drop = true;
float direction_choice;
float[] brickX = new float[10];
float[] brickY = new float[5];
float brickW = 50, brickH = 25;
void setup(){
size(825,800);
surface.setTitle("Brick breaker");
noCursor();
smooth();
brickX[0] = 50;
brickX[1] = 125;
brickX[2] = 200;
brickX[3] = 275;
brickX[4] = 350;
brickX[5] = 425;
brickX[6] = 500;
brickX[7] = 575;
brickX[8] = 650;
brickX[9] = 725;
brickY[0] = 50;
brickY[1] = 125;
brickY[2] = 200;
brickY[3] = 275;
brickY[4] = 350;
}
void paddle(){
noStroke();
fill(white);
rect(paddleX, paddleY, paddleW, paddleH);
}
void ball(){
noStroke();
fill(red);
circle(ballx, bally, balld);
}
void draw(){
background(black);
paddle();
ball();
if (bally + ballr == paddleY && ballx > paddleX && ballx < paddleX + (paddleW / 2)){
ball_drop = false;
ballspdY = -ballspdY;
ballspdX = -4;
}
/*
if (bally + ballr == paddleY && ballx > paddleX && ballx < paddleX + paddleW){
ball_drop = false;
ballspdY = -ballspdY;
direction_choice = int(random(1,3));
if (direction_choice == 1){
ballspdX = 4;
}
if (direction_choice == 2){
ballspdX = -4;
}
}
println(direction_choice);
*/
if (bally + ballr == paddleY && ballx > paddleX + (paddleW /2) && ballx < paddleX + paddleW){
ball_drop = false;
ballspdY = -ballspdY;
ballspdX = 4;
}
if (ballx + ballr > width || ballx - ballr < 0){
ballspdX = -ballspdX;
}
if (bally - ballr < 0){
ballspdY = -ballspdY;
}
if (ball_drop){
ballspdX = 0;
ballspdY = 1;
}
for (int i = 0; i < brickX.length; i ++){
for(int j = 0; j < brickY.length; j ++){
fill(red);
rect(brickX[i], brickY[j], brickW, brickH);
if (collideLineCircle(brickX[i], brickY[j] + brickH, brickX[i] + brickW, brickY[j] + brickH, ballx, bally, ballr)){
ballspdY = -ballspdY;
}
}
}
if (bally >= 800){
bally = 600;
ballx = 412.5;
ball_drop = true;
}
bally += ballspdY;
ballx += ballspdX;
}
boolean collideLineCircle(float x1, float y1, float x2, float y2, float cx, float cy, float cr){
float A = y2 - y1, B = x1 - x2, C = x2*y1 - x1+y2;
float denom = A+A + B*B;
if (denom == 0){
return dist(x1,y1, cx, cy) < cr;
}
float Ix = (B*B*cx-A*B*cy - A*C)/denom, Iy = (A*A*cy-A*B*cx - B*C)/denom;
if (Ix >= min(x1,x2) && Ix <= max(x1,x2) & Iy >= min(y1,y2) && Iy <= max(y1,y2)) {
return abs (A*cx + B*cy + C)/sqrt(denom) < cr;
}
float d1 = dist(x1,y1,cx,cy), d2 = dist(x2,y2,cx,cy);
return min(d1,d2) < cr;
}
void mouseMoved(MouseEvent evt){
paddleX = evt.getX();
}
There are a number of ways this can be done. Perhaps the simplest change, given the data structures you already have is to create another array, this time a boolean array, and call it something like brickIsVisible.
Then you can use a simple if statement, e.g., if (brickIsVisible[i]) in your loops to determine how to color the brick. The same variable can be used to tell whether or not to do a collision test between the ball and the brick.
As for the coloring itself, there are a couple options.
I'm not sure how you are drawing your board. If you redraw the entire board with each gameloop frame, then presumably you first draw the background (which covers over the bricks) and then you draw the bricks. If this what is happening, then if brickIsVisible[i] is false you can simply omit drawing that brick on top of the background.
Another technique that is sometimes used is to make use of a transparent color. This is done by adding an alpha channel value to the color definition. Thus there are four variables instead of three. They are referred to as RGBA instead of RGB. If the fourth variable is 0, the color will be transparent. If it is 255 it will be fully visible. Intermediate values in sequence can be used if you want to create a fade in or fade out.
I am guessing you are using java.awt.Color. Following is an example that uses the four argument constructor, with the fourth being the alpha channel.
Color invisiblePurple = new Color(255, 0, 255, 0);
If the color is invisible, the RGB values don't really matter.
These days I mostly use JavaFX for graphics, so I might not be up on all the tricks of the trade with AWT/Swing. With JavaFX, one can directly set an opacity property for a graphic being displayed, which is pretty convenient. I think part of the reason that this is available in JavaFX is that screen graphics are structured more like a DOM tree (like an HTML domain object model), and the redrawing is handled behind the scenes on the current state of the tree, rather than explicitly for each object, as it is with AWT/Swing.
Another possible technique shown below uses a brick class array. The class has a 'show' boolean associated with it and the bricks are only displayed when brick[id].show is true. In this demo when the brick is selected with a mouse brick[id].show is set to false and that brick is not displayed. For your project you would have to do this when a brick is hit by the ball.
/*
Creates a grid of rectangles from a Brick class array.
Syntax: brick[id] = new Brick( x, y, w, h, "title", bkgrndColor, txtColor);
ID is taken from position in array.
*/
final int _brickGridX = 40;
final int _brickGridY = 60;
final int _brickW = 120;
final int _brickH = 60;
color BLUE = color(64, 124, 188);
color LTGRAY = color(185, 180, 180);
color YELLOW = color(245, 250, 13);
color RED = color(255, 0, 0);
color BLACK = color(0, 0, 0);
color WHITE = color(255, 255, 255);
Brick[] brick;
class Brick {
float x, y, w, h;
String title;
color bkgrnd;
color txtColor;
boolean show;
// Constructor
Brick(int xpos, int ypos, float wt, float ht, String titleStr, color background, color foreground) {
x = xpos;
y = ypos;
w = wt;
h = ht;
title = titleStr;
bkgrnd = background;
txtColor = foreground;
}
void display(int id) {
if (brick[id].show) {
fill(bkgrnd); // background color
stroke(0);
rect(x, y, w, h);
fill(txtColor); // text color
textSize(42);
textAlign(CENTER, CENTER);
text(title, x, y, w, h);
}
}
void press(int id) {
println("brick id = ", id + ": show =", brick[id].show);
}
}
void brickGrid() {
int left = 0;
int top = 0;
int vg = 0; // Space between cols (vert.gutter)
int hg = 0; // Space between rows (horz.gutter)
int rows = 5;
int cols = 5;
int id = 0;
brick = new Brick[rows*cols]; // creates brick array
for (int k = 0; k < cols; k++) {
for (int j = 0; j < rows; j++) {
left = _brickGridX + j * (_brickW + vg);
top = _brickGridY + k * (_brickH + hg);
brick[id] = new Brick(left, top, _brickW, _brickH, str(id), LTGRAY, BLACK);
brick[id].show = true;
id++;
}
}
}
void setup() {
size(800, 600);
background(BLUE);
brickGrid();
}
void draw() {
background(BLUE);
for (int i = 0; i < brick.length; i++) {
brick[i].display(i);
}
}
void mousePressed() {
for (int i = 0; i < brick.length; i++) {
if ((mouseX >= brick[i].x) && (mouseX <= brick[i].x + _brickW) && (mouseY >= brick[i].y) && (mouseY <= brick[i].y + _brickH)) {
brick[i].show = false;
// brick[i].press(i);
}
}
}
I am trying to add a square to the canvas when a mouse key is pressed and i want it to remain on the canvas when the mouse key is released, but it disappears when is released the key. Can anybody help me, what am i doing wrong?
int squareSize = 6;
final float DIFF_SIZE = 1;
final int MIN_COLOUR = 1;
final int MAX_COLOUR = 10;
final float INIT_RED = 100, INIT_GREEN = 50, INIT_BLUE = 80;
final float FINAL_RED = 255, FINAL_GREEN = 200, FINAL_BLUE = 250;
final float MAX_SIZE = 40;
final float X_SPACING = 10;
final float Y_SPACING = 10;
float squareX, squareY;
void setup() {
size(600, 600);
}
void draw() {
squareX = mouseX - squareSize / 2;
squareY = mouseY - squareSize / 2;
background(255);
drawRowsOfBlocks();
}
void drawOneBlock() {
rect(squareX, squareY, squareSize, squareSize);
for (int i = MIN_COLOUR; mousePressed && i <= MAX_COLOUR / 10; i++)
{
float redValue = INIT_RED + (i - MIN_COLOUR) / (MAX_COLOUR - MIN_COLOUR)(FINAL_RED - INIT_RED);
float greenValue = INIT_GREEN + (i - MIN_COLOUR) / (MAX_COLOUR - MIN_COLOUR)(FINAL_GREEN - INIT_GREEN);
float blueValue = INIT_BLUE + (i - MIN_COLOUR) / (MAX_COLOUR - MIN_COLOUR) * (FINAL_BLUE - INIT_BLUE);
fill(redValue, greenValue, blueValue);
rect(squareX, squareY, squareSize, squareSize);
squareSize += DIFF_SIZE;
}
if (squareSize > MAX_SIZE) {
squareSize = 6;
}
}
void drawRowsOfBlocks() {
drawOneBlock();
for (int i = 1; keyPressed && i <= 2; i++) {
drawOneBlock();
float squareY2;
squareY2 = squareY + squareSize + Y_SPACING;
squareY = squareY2;
}
}
Create a class which can handle a rectangle. The calls needs a method to draw the rectangle (Draw()) and a method to update the position and size of the rectangle (Update()):
final int DIFF_SIZE = 1;
final int MIN_SIZE = 6;
final int MAX_SIZE = 40;
final float INIT_RED = 100, INIT_GREEN = 50, INIT_BLUE = 80;
final float FINAL_RED = 255, FINAL_GREEN = 200, FINAL_BLUE = 250;
class Rectangle {
int pos_x, pos_y, size;
color col;
Rectangle(int px, int py, int s, color c) {
col = c;
pos_x = px; pos_y = py;
size = s;
}
void Update(int px, int py, int inc_size) {
pos_x = px; pos_y = py;
size += inc_size;
if (size > MAX_SIZE)
size = MIN_SIZE;
float w = float(size - MIN_SIZE) / float(MAX_SIZE - MIN_SIZE);
float redValue = INIT_RED + w * (FINAL_RED - INIT_RED);
float greenValue = INIT_GREEN + w * (FINAL_GREEN - INIT_GREEN);
float blueValue = INIT_BLUE + w * (FINAL_BLUE - INIT_BLUE);
col = color(int(redValue), int(greenValue), int(blueValue));
}
void Draw() {
fill(col);
rect(pos_x-size/2, pos_y-size/2, size, size);
}
}
Use ArrayList to store all the drawn rectangles:
ArrayList<Rectangle> rectangles = new ArrayList<Rectangle>();
Add a global, boolean state (drawingRect) which indicates if the mouse button is currently pressed. Set the state and add new rectangle at the end of the list when the mousePressed() event occurs. rest the state when the mouseReleased() event occurs
boolean drawingRect = false;
void mousePressed() {
drawingRect = true;
color col = color(int(INIT_RED), int(INIT_GREEN), int(INIT_BLUE));
rectangles.add(new Rectangle(mouseX, mouseY, MIN_SIZE, col));
}
void mouseReleased() {
drawingRect = false;
}
Use the method .Update(), to change the location and size of the last rectangle in the list as long as the state drawingRect indicates that a mouse button is pressed.
Continuously draw all te rectangles in a loop:
void setup() {
size(600, 600);
}
void draw() {
if (drawingRect && rectangles.size() > 0) {
Rectangle lastRect = rectangles.get(rectangles.size()-1);
lastRect.Update(mouseX, mouseY, DIFF_SIZE);
}
background(255);
for (int i = 0; i < rectangles.size(); i++) {
Rectangle rect = rectangles.get(i);
rect.Draw();
}
}
I want to create a drawLine function, however I am not able to use any graphics classes (I can set pixels though). I tried this method https://en.wikipedia.org/wiki/Bresenham's_line_algorithm#Method, but this only works when the line is going from top left to bottom right and not for example going from top right to bottom left. Does anyone have a way that does this? The current code I have:
public void drawLine(int startX, int startY, int endX, int endY) {
double deltaX = endX - startX;
double deltaY = endY - startY;
double error = -1;
double deltaError = Math.abs(deltaY / deltaX);
int y = startY;
for (int x = startX; x < endX - 1; x++) {
error += deltaError;
if (error >= 0) {
y++;
error--;
}
drawPixel(x, y);
}
}
Any help is appreciated.
I solved it. The end result is this.
public void drawLine(int startX, int startY, int endX, int endY) {
if (startX > endX && startY > endY) {
int startXCopy = startX;
startX = endX;
endX = startXCopy;
int startYCopy = startY;
startY = endY;
endY = startYCopy;
}
double deltaX = endX - startX;
double deltaY = endY - startY;
double error = -1;
double deltaError = Math.abs(deltaY / deltaX);
if (deltaX == 0) {
for (int y = startY; y < endY; y++)
drawPixel(startX, y);
}
if (deltaY == 0) {
for (int x = startX; x < endX; x++)
drawPixel(x, startY);
}
if (deltaX >= deltaY) {
int y = startY;
int yDirection = endY > startY ? 1 : -1;
for (int x = startX; x < endX - 1; x++) {
error += deltaError;
if (error >= 0) {
y += yDirection;
error--;
}
drawPixel(x, y);
}
} else if (deltaY > deltaX) {
int x = startX;
int xDirection = endX > startX ? 1 : -1;
for (int y = startY; y < endY - 1; y++) {
error += deltaError;
if (error >= 0) {
x += xDirection;
error--;
}
drawPixel(x, y);
}
}
}
To draw a line is a simple Math problem and can be achieved on different ways.
What you need is the basic linear euqation y = f(x) = mx + b
where m is your slope, defined as m=(y2−y1)/(x2−x1), bis your startY value and the x is expressed by x = x_i - startX where x_i is your current point on your line. Then you can compute all y-values for each x_i value on the line between your start point and your end point. The quantity of points depends on a resolution factor.
double slope = (double)(endY - startY) / (endX - startX);
//adjustable resolution factor
double resolution = 1;
double x = startX;
while (x <= endX) {
double y = slope * (x - startX) + startY;
drawPixel(x, y);
x += resolution;
}
I am trying to make a processing program, but if I use P2D, P3D, or OPENGL mode I get an error:
com.sun.jdi.VMDisconnectedException
at com.sun.tools.jdi.TargetVM.waitForReply(TargetVM.java:285)
at com.sun.tools.jdi.VirtualMachineImpl.waitForTargetReply(VirtualMachineImpl.java:1015)
at com.sun.tools.jdi.PacketStream.waitForReply(PacketStream.java:51)
at com.sun.tools.jdi.JDWP$ObjectReference$InvokeMethod.waitForReply(JDWP.java:4589)
at com.sun.tools.jdi.ObjectReferenceImpl.invokeMethod(ObjectReferenceImpl.java:374)
at processing.mode.java.runner.Runner.findException(Runner.java:701)
at processing.mode.java.runner.Runner.reportException(Runner.java:652)
at processing.mode.java.runner.Runner.exception(Runner.java:595)
at processing.mode.java.runner.EventThread.exceptionEvent(EventThread.java:367)
at processing.mode.java.runner.EventThread.handleEvent(EventThread.java:255)
at processing.mode.java.runner.EventThread.run(EventThread.java:89)
the error message itself varies between P2D and P3D, but they both get a no framebuffer objects available error. I am using processing 2.0b7, please help and let me know if you need more info.
Note: I don't know if this is a separate issue or not, but I am also getting GLSL shader errors to.
Now, here is my code:
Cell[][] Cells = new Cell[50][50];
byte Direction = 1;
byte Times = 1;
int oldwidth = 500;
int oldheight = 500;
void setup() {
size(oldwidth, oldheight, OPENGL);
background(255);
colorMode(HSB,250);
for (int x = 0; x < 50; x++) {
for (int y = 0; y < 50; y++) {
Cells[x][y] = new Cell(x * 5, y * 5, 255, x * (width / 50), y * (height / 50), width / 50, height / 50);
}
}
}
void draw() {
for (int x = 0; x < 50; x++) {
for (int y = 0; y < 50; y++) {
if (width == oldwidth) Cells[x][y].Width = width / 50;
if (height == oldheight) Cells[x][y].Height = height / 50;
if (Direction == 1){
Cells[x][y].Hue += 5;
if (Cells[x][y].Hue > 250) Cells[x][y].Hue -= 250;
}
if (Direction == 2){
Cells[x][y].Saturation -= 5;
if (Cells[x][y].Saturation < 0) Cells[x][y].Saturation += 500;
}
if (Direction == 3){
Cells[x][y].Hue -= 5;
if (Cells[x][y].Hue < 0) Cells[x][y].Hue += 250;
}
if (Direction == 4){
Cells[x][y].Saturation += 5;
if (Cells[x][y].Saturation > 500) Cells[x][y].Saturation -= 500;
}
Cells[x][y].Draw();
}
}
if (Times == 50){
Times = 1;
if (Direction == 4) Direction = 1; else Direction += 1;
} else Times += 1;
delay(10);
}
class Cell {
int X;
int Y;
int Width;
int Height;
float Hue;
float Saturation;
float Brightness;
Cell(color parC, int parX, int parY, int parWidth, int parHeight) {
Hue = hue(parC);
Saturation = saturation(parC);
Brightness = brightness(parC);
X = parX;
Y = parY;
Width = parWidth;
Height = parHeight;
}
Cell(float parHue, float parSaturation, float parBrightness, int parX, int parY, int parWidth, int parHeight) {
Hue = parHue;
Saturation = parSaturation;
Brightness = parBrightness;
X = parX;
Y = parY;
Width = parWidth;
Height = parHeight;
}
void Draw() {
if (Saturation > 250) if (Saturation > 500) stroke(color(Hue,0,Brightness)); else stroke(color(Hue,Saturation - (Saturation - 250) * 2,Brightness)); else stroke(color(Hue,Saturation,Brightness));
if (Saturation > 250) if (Saturation > 500) fill(color(Hue,0,Brightness)); else fill(color(Hue,Saturation - (Saturation - 250) * 2,Brightness)); else fill(color(Hue,Saturation,Brightness));
rect(X, Y, Width, Height);
}
}
I just realized that it is just that my graphics card does not support OPENGL 2.0
Here is a program that has a ball drop and bounce from wherever the mouse is clicked. Would anyone know how to change the rate that the ball drops to the force of gravity?
Im trying to figure out the proper solution to this... but i am having a little trouble. All help and or input would be much appreciated.
float x;
float y;
float yspeed = 0;
float xspeed = 0;
float balldiameter = 10;
float ballradius = balldiameter/2;
void setup() {
size (400,400);
background (255);
fill (0);
ellipseMode(CENTER);
smooth();
noStroke();
x = width/2;
y = height/2;
}
void draw() {
mouseChecks();
boundaryChecks();
ballFunctions();
keyFunctions();
}
void mouseChecks() {
if (mousePressed == true) {
x = mouseX;
y = mouseY;
yspeed = mouseY - pmouseY;
xspeed = mouseX - pmouseX;
}
}
void boundaryChecks() {
if (y >= height - ballradius) {
y = height - ballradius;
yspeed = -yspeed/1.15;
}
if (y <= ballradius) {
y = ballradius;
yspeed = -yspeed/1.35;
}
if (x >= width -ballradius) {
x = width -ballradius;
xspeed = -xspeed/1.10;
}
if (x <= ballradius) {
x = ballradius;
xspeed = -xspeed/1.10;
}
}
void ballFunctions() {
if (balldiameter < 2) {
balldiameter = 2;
}
if (balldiameter > 400) {
balldiameter = 400;
}
ballradius = balldiameter/2;
background(255); //should this be in here?
ellipse (x,y,balldiameter,balldiameter);
yspeed = yspeed += 0.2;
xspeed = xspeed/1.005;
y = y + yspeed;
x = x + xspeed;
}
void keyFunctions() {
if (keyPressed) {
if(keyCode == UP) {
balldiameter +=1;
}
if (keyCode == DOWN) {
balldiameter -=1;
}
}
}
The acceleration of gravity on earth is 9.81 m/s^2. So, if your ball's velocity is 0 at the point the mouse is clicked, the final velocity will be the acceleration integrated in relation to time. This would be (9.81 * t) / 2. Where t is in seconds. The resulting units would be m/sec. You would have to convert meters to some screen space unit for drawing.