KeyPressed BACKSPACE and delete just one shape - processing

I've create a code for a "generative" logo {Like this http://ebologna.it/ } (it's at the start so is not complete), and I want that while pressing one time the BACKSPACE I can go back just for one shape. Now like I have my code, when I press Backspace it delete all.
Below is the code:
import controlP5.*;
ControlP5 cp5;
String textValue = "";
String val;
void setup() {
size(700,800);
PFont font = createFont("arial",20);
cp5 = new ControlP5(this);
cp5.addTextfield("INPUT")
.setPosition(width/2-100,600)
.setSize(200,40)
.setFont(font)
.setFocus(true)
.setColor(color(255,255,255))
;
textFont(font);
background(0);
noStroke();
}
void draw() {
if (keyPressed) {
if (key == 'o' || key == 'O') {
fill(205, 152, 59, 100);
ellipse(width/2, height/2, 50, 50);
}
if (key == 'b' || key == 'B') {
fill(20, 84, 42, 100);
rectMode(CENTER);
rect(width/2, height/2, 50, 50);
}
}
if (key == BACKSPACE) { //This reset all, I want to reset just the last one shape
background (0);
}
val = cp5.get(Textfield.class,"INPUT").getText();
println(val.length());
}
Thanks !

Another option is to use a for loop to go through each character of the text String and draw the corresponding shape.
A for loop may look complicated because of it's syntax but it's not too bad if you look at it as a way of repeating a set of instructions for a given number of times/steps. The syntax roughly like so:
for( intial step ; condition to stop ; incrementation ){
//something to repeat while the condition to stop is still false
}
think of walking 10 steps, one step a time:
for(int step = 0 ; step < 10 ; step = step+1){
println("step index: " + i);
}
If you can do one step at a time, you can also hop:
for(int step = 0 ; step < 10 ; step = step+2){
println("step index: " + i);
}
Going back to your challenge, you can use a for loop to go through each character of the text. For example:
String text = "go";
for(int letterIndex = 0 ; letterIndex < text.length(); letterIndex = letterIndex + 1){
//get the character
char letter = text.charAt(letterIndex);
println(letter);
}
The snippet above uses String's length() function to retrieve the number of characters and the charAt() to retrieve a character by it's index in the String
Applied to your code:
import controlP5.*;
ControlP5 cp5;
void setup() {
size(700,800);
PFont font = createFont("arial",20);
cp5 = new ControlP5(this);
cp5.addTextfield("INPUT")
.setPosition(width/2-100,600)
.setSize(200,40)
.setFont(font)
.setFocus(true)
.setColor(color(255,255,255));
textFont(font);
background(0);
noStroke();
}
void draw() {
background (0);
//get the text string
String text = cp5.get(Textfield.class,"INPUT").getText();
//loop through each character
for(int letterIndex = 0 ; letterIndex < text.length(); letterIndex = letterIndex + 1){
//get the character
char letter = text.charAt(letterIndex);
//draw the coresponding shape
if (letter == 'o' || letter == 'O') {
fill(205, 152, 59, 100);
ellipse(width/2, height/2, 50, 50);
}
if (letter == 'b' || letter == 'B') {
fill(20, 84, 42, 100);
rectMode(CENTER);
rect(width/2, height/2, 50, 50);
}
}
}

If you want to be able to change what's been drawn to the screen, you're going to have to take this approach:
Step 1: Store everything you need to draw to the screen in a data structure. For you, this might be an ArrayList that holds instances of a Circle class that you create.
Step 2: Every single time draw() is called, clear the previous frames by calling the background() function, and then draw everything in the data structure to the screen.
Step 3: To modify what's on the screen, just modify what's in the data structure. For you, you might remove the Circle in the last position of the ArrayList.

Related

Failed attempt at goto 10 in Processing

