I wrote this code on Processing 3.3.7, it creates a ball that bounces around.
Ball b;
int n = 0;
void setup() {
size(600, 400);
b = new BallBuilder()
.buildRadius(20)
.buildXSpeed(5)
.buildYSpeed(5)
.buildYAcceleration(1)
.toBall();
}
void draw() {
background(0);
n++;
print("n: " + n + " | ");
print("xSpeed: " + b.getXSpeed() + " | ");
println("ySpeed: " + b.getYSpeed());
b.display();
b.move();
}
There is also a Ball class, which has these methods:
void display() {
fill(255);
stroke(255);
ellipse(xPosition, yPosition, radius * 2, radius * 2);
}
void move() {
this.moveX();
this.moveY();
}
private void moveX() {
for(float i = 0; i <= abs(this.xSpeed); i += abs(this.xSpeed) / 10) {
this.bounceX();
this.xPosition += this.xSpeed / 10;
}
}
private void moveY() {
for(float i = 0; i <= abs(this.ySpeed); i += abs(this.ySpeed) / 10) {
this.bounceY();
this.yPosition += this.ySpeed / 10;
}
this.ySpeed += this.yAcceleration;
}
void bounceX() {
if(!this.canMoveX()) {
this.xSpeed = -this.xSpeed;
}
}
void bounceY() {
if(!this.canMoveY()) {
this.ySpeed = -this.ySpeed;
}
}
boolean canMoveX() {
if(this.xPosition < radius || this.xPosition >= width - this.radius) {
return false;
}
return true;
}
boolean canMoveY() {
if(this.yPosition < radius || this.yPosition >= height - this.radius) {
return false;
}
return true;
}
}
And there's also a builder and two getters for the Ball(not posted here, as they're pretty straight forward). The problem is, neither the xSpeed nor the ySpeed can be set to 0, otherwise the code stops running. That means that I need to give it both speeds when instantiating and if I set the acceleration makes the speed go to 0, the program stops running (the n variable is used to count the number of times the draw() loops, when the speed hits 0, it stops increasing). What am I missing?
Have you tried debugging your code to figure out where the code differs from what you expected?
You have two loops like this:
for(float i = 0; i <= abs(this.xSpeed); i += abs(this.xSpeed) / 10) {
You might add a print statement inside these loops, like this:
println("i: " + i);
If you did this, you'd discover that i is always 0. Why is that?
Think about what happens if this.xSpeed is 0: when will this loop exit?
Related
I have tried many methods, and can't seem to grasp the idea of extracting an index from my array of strings to help me generate my desired number of building with a desired height, please help, here is my example
edit: Hi, i saw your feedback and posted my code below, hopefully it helps with the idea overall, as much as it is just creating rects, its more complicated as i need to involve arrays and string splitting along with loops. i more or less got that covered but i as i said above, i cannot extract the values from my array of string and create my facades at my own desired number and height
String buffer = " ";
String bh = "9,4,6,8,12,2";
int[] b = int(split(bh, ","));
int buildingheight = b.length;
void setup () {
size(1200, 800);
background(0);
}
void draw () {
}
void Textbox() {
textSize(30);
text(buffer, 5, height-10);
}
void keyTyped() {
if (key == BACKSPACE) {
if (buffer.length() > 0) {
buffer = buffer.substring(0, buffer.length() - 1);
}
} else if (key == ENTER) {
background(0);
stroke(0);
GenerateFacade();
println(buffer);
}
else {
buffer = buffer + key;
Textbox();
}
}
void GenerateFacade() {
fill(128);
for (int i = 0; i < b.length; i++) {
for (int j = 0; j < b.length; j++) {
if (int(b[j]) > buildingheight) {
buildingheight = int(b[j]);
}
}
rect(i*width/b.length, height - (int(b[i])*height/buildingheight), width/b.length, int(b[i])*height/buildingheight);
}
}
For the next time it would be great if you provide us with some code so we know what you tried and maybe can point you to the problem you have.
You need just the keyPressed function and some variables
int x = 0;
int buildingWidth = 50;
int buildingHeight = height / 6;
void setup(){
size(1000, 500);
background(255);
}
void draw(){
}
void keyPressed(){
if(key >= '0' && key <= '9'){
int numberPressed = key - '0' ;
fill(0);
rect(x, height - buildingHeight * numberPressed,
buildingWidth, buildingHeight * numberPressed);
x += buildingWidth;
}
}
This is my result
I can't see where the circle and not sure what's wrong with my code to make it so I can't see the circle with gravity that I coded. Wondering where I went wrong and what I could do to improve it. Can't seem to see what I've done wrong and I put the circle in gameState2 because I'm making the game in that gameState, gameState1 is for the introduction screen. I want to know why the circle won't appear when I use pvectors. If someone can please help me it would be greatly appreciated(this is an assignment for my class). I hope the comments help show the area in which I need help. (Also if someone could look over my code just for confirmation that I won't get bugs while trying to make the gravity.)
PImage background, backgroundGameState1, headbasketballbackground, player1, player2;
boolean moveRight, moveLeft, moveRight2, moveLeft2;
int canvasSizeX= 1000;
int canvasSizeY = 600;
int mainBackgroundX = 1000;
int mainBackgroundY = 600;
int gameState1 = 1;
int player1X = 100;
int player1Y = 200;
int player2X = 100;
int player2Y = 200;
int backgroundGameState1X= 1000;
int backgroundGameState1Y=600;
int time;
int player1MovmentX = 700;
int player2MovmentX = 100;
PVector Position = new PVector(250, 400);
PVector Velocity = new PVector(0, 0);
PVector Acceleration = new PVector(0, 5);
float elasticity = 0.8;
float airResistance = 0;
void setup() {
//size of canvas is 1000 on the X-axis by 600 on the y-axis
size(1000, 600);
//Loaded images and called them, also made sure to resize them in order to match the canvas size or to make program more asthetically pleasing
background = loadImage("headbasketballbackground.png");
background.resize(mainBackgroundX, mainBackgroundY);
backgroundGameState1 = loadImage("backgroundgamestate1.png");
backgroundGameState1.resize(backgroundGameState1X, backgroundGameState1Y);
player1 = loadImage("steph.png");
//resized image for the steph curry png
player1.resize(player1X, player1Y);
player2 = loadImage("kobe.png");
//resized the png
player2.resize(player2X, player2Y);
time=millis();
}
void draw() {
if (gameState1 == 1) {
background(backgroundGameState1);
if (millis() > time + 1000) {
text("Click On Space To Enter The Game!", 100, 100);
textSize(50);
// delay(3000); Used as a test to see how the delay would work and found it to be extremely slow so I increased it to 1000 milliseconds
}
drawGameState1();
}
if (gameState1 == 2) {
background(background);
image(player1, player1MovmentX, 300);
image(player2, player2MovmentX, 300);
}
if (player1MovmentX < 30) {
player1MovmentX = 40;
}
if (player1MovmentX > 930) {
player1MovmentX = 920;
}
if ( player2MovmentX < 30) {
player2MovmentX = 40;
}
if (player2MovmentX > 930) {
player2MovmentX = 920;
}
// if (gameState2 == 3) {
// text("Congrats you won!");
//}
}
void drawGameState1() {
}
void drawGameState2() {
drawBall();
checkIfBallHitEdge();
moveBall();
drawPlayer1Movment();
drawPlayer2Movment();
//drawBoundaries();
}
void drawGameState3() {
}
void drawPlayer1Movment() {
if (moveRight) {
player1MovmentX += 25;
}
if (moveLeft) {
player1MovmentX -= 25;
}
}
void drawPlayer2Movment() {
if (moveRight2) {
player2MovmentX += 25;
}
if (moveLeft) {
player2MovmentX -= 25;
}
}
//pvectors used here
void drawBall() {
ellipse(Position.x, Position.y, 30, 30);
}
void moveBall() {
Velocity = Velocity.add(Acceleration);
Velocity = Velocity.mult((1-airResistance)); // This slows the ball down a little bit each instant
Position = Position.add(Velocity);
}
//pvectors end here
void checkIfBallHitEdge() {
if (Position.x < 0 || Position.x > width) {
Velocity.x *= -1;
}
if (Position.y < 0) {
Velocity.y *= -1;
}
if (Position.y > height) { // Strikes the ground
Velocity.y *= -elasticity;
Position.y = height;
}
}
void keyPressed() {
if (gameState1 == 1) {
if (keyCode == 32) {
gameState1 = 2;
}
} else if (gameState1 == 2) {
if (keyCode == RIGHT) {
moveRight = true;
player1MovmentX += 25;
}
if (keyCode == LEFT) {
moveLeft = true;
player1MovmentX -= 25;
}
if (keyCode == 68) {
moveRight2 = true;
player2MovmentX += 25;
}
if (keyCode == 65) {
moveLeft2 = true;
player2MovmentX -= 25;
}
if (keyCode == UP) {
Velocity.y = -70;
}
}
}
void keyReleased() {
if (keyCode == RIGHT) {
moveRight = false;
}
if (keyCode == LEFT) {
moveLeft = false;
}
if (keyCode == 68) {
moveRight2 = false;
}
if (keyCode == 65) {
moveLeft2 = false;
}
}
I used the processing IDE for java.
so, I've spent a fair few hours on my Mario-like game but recently I've been stuck on the collisions after I changed to an object based collision system that seems like it should work but there is a bug somewhere that i cant find.
currently the box that represents the player just falls straight through the platform rather than sitting on the platform
You wont be able to run this snippet because I'm new to stack overflow and couldn't find anything closer to processing.
Here is the box class that has all my collision detection
//Box class -- THIS IS WHERE I NEED HELP -- everything else is just for context
//Box class
class Box {
private float xpos, ypos, sizeX, sizeY;
private float bottom = ypos + sizeY;
private float top = ypos;
private float left = xpos;
private float right = xpos + sizeX;
Box(float startX, float startY, float xSize, float ySize) {
boxes++;
xpos = startX;
ypos = startY;
sizeX = xSize;
sizeY = ySize;
}
void update() {
rect(xpos, ypos, sizeX, sizeY);
}
void collision() {
//If on box level
if (player.playerY + player.playerHeight >= top && player.playerY <= bottom) {
//Left Side
if ((player.playerX + player.playerWidth) <= left && (player.playerX + player.playerWidth) + speed >= left) {
player.playerX = left - player.playerWidth;
player.canMoveRight = false;
}
//Right Side
if (player.playerX >= right && player.playerX + speed <= right) {
player.playerX = right;
player.canMoveLeft = false;
}
}
//If in box Y coord
if (player.playerX + player.playerWidth >= left && player.playerX <= right) {
//top
if (player.playerY + player.playerHeight <= top && player.playerY + player.yVelocity + gravity >= top) {
player.Gravity = false;
player.playerY = top - player.playerHeight;
player.yVelocity = 0;
player.canMoveDown = false;
}
//bottom
if (player.playerY + player.yVelocity >= bottom && player.playerY + player.yVelocity + gravity <= bottom) {
player.canMoveUp = false;
player.yVelocity = 0;
player.playerY = bottom;
}
}
//onGround
if (player.playerY == ypos - player.playerHeight) {
player.onGround = true;
}
}
}
Control structure for multiple keypresses
//Control structure to enable multiple keypresses
//Control
float speed = 4;
float gravity = 1;
float jump = 10;
boolean isUp, isLeft, isDown, isRight;
void control() {
//Controls
if (isUp) {
if (player.canMoveUp) {
if (player.onGround) {
player.Gravity = true;
player.yVelocity = 0 + jump;
player.onGround = false;
}
}
}
if (isDown) {
if (player.canMoveDown) {
}
}
if (isRight) {
if (player.canMoveRight) {
player.playerX += speed;
}
}
if (isLeft) {
if (player.canMoveLeft) {
player.playerX -= speed;
}
}
if (player.onGround) {
player.Gravity = false;
player.yVelocity = 0;
}
}
void keyPressed() {
setMove(keyCode, true);
}
void keyReleased() {
setMove(keyCode, false);
}
boolean setMove(int k, boolean b) {
switch (k) {
case UP:
return isUp = b;
case DOWN:
return isDown = b;
case LEFT:
return isLeft = b;
case RIGHT:
return isRight = b;
default:
return b;
}
}
Main tab, box/entity updates and player class
//Main tab
float boxes = 0;
//Calls classes
Box b = new Box(0, 700, 800, 100);
Box b1 = new Box(300, 675, 25, 25);
Player player = new Player(50, 400, 20, 20);
void setup() {
size(800, 800);
frameRate(60);
}
void draw() {
background(255, 255, 255);
boxesUpdate();
boxesCollision();
entityUpdate();
control();
println(player.playerX + ", " + player.playerY);
println(player.yVelocity + ", " + player.Gravity + ", " + player.onGround + ", " + player.canMoveDown);
}
//Box collision update method for when i add more boxes
void boxesCollision() {
player.Gravity = true;
player.canMoveUp = true;
player.canMoveDown = true;
player.canMoveLeft = true;
player.canMoveRight = true;
player.onGround = false;
b.collision();
b1.collision();
if (player.Gravity) {
player.playerY += player.yVelocity;
player.yVelocity += gravity;
}
}
//Along with another update method for the other parts of the boxes
void boxesUpdate() {
b.update();
b1.update();
}
//Entity update method to update players and for when i add NPCs and enemies
void entityUpdate() {
player.update();
}
//Player class
class Player {
private float playerX, playerY, playerWidth, playerHeight;
private float yVelocity = 0;
private float xVelocity = 0;
private boolean canMoveRight, canMoveLeft, canMoveUp, canMoveDown;
private boolean onGround, Gravity;
Player(float X, float Y, float xSize, float ySize) {
playerWidth = xSize;
playerHeight = ySize;
playerX = X;
playerY = Y;
}
void update() {
rect(playerX, playerY, playerWidth, playerHeight);
}
}
I am currently using a processing sketch to work through a large number of images I have in a folder. I have set an onClick command to advance to the next image in the string. It is quite time consuming and I would like to automate the action that once the sketch is completed the sketch would repeat it's self selecting the next image from the string. The onClick command also save the image the export folder but each time saves with the same file name, I've tried to set up sequential numbering but it hasn't worked so far. Any help would be greatly appreciated.
String[] imgNames = {"1.jpg", "2.jpg", "3.jpg"};
PImage img;
int imgIndex = 0;
void nextImage() {
background(255);
frameRate(10000);
loop();
frameCount = 0;
img = loadImage(imgNames[imgIndex]);
img.loadPixels();
imgIndex += 1;
if (imgIndex >= imgNames.length) {
imgIndex = 0;
}
}
void paintStroke(float strokeLength, color strokeColor, int strokeThickness) {
float stepLength = strokeLength/4.0;
// Determines if the stroke is curved. A straight line is 0.
float tangent1 = 0;
float tangent2 = 0;
float odds = random(1.0);
if (odds < 0.7) {
tangent1 = random(-strokeLength, strokeLength);
tangent2 = random(-strokeLength, strokeLength);
}
// Draw a big stroke
noFill();
stroke(strokeColor);
strokeWeight(strokeThickness);
curve(tangent1, -stepLength*2, 0, -stepLength, 0, stepLength, tangent2, stepLength*2);
int z = 1;
// Draw stroke's details
for (int num = strokeThickness; num > 0; num --) {
float offset = random(-50, 25);
color newColor = color(red(strokeColor)+offset, green(strokeColor)+offset, blue(strokeColor)+offset, random(100, 255));
stroke(newColor);
strokeWeight((int)random(0, 3));
curve(tangent1, -stepLength*2, z-strokeThickness/2, -stepLength*random(0.9, 1.1), z-strokeThickness/2, stepLength*random(0.9, 1.1), tangent2, stepLength*2);
z += 1;
}
}
void setup() {
size(1600, 700);
nextImage();
}
void draw() {
translate(width/2, height/2);
int index = 0;
for (int y = 0; y < img.height; y+=1) {
for (int x = 0; x < img.width; x+=1) {
int odds = (int)random(20000);
if (odds < 1) {
color pixelColor = img.pixels[index];
pixelColor = color(red(pixelColor), green(pixelColor), blue(pixelColor), 100);
pushMatrix();
translate(x-img.width/2, y-img.height/2);
rotate(radians(random(-90, 90)));
// Paint by layers from rough strokes to finer details
if (frameCount < 20) {
// Big rough strokes
paintStroke(random(150, 250), pixelColor, (int)random(20, 40));
} else if (frameCount < 1000) {
// Thick strokes
paintStroke(random(75, 125), pixelColor, (int)random(8, 12));
} else if (frameCount < 1500) {
// Small strokes
paintStroke(random(20, 30), pixelColor, (int)random(1, 4));
} else if (frameCount < 10000) {
// Big dots
paintStroke(random(5, 10), pixelColor, (int)random(5, 8));
} else if (frameCount < 10000) {
// Small dots
paintStroke(random(1, 2), pixelColor, (int)random(1, 3));
}
popMatrix();
}
index += 1;
}
}
if (frameCount > 10000) {
noLoop();
}
// if(key == 's'){
// println("Saving...");
// saveFrame("screen-####.jpg");
// println("Done saving.");
// }
}
void mousePressed() {
save("001.tif");
nextImage();
}
Can't you just call the nextImage() function from inside this if statement?
if (frameCount > 10000) {
noLoop();
}
Would be:
if (frameCount > 10000) {
nextImage();
}
As for using different filenames, just use an int that you increment whenever you save the file, and use that value in the save() function. Or you could use the frameCount variable:
save("img" + frameCount + ".tif");
If you have follow-up questions, please post a MCVE instead of your whole project. Try to isolate one problem at a time in a small example program that only does that one thing. Good luck.
I am trying to create 100 frames where the numbers 0-100 are "printed" in the center of every frame. If I try the code below I get the error "It looks like you're mixing "active" and "static" modes".
size(1440,900);
font = loadFont("Arial-Black-96.vlw");
textFont(font,96);
int x = 0;
void draw() {
background(204);
y=0;
if (x < 100) {
text(y, 10, 50);
x = x + 1;
y=y+1;
} else {
noLoop();
}
// Saves each frame as screen-0001.tif, screen-0002.tif, etc.
saveFrame();
}
You need to wrap the first 3 lines in the setup() function.
Like:
void setup(){
size(1440,900);
font = loadFont("Arial-Black-96.vlw");
textFont(font,96);
}
I answered this without running the code, there were others issues, here a version of your code:
PFont font;
int x = 0;
int size = 96;
void setup() {
size(1440, 900);
font = createFont("Arial-Black", size);
textFont(font);
}
void draw() {
background(204);
if (x <= 100) {
String number = nf(x, 2);
text(number, width/2 - textWidth(number)/2, height/2);
x++;
saveFrame();
}
else {
exit();
}
}