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();
}
}
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);
}
}
}
Currently, I'm making a 2d java game that includes a tank at the top of the screen shooting the oncoming cars from below, I have made a crash method and collision detection which determines to stop the game when the tank crashes or enters the radius of the cars. However, sometimes it works early, sometimes late and other times it doesn't. My question is how can I fix it so that when the tank enters the radius of the car it stops the game with simple code that excludes vectors.
Below are my classes and code.
I'm using Java in Processing.
PImage bg; //loads bakground
PFont f; //loads font
Car[] cars = new Car[3];
//Bullet[] bullets = new Bullet[100];
int x = 0;
int y = 0;
int game = 0;
int running = 0;
int over = 1;
int score = 0;
int move = 20;
int cX, cY;
//int carRadius = 20;
Tank tank;
void setup()
{
size(500,1000);
textSize(40);
bg = loadImage("bg.jpeg"); //loads background
bg.resize(width,height); //the background will fill the height and width of the screen size
tank = new Tank(tankX, tankY, 3, 2); //X pos, Y pos, speedY
for (int i=0; i<cars.length; i++)
{
int cX = (int)random(width-100); //car xpos
int cY = (int)random(900); //car ypos
int speedY = 3; //car speedY
cars[i] = new Car(cX, cY, speedY);
}
cars[0] = new Car((int)random(5, width-100), (int)random(5, height), 2); //X pos, Y pos, speedY
cars[1] = new Car((int)random(5, width-100), (int)random(5, height), 2); //X pos, Y pos, speedY
cars[2] = new Car((int)random(5, width-100), (int)random(5, height), 2); //X pos, Y pos, speedY
f = createFont("Arial", 36, true);
}
void draw()
{
if (game == running)
{
drawBackground(); //background
for (Car c : cars) {
c.draw();
c.move();
}
tank.draw(); //tank
drawScore(); //draw score
//if (bullet.crash(cars[0]) == true) {
// cars.remove(c);
// score++;
//}
if (game == over)
{
tank.speedX = 0;
tank.speedY = 0;
move = 0;
gameOver();
}
//if tank crashes into cars
if(tank.crash(cars[0]))
{
game = over;
gameOver();
}
if(tank.crash(cars[1]))
{
game = over;
gameOver();
}
if(tank.crash(cars[2]))
{
game = over;
gameOver();
}
/*
if(bullet.shoot(cars[0]))
{
cars[0].remove(c);
score++;
}
if(bullet.shoot(cars[1]))
{
cars[1].remove(c);
score++;
}
if(bullet.shoot(cars[2]))
{
cars[2].remove(c);
score++;
}
*/
}
}
void keyReleased() {
tankXD = 0;
tankYD = 0;
}
void keyPressed() //controls for the tank using the arrow keys
{
if(keyCode == LEFT) {
tankXD =- 10;
}
if(keyCode == RIGHT) {
tankXD = 10;
}
if(keyCode == DOWN) {
tankYD = 10;
}
if(keyCode == UP) {
tankYD =- 10;
}
if(keyCode == ' ') {
bulletSPD = 30;
//bullets.add(new Bullet(tank.x+30, tank.y+140, 3));
}
}
//void carFill()
// {
// fill(255,0,0);
// }
void drawBackground()
{
image(bg, y, 0);
}
void drawScore() {
fill(255);
textFont(f);
text("Score: " + String.valueOf(score), 200, 50);
}
void gameOver() {
clear();
textFont(f);
text("Game Over! ", 150, 400);
}
class Car
{
//members
int cX, cY;
int speedY = 2;
int speedX = 0;
int animationCounter = 0;
int carRadius = 30;
PImage image1,image2,image3;
//constructor
Car(int cX, int cY, int speedY)
{
this.cX = cX;
this.cY = cY;
this.speedY = speedY;
image1 = loadImage("c1.png");
image2 = loadImage("c2.png");
image3 = loadImage("c3.png");
}
void update() {
draw();
move();
}
void move()
{
this.cY = this.cY - speedY; //move upwards
if(this.cY < 0 - image1.height)
this.cY = height + image1.height;
if(this.cY > height + image1.height +30)
this.cY = -image1.height;
}
void draw()
{
if (animationCounter >=0 & animationCounter <=8)
{ image(image1,this.cX,this.cY); }
else if (animationCounter >8 & animationCounter <=16)
{ image(image2,this.cX,this.cY); }
else
{ image(image3,this.cX,this.cY); }
animationCounter = animationCounter + 1;
if(animationCounter>20)
animationCounter = 0;
}
}
int tankX = 215; //tank xpos
int tankY = 60; //tank ypos
int tankXD = 0; //tank x dir
int tankYD = 0; //tank y dir
int bulletX = tankX; //bullet xpos
int bulletY = tankY; //bullet ypos
int bulletW = 8; //bullet xpos
int bulletH = 20; //bullet ypos
int bulletSPD = 0; //bullet speed
int bulletRadius = 4;
float bulletDistance = 5;
PImage image1;
class Tank
{
//members
int tankX;
int tankY;
int speedX;
int speedY;
//constructor
Tank (int tankX, int tankY, int speedX, int speedY)
{
this.tankX = tankX;
this.tankY = tankY;
this.speedX = speedX;
this.speedY = speedY;
image1 = loadImage("tank.png");
}
void draw() {
image(image1,tankX, tankY);
tankX+=tankXD;
tankY+=tankYD;
bulletX=tankX;
bulletY+=bulletSPD;
if(bulletY>800) {
bulletX=tankX;
bulletY=tankY;
bulletSPD=0;
}
//draw bullet
fill(255,0,0);
stroke(255,0,0);
rect(bulletX+30, bulletY+140, bulletW, bulletH);
}
//tank crash method
boolean crash(Car other)
{
return (abs(this.tankY-other.cY) <20) && abs(this.tankX-other.cX) <10;
}
/*
boolean shoot (Bullet b, Car c) {
float d = dist(bulletX, bulletY, cX, cY);
if ((d < 5) == true) {
// we have a collision
return true;
} else {
return false;
}
}
*/
/*
boolean shoot(Car c) {
float d = dist(bulletX, bulletY, cX, cY);
if (d < 5) {
// we have a collision
return true;
} else {
return false;
}
}
*/
}
So I believe you want to fix the collision. If you have two circles and you want to see if they collide, you need to see if the radii collide. You can do this by seeing if the distance between the centers is greater than or less than the total of the two radii. Like this:
//returns whether or not two circles collide
//x1, y1, and r1 are for circle 1
boolean colliding(int x1, int y1, int x2, int y2, int r1, int r2) {
return sqrt(pow(x1-x2, 2) + pow(y1-y2, 2)); <= r1 + r2
}
If you wish to use rectangular hitboxes instead, check this link.
I hope this helped, have a good day.
I am working on a project that finds the average color of each scene from a movie and if those colors are within a certain threshold value of red then the frame will be saved as a png. The atnm1.mov reads that RuntimeException: Could not load movie file antm1.mov, and the files do not save?
import processing.video.*;
color trackColor;
float threshold;
Movie video;
void setup() {
size(1200,900);
video = new Movie(this, "antm1.mov");
video.loop();
trackColor = color(255, 0, 0);
}
void movieEvent(Movie video) {
video.read();
}
void draw() {
video.loadPixels();
image(video, 0, 0);
threshold = 80;
float avgX = 0;
float avgY = 0;
int count = 0;
// Begin loop to walk through every pixel
for (int x = 0; x < video.width; x++ ) {
for (int y = 0; y < video.height; y++ ) {
int loc = x + y * video.width;
// What is current color
color currentColor = video.pixels[loc];
float r1 = red(currentColor);
float g1 = green(currentColor);
float b1 = blue(currentColor);
float r2 = red(trackColor);
float g2 = green(trackColor);
float b2 = blue(trackColor);
float d = dist(r1, g1, b1, r2, g2, b2);
if (d < threshold*threshold) {
avgX += x;
avgY += y;
count++;
}
}
}
if (count >5) {
avgX = avgX / count;
avgY = avgY / count;
saveFrame("output/mov1####.png");
}
}
I am trying to make the drawRedlines function appear and disappear inside the mousePressed function and mouseReleased function. I have tried using background(255); in my mouseReleased but it also removes my crossBars function for some reason. I tried changing the cords for the redLine rect's to 0 but it still is in the same position when I release the mouse.
final int NUM_LINES = 15;
final int LINE_THICK = 20;
final int CONVERGE_VERTICAL_OFFSET = 175;
final int CONVERGE_VERTICAL_OFFSET2 = 100;
int capSize = 20;
int width = 500;
int height = 500;
int x1 = 30;
int crossWidth = width - (30*2);
int y1 = height - 20;
int crossHeight = 20;
int capX = x1;
int capY = y1 + crossHeight/2;
int capX2 = width - x1;
int diffY = 60;
int diffX = 10;
int redLinex = 145;
int redLinex2 = 350;
int redLiney = 0;
int redlineHeight = height;
int redlineWidth = 5;
void setup(){
size(500,500);
drawConvergingvertical();
horizontalCross();
drawYellowlines();
}
void draw(){
}
void mousePressed(){
drawRedlines();
}
void mouseReleased(){
drawConvergingvertical();
horizontalCross();
drawYellowlines();
}
void horizontalCross(){
for(int rows = 0; rows < NUM_LINES; rows++){
//println(rows, capX, capX2); Used this to Debug;
drawCrossbars();
y1 = y1 - diffY;
capY = capY - diffY - 1;
x1 = x1 + diffX;
capX = capX + diffX;
crossWidth = crossWidth - diffX*2;
capX2 = capX2 - diffX;
crossHeight = crossHeight - 2;
capSize = capSize - 2;
}
}
void drawCrossbars(){
rect(x1,y1,crossWidth,crossHeight);
ellipse(capX,capY,capSize,capSize);
ellipse(capX2,capY,capSize,capSize);
}
void drawConvergingvertical(){
fill(0);
stroke(0);
quad(width/2-CONVERGE_VERTICAL_OFFSET,height,width/2-CONVERGE_VERTICAL_OFFSET2,0,width/2-CONVERGE_VERTICAL_OFFSET2+LINE_THICK,0,width/2-CONVERGE_VERTICAL_OFFSET+LINE_THICK,height);
quad(width/2+CONVERGE_VERTICAL_OFFSET,height,width/2+CONVERGE_VERTICAL_OFFSET2,0,width/2+CONVERGE_VERTICAL_OFFSET2-LINE_THICK,0,width/2+CONVERGE_VERTICAL_OFFSET-LINE_THICK,height);
}
void drawYellowlines(){
fill(255,255,0);
stroke(255,255,0);
rect(150, height - 100, 200, 10);
rect(150, 100, 200, 10);
}
void drawRedlines(){
redLinex = 145;
redLinex2 = 350;
redLiney = 0;
redlineHeight = height;
redlineWidth = 5;
fill(255,0,0);
stroke(255,0,0);
rect(redLinex,redLiney,redlineWidth,redlineHeight);
rect(redLinex2,redLiney,redlineWidth,redlineHeight);
}
How to remove a shape without using background(255); [...]
Not at all. You cant "remove" something what is drawn in the window. All you can do is to draw something different, what covers the shape. background doesn't remove anything. It just draws an uniform color in the entire window.
You've to redraw the entire scene in draw().
Use the built-in variable mousePressed to identify if the mouse is pressed and call drawRedlines() dependent on the state of the variable. Furthermore you've to reset the state of some variables in in every frame:
void draw() {
capSize = 20;
x1 = 30;
crossWidth = width - (30*2);
y1 = height - 20;
crossHeight = 20;
capX = x1;
capY = y1 + crossHeight/2;
capX2 = width - x1;
diffY = 60;
diffX = 10;
redLinex = 145;
redLinex2 = 350;
redLiney = 0;
redlineHeight = height;
redlineWidth = 5;
background(200);
drawConvergingvertical();
horizontalCross();
drawYellowlines();
if (mousePressed) {
drawRedlines();
}
}
Note, it is not necessary to draw anything in the mouse callback functions mousePressed respectively mouseReleased.
void mousePressed(){
}
void mouseReleased(){
}
Side note: Remove declaration of the variables width and height from your code. This are built-in variables, so it is not necessary to declare them at all, especially since the dependent variables are set in draw.
int width = 500;
int height = 500;
The draw() method is a loop. If you draw your stuff inside that loop, you can update it in real time. I modified your loop a little bit so the red lines appears only while the left mouse button si down:
final int NUM_LINES = 15;
final int LINE_THICK = 20;
final int CONVERGE_VERTICAL_OFFSET = 175;
final int CONVERGE_VERTICAL_OFFSET2 = 100;
int capSize = 20;
int width = 500;
int height = 500;
int x1 = 30;
int crossWidth = width - (30*2);
int y1 = height - 20;
int crossHeight = 20;
int capX = x1;
int capY = y1 + crossHeight/2;
int capX2 = width - x1;
int diffY = 60;
int diffX = 10;
int redLinex = 145;
int redLinex2 = 350;
int redLiney = 0;
int redlineHeight = height;
int redlineWidth = 5;
boolean redLineVisible = false;
void setup(){
size(500,500);
//drawConvergingvertical();
//horizontalCross();
//drawYellowlines();
}
void draw(){
background(255);
drawConvergingvertical();
horizontalCross();
drawYellowlines();
drawRedlines();
}
void mousePressed(){
//drawRedlines();
redLineVisible = true;
}
void mouseReleased(){
//drawConvergingvertical();
//horizontalCross();
//drawYellowlines();
//drawRedlines();
redLineVisible = false;
}
void horizontalCross(){
for(int rows = 0; rows < NUM_LINES; rows++){
//println(rows, capX, capX2); Used this to Debug;
drawCrossbars();
y1 = y1 - diffY;
capY = capY - diffY - 1;
x1 = x1 + diffX;
capX = capX + diffX;
crossWidth = crossWidth - diffX*2;
capX2 = capX2 - diffX;
crossHeight = crossHeight - 2;
capSize = capSize - 2;
}
}
void drawCrossbars(){
rect(x1,y1,crossWidth,crossHeight);
ellipse(capX,capY,capSize,capSize);
ellipse(capX2,capY,capSize,capSize);
}
void drawConvergingvertical(){
fill(0);
stroke(0);
quad(width/2-CONVERGE_VERTICAL_OFFSET,height,width/2-CONVERGE_VERTICAL_OFFSET2,0,width/2-CONVERGE_VERTICAL_OFFSET2+LINE_THICK,0,width/2-CONVERGE_VERTICAL_OFFSET+LINE_THICK,height);
quad(width/2+CONVERGE_VERTICAL_OFFSET,height,width/2+CONVERGE_VERTICAL_OFFSET2,0,width/2+CONVERGE_VERTICAL_OFFSET2-LINE_THICK,0,width/2+CONVERGE_VERTICAL_OFFSET-LINE_THICK,height);
}
void drawYellowlines(){
fill(255,255,0);
stroke(255,255,0);
rect(150, height - 100, 200, 10);
rect(150, 100, 200, 10);
}
void drawRedlines(){
if (redLineVisible) {
redLinex = 145;
redLinex2 = 350;
redLiney = 0;
redlineHeight = height;
redlineWidth = 5;
fill(255,0,0);
stroke(255,0,0);
rect(redLinex,redLiney,redlineWidth,redlineHeight);
rect(redLinex2,redLiney,redlineWidth,redlineHeight);
}
}
Have fun.
I've created objects already in the canvas method. But I need help on how to create an arraylist and to add these four objects to the arraylist so that they will constantly appear. I've looked at the arraylist Heres the code, any assistance will be greatly appreciated.
public class BouncingBallView extends View {
private int xMin = 0; // This view's bounds
private int xMax;
private int yMin = 0;
private int yMax;
private int xMin1 = 0; // This view's bounds
private int xMax1;
private int yMin1 = 0;
private int yMax1;
private int xMin2 = 0; // This view's bounds
private int xMax2;
private int yMin2 = 0;
private int yMax2;
private int xMin3 = 0; // This view's bounds
private int xMax3;
private int yMin3 = 0;
private int yMax3;
private float ballRadius = 80;
private float ballRadius2 = 80;// Ball's radius
private float ballX = ballRadius + 20; // Ball's center (x,y)
private float ballY = 10;//ballRadius + 40;
private float ballX1= ballRadius2 + 30;
private float ballY1 = 15;
private float ballX2 = ballRadius + 20; // Ball's center (x,y)
private float ballY2 = 10;//ballRadius + 40;
private float ballX3 = ballRadius + 20; // Ball's center (x,y)
private float ballY3 = 10;//ballRadius + 40;
private float ballSpeedX = 50; // Ball's speed (x,y)
private float ballSpeedX1= 25;
private float ballSpeedY = 30;
private float ballSpeedY1= 15;
private float ballSpeedX2 = 40; // Ball's speed (x,y)
private float ballSpeedX3= 20;
private float ballSpeedY2 = 20; // Ball's speed (x,y)
private float ballSpeedY3= 10;
private RectF ballBounds; // Needed for Canvas.drawOval
private RectF ballBounds2;
private RectF ballBounds3;
private RectF ballBounds4;
private Paint paint; // The paint (e.g. style, color) used for drawing
// Constructor
public BouncingBallView(Context context) {
super(context);
ballBounds = new RectF();
ballBounds2 = new RectF();
ballBounds3 = new RectF();
ballBounds4 = new RectF();
paint = new Paint();
}
// Called back to draw the view. Also called by invalidate().
#Override
protected void onDraw(Canvas canvas) {
ballBounds2.set(10, ballY1, 50, ballY1+40);
paint.setColor(Color.BLUE);
canvas.drawRoundRect(ballBounds2,6,6, paint);
// Draw the ball
ballBounds.set(10, ballY, 50, ballY+40);
paint.setColor(Color.RED);
canvas.drawRoundRect(ballBounds,6,6, paint);
ballBounds3.set(10, ballY2, 50, ballY2+40);
paint.setColor(Color.YELLOW);
canvas.drawRoundRect(ballBounds3,6,6, paint);
ballBounds4.set(10, ballY3, 50, ballY3+40);
paint.setColor(Color.GREEN);
canvas.drawRoundRect(ballBounds4,6,6, paint);
// Update the position of the ball, including collision detection and reaction.
update();
// Delay
try {
Thread.sleep(30);
} catch (InterruptedException e) { }
invalidate(); // Force a re-draw
}
// Detect collision and update the position of the ball.
private void update() {
// Get new (x,y) position
//ballX += ballSpeedX;
ballY += ballSpeedY;
ballY1 += ballSpeedY1;
ballY2 += ballSpeedY2;
ballY3 += ballSpeedY3;
// Detect collision and react
// if (ballX + ballRadius > xMax) {
// ballSpeedX = -ballSpeedX;
// ballX = xMax-ballRadius;
// }
// else if (ballX - ballRadius < xMin) {
// ballSpeedX = -ballSpeedX;
// ballX = xMin+ballRadius;
// }
if (ballY + ballRadius > yMax) {
ballSpeedY = -ballSpeedY;
ballY = yMax - ballRadius;
} else if (ballY - ballRadius < yMin) {
ballSpeedY = -ballSpeedY;
ballY = yMin + ballRadius;
}
if (ballY1 + ballRadius2 > yMax1) {
ballSpeedY1 = -ballSpeedY1;
ballY1 = yMax1 - ballRadius2;
} else if (ballY1 - ballRadius2 < yMin1) {
ballSpeedY1 = -ballSpeedY1;
ballY1 = yMin1 + ballRadius2;
}
if (ballY2 + ballRadius2 > yMax2) {
ballSpeedY2 = -ballSpeedY2;
ballY2 = yMax2 - ballRadius2;
} else if (ballY2 - ballRadius2 < yMin2) {
ballSpeedY2 = -ballSpeedY2;
ballY2 = yMin2 + ballRadius2;
}
if (ballY3 + ballRadius2 > yMax3) {
ballSpeedY3 = -ballSpeedY3;
ballY3 = yMax3 - ballRadius2;
} else if (ballY3 - ballRadius2 < yMin3) {
ballSpeedY3 = -ballSpeedY3;
ballY3 = yMin3 + ballRadius2;
}
}
// Called back when the view is first created or its size changes.
#Override
public void onSizeChanged(int w, int h, int oldW, int oldH) {
// Set the movement bounds for the ball
xMax = w-1;
yMax = h-1;
xMax1= w-1;
yMax1= h-1;
xMax2 = w-1;
yMax2 = h-1;
xMax3 = w-1;
yMax3 = h-1;
}
}
This code goes inside of your constructor.
ArrayList<RectF> ballBoundArray = new ArrayList<RectF>();
ballBoundArray.add(ballBounds);
ballBoundArray.add(ballBounds2);
ballBoundArray.add(ballBounds3);
ballBoundArray.add(ballBounds4);
Edit: If you want the array list to be accessible outside of the constructor, define it as a private or public variable with the other ballbounds.