I've tried a Goto 10 exercise on Processing and have no idea where is my mistake. The intent was to make a Goto 10 like scenario but there's something I'm missing. I believe the loop may be off.
//line size
int a = 15;
void setup(){
background(255);
size(500,500);
noLoop();
strokeWeight(2);
}
void draw(){
// Y
for(int lineY = 0; lineY < height/a; lineY++){
// X
for(int lineX = 0; lineX < width/a; lineX++){
float randomN = random(1);
pushMatrix();
if (randomN >= 0.5){
rotate(-90);
}
else {
rotate(-45);
}
line(0,0,a,0);
popMatrix();
translate(a, 0);
}
translate((-width), a);
}
}
The amount by which you're translating the x movements of each column don't add up to the full width of the sketch:
for(int lineX = 0; lineX < width/a; lineX++)
width/a will be 33.333 in your example (500 / 15). So you'll end up with 33 loops and 33 columns. But 33 columns * 15 px wide = 495 (not 500).
So when you try to translate back to the beginning of the new row with translate((-width), a); you're moving back a little bit too far each row (-500 instead of -495).
To fix it, make sure you only move back the distance that you moved forward while drawing the columns:
int numCols = floor(width/a); // calculate the number of columns
translate((-numCols * a), a); // move back the correct x distance

Problem with drawing a Pythagoras Tree using L-system and production rules

I am drawing a Pythagoras Tree using L-system and 2 production rules. I managed to use the first rule called “F-rule” to draw the right handside of the tree. I tried using the second rule “H-rule” to draw the left handside. NO matter what I change in the H-rule, it messes up the result of the right handside. Any idea how I can create the leftside similar to the right ? Many thanks.
int SZ = 800;
Tree tree;
void settings() {
size(SZ,SZ);
}
void setup() {
int d = 100;
int x = SZ/2;
int y = SZ/2;
float branchAngle = radians(180);
float branchAngle_Left = radians(-45);
float branchAngle_Right = radians(45);
float initOrientation = PI;
String state = "F"; // initiator
float scaleFactor = 0.8;
String F_rule = "F[+sH]s+F";
String H_rule = "";
String f_rule = "";
int numIterations = 6;
background(255);
noLoop();
tree = new Tree(d, x, y, branchAngle, branchAngle_Right, branchAngle_Left, initOrientation, state, scaleFactor, F_rule, H_rule, f_rule, numIterations);
}
void draw() {
tree.draw();
}
class Tree {
int m_lineLength; // turtle line length
int m_x; // initial x position
int m_y; // initial y position
float m_branchAngle_Right; // turtle rotation at branch
float m_branchAngle_Left; // turtle rotation at branch
float m_branchAngle;
float m_initOrientation; // initial orientation
String m_state; // initial state
float m_scaleFactor; // branch scale factor
String m_F_rule; // F-rule substitution
String m_H_rule; // H-rule substitution
String m_f_rule; // f-rule substitution
int m_numIterations; // number of times to substitute
// constructor
// (d = line length, x & y = start position of drawing)
Tree(int d, int x, int y, float branchAngle, float branchAngle_Right, float branchAngle_Left, float initOrientation, String state, float scaleFactor,
String F_rule, String H_rule, String f_rule, int numIterations) {
m_lineLength = d;
m_x = x;
m_y = y;
m_branchAngle= branchAngle;
m_branchAngle_Right = branchAngle_Right;
m_branchAngle_Left = branchAngle_Left;
m_initOrientation = initOrientation;
m_state = state;
m_scaleFactor = scaleFactor;
m_F_rule = F_rule;
m_H_rule = H_rule;
m_f_rule = f_rule;
m_numIterations = numIterations;
// Perform L rounds of substitutions on the initial state
for (int k=0; k < m_numIterations; k++) {
m_state = substitute(m_state);
}
}
void draw() {
pushMatrix();
pushStyle();
stroke(0);
translate(m_x, m_y); // initial position
rotate(m_initOrientation); // initial rotation
for (int i=0; i < m_state.length(); i++) {
turtle(m_state.charAt(i));
}
popStyle();
popMatrix();
}
void turtle(char c) {
switch(c) {
case 'F': // drop through to next case
case 'H':
//line (0, 0, 0, m_lineLength);
rect(0, 0, m_lineLength, m_lineLength);
translate(0, m_lineLength);
break;
case 'f':
translate(0, m_lineLength);
break;
case 't':
translate(0, -m_lineLength);
break;
case 's':
scale(m_scaleFactor);
break;
case '&':
rotate(m_branchAngle);
break;
case '-':
rotate(m_branchAngle_Left);
break;
case '+':
rotate(m_branchAngle_Right);
break;
case '[':
pushMatrix();
break;
case ']':
popMatrix();
break;
default:
println("Bad character: " + c);
exit();
}
}
// apply substitution rules to string s and return the resulting string
String substitute(String s) {
String newState = new String();
for (int j=0; j < s.length(); j++) {
switch (s.charAt(j)) {
case 'F':
newState += m_F_rule;
break;
case 'H':
newState += m_H_rule;
break;
case 'f':
newState += m_f_rule;
break;
default:
newState += s.charAt(j);
}
}
return newState;
}
}
After a bit of research (1, 2, 3, 4, 5) I have arrived to a few conclusions. However, I haven't been able to find the H and F rules anywhere.
First of all I wouldn't recomend you setting two different angles since they are dependant as they form a right triangle. branchAngle_Right = 90 - branchAngle_Left
Moreover, for 45º, the fact that the scale factor is √2/2 (and not 0,8) is not arbitrary. It's due to trygonometric consequences. If we wanted to generalize it would be something like this: m_scaleFactor_Right = cos(m_branchAngle_Right), and the same for left.
Finally, i would try to redo, the tree generation as it seems to me that it has been overcomplicated. The fourth and the fith (in the coments) references atached at the begining are example codes. See how, in the fith one, it is being calculated the position of the new square and not translating from the previous square, which may be the cause of your problems when doing the left side backwards.
However, i do thing your code could work, but the efford you would put into it would be much larger than doing it from the begining and not overcomplicating.
If you still want to continue that way, please attach some information about those rules you were saying so we can help you.

How to add settings to snake game(Processing)?

Im trying to add settings to a snake game made in processing. I want to have something like easy, normal and hard or something along the lines of that and change the speed and maybe size of the grid. If anyone coudl explain how to id greatly appreciate it!
ArrayList<Integer> x = new ArrayList<Integer>(), y = new ArrayList<Integer>();
int w = 30, h = 30, bs = 20, dir = 2, applex = 12, appley = 10;
int[] dx = {0,0,1,-1}, dy = {1,-1,0,0};
boolean gameover = false;
void setup() {
size(600,600);
x.add(5);
y.add(5);
}
void draw() {
background(255);
for(int i = 0 ; i < w; i++) line(i*bs, 0, i*bs, height); //Vertical line for grid
for(int i = 0 ; i < h; i++) line(0, i*bs, width, i*bs); //Horizontal line for grid
for(int i = 0 ; i < x.size(); i++) {
fill (0,255,0);
rect(x.get(i)*bs, y.get(i)*bs, bs, bs);
}
if(!gameover) {
fill(255,0,0);
rect(applex*bs, appley*bs, bs, bs);
if(frameCount%5==0) {
x.add(0,x.get(0) + dx[dir]);
y.add(0,y.get(0) + dy[dir]);
if(x.get(0) < 0 || y.get(0) < 0 || x.get(0) >= w || y.get(0) >= h) gameover = true;
for(int i = 1; i < x.size(); i++) if(x.get(0) == x.get(i) && y.get(0) == y.get(i)) gameover = true;
if(x.get(0)==applex && y.get(0)==appley) {
applex = (int)random(0,w);
appley = (int)random(0,h);
}else {
x.remove(x.size()-1);
y.remove(y.size()-1);
}
}
} else {
fill(0);
textSize(30);
text("GAME OVER. Press Space to Play Again", 20, height/2);
if(keyPressed && key == ' ') {
x.clear(); //Clear array list
y.clear(); //Clear array list
x.add(5);
y.add(5);
gameover = false;
}
}
if (keyPressed == true) {
int newdir = key=='s' ? 0 : (key=='w' ? 1 : (key=='d' ? 2 : (key=='a' ? 3 : -1)));
if(newdir != -1 && (x.size() <= 1 || !(x.get(1) ==x.get(0) + dx[newdir] && y.get (1) == y.get(0) + dy[newdir]))) dir = newdir;
}
}
You need to break your problem down into smaller steps:
Step one: Can you store the difficulty in a variable? This might be an int that keeps track of a level, or a boolean that switches between easy and hard. Just hardcode the value of that variable for now.
Step two: Can you write your code so it changes behavior based on the difficulty level? Use the variable you created in step one. You might use an if statement to check the difficulty level, or maybe the speed increases over time. It's completely up to you. Start out with a hard-coded value. Change the value to see different behaviors.
Step three: Can you programatically change that value? Maybe this requires a settings screen where the user chooses the difficulty, or maybe it gets more difficult over time. But you have to do the first two steps before you can start this step.
If you get stuck on a specific step, then post an MCVE and we'll go from there.

How to set up if statements so that loop goes forward and then in reverse? Processing

int x = 31;
int y = 31;
int x_dir = 4;
int y_dir = 0;
void setup ()
{
size (800, 800);
}
void draw ()
{
background (150);
ellipse (x,y,60, 60);
if (x+30>=width)
{
x_dir =-4;
y_dir = 4;
}
if (y+30>=height)
{
x_dir=4;
y_dir = 0;
}
if (x+30>=width)
{
x_dir = -4;
}
x+=x_dir;
y+=y_dir;
println(x,y);
}
Hi,
I have to create this program in processing which produces an animation of a ball going in a Z pattern (top left to top right, diagonal top right to bottom left, and then straight from bottom left to bottom right) which then goes backwards along the same path it came.
While I have the code written out for the forward direction, I don't know what 2 if or else statements I need to write for the program so that based on one condition it goes forwards, and based on another condition it will go backwards, and it will continue doing so until it terminates.
If I am able to figure out which two if statements I need to write, all I need to do is copy and reverse the x_dir and y_dir signs on the forward loop.
There are a ton of different ways you can do this.
One approach is to keep track of which "mode" you're in. You could do this using an int variable that's 0 when you're on the first part of the path, 1 when you're on the second part of the path, etc. Then just use an if statement to decide what to do, how to move the ball, etc.
Here's an example:
int x = 31;
int y = 31;
int mode = 0;
void setup ()
{
size (800, 800);
}
void draw ()
{
background (150);
ellipse (x, y, 60, 60);
if (mode == 0) {
x = x + 4;
if (x+30>=width) {
mode = 1;
}
} else if (mode == 1) {
x = x - 4;
y = y + 4;
if (y+30>=height) {
mode = 2;
}
} else if (mode == 2) {
x = x + 4;
if (x+30>=width) {
mode = 3;
}
} else if (mode == 3) {
x = x - 4;
y = y - 4;
if (y-30 < 0) {
mode = 2;
}
}
}
Like I said, this is only one way to approach the problem, and there are some obvious improvements you could make. For example, you could store the movement speeds and the conditions that change the mode in an array (or better yet, in objects) and get rid of all of the if statements.

How can I improve Java2D performance of TextLayout.draw(..)

I'm using the Java2D TextLayout class together with a LineBreakMeasurer and an AttributedCharacterIterator to draw a piece of text into a box. The text is wrapped.
Profiling shows me that the code is very slow. Most of the time is lost in the method TextLayout.draw(..).
Does anyone have a suggestion for speed improvement?
// Get iterator for string
AttributedCharacterIterator iterator = attribText.getIterator();
// Create measurer
LineBreakMeasurer measurer = new LineBreakMeasurer(iterator, context);
// loop over the lines
int i = 1;
while (measurer.getPosition() < iterator.getEndIndex()) {
// Get line
TextLayout textLayout = measurer.nextLayout(w);
// get measurements
float ascent = textLayout.getAscent();
float descent = textLayout.getDescent();
float leading = textLayout.getLeading();
float size = ascent + descent;
// Move down to baseline
if( i == 1 ) {
if( coverType == CoverType.SPINE ) {
y = (box.height-size)/2;
y -= (size+leading)*(lines-1)/2;
} else if( vAlign == Alignment.Center ) {
y += (h-size)/2-(size+leading)*(lines-1)/2;
} else if( vAlign == Alignment.Bottom ) {
y += (h-size) - (size+leading)*(lines-1);
}
}
y += ascent;
// calculate starting point for alignment
float paintX = x;
switch( hAlign ) {
case Right: {
paintX = x + w - textLayout.getVisibleAdvance();
break;
}
case Center: {
paintX = x + (w - textLayout.getVisibleAdvance())/2;
break;
}
}
// Draw line
textLayout.draw(g2d, paintX, y);
// Move down to top of next line
y += descent + leading;
i++;
}
The relevant code snippet is shown above. attribText is an AttributtedString set before. context is the g2d.getFontRenderContext().
This post is rather old now so I hope you have found a solution that works for your needs. If you haven't here is something to think about. You only need to draw the text that is within the visible region. Since you know the y coordinate of each line it is easy to check to see if the y lies within the bounds of getVisibleRect(). Only painting the text that is necessary greatly improves performance (assuming of course that your text is longer than a single page).

Resources