4
\$\begingroup\$

I am new to programming using the site openprocessing.org.

The code given does the following on my iPad:

  1. Draw a red circle
  2. Wait until I finger tap near the red circle’s center
  3. Erase the red circle
  4. Pause for a few seconds
  5. Draw a white circle

Any comments on my program would be appreciated.

let x1, y1;
let x2, y2;
let CircleDiameter;
let MoveState = 0;
function setup() {
 createCanvas(windowWidth, windowHeight);
 frameRate(60);
 
 CircleDiameter = floor(.50*windowWidth);
 
 x1=floor(.25*windowWidth);
 y1=floor(.50*windowHeight);
 x2=floor(.75*windowWidth);
 y2=floor(.50*windowHeight);
 
 background('black');
 
 fill('Red');
 circle(x1,y1,CircleDiameter);
 
 fill('Yellow');
 circle(x1,y1,10);
}
function touchStarted() {
 if( MoveState === 0 && abs(mouseX-x1) <= 25 && abs(mouseY-y1) <= 25) {
 MoveState = 1;
 }
}
function draw() {
 if( MoveState === 1 ) {
 MoveState = 2;
 InitialframeCount = frameCount;
 EraseStart = InitialframeCount + 1;
 EraseEnd = InitialframeCount + CircleDiameter;
 DrawStart = EraseEnd + 1 + 3*60;
 DrawEnd = EraseEnd + CircleDiameter + 3*60;
 } else if ( MoveState === 2) {
 if( frameCount >= EraseStart && frameCount <= EraseEnd) {
 fill('Red');
 circle(x1,y1, CircleDiameter - (frameCount-EraseStart) - 1 );
 }
 if( frameCount >= DrawStart && frameCount <= DrawEnd) {
 fill('White');
 circle(x2,y2, (frameCount-DrawStart) + 1 );
 }
 if( frameCount === DrawEnd) {
 MoveState = 999;
 }
 }
 
}

Here is an animated gif of the output:

animation of red circle being erased before white circle is drawn

Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
asked Jul 15 at 19:48
\$\endgroup\$
10
  • \$\begingroup\$ If you reduce it to an MRE, you could ask for help on Stack Overflow. Alternately, you might try looking up the setTimeout function as an alternative to busy-waiting. \$\endgroup\$ Commented Jul 16 at 23:35
  • \$\begingroup\$ Yes -one could declare a function const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)) and then instead of the for loop with a call to random() one could instead call delay(3000); after declaring mousePressed() with the async keyword. Perhaps the loop with the call to random() takes more than a few seconds on "common hardware for todays users"... \$\endgroup\$ Commented Jul 16 at 23:45
  • \$\begingroup\$ @mdfst13 Thanks for your suggestion. Unfortunately openprocessing.org does not seem to support setTimeout. However I discovered something useful that works for me, the system variable frameCount. \$\endgroup\$ Commented Jul 17 at 2:54
  • 2
    \$\begingroup\$ @Will.Octagon.Gibson I'm glad that you found something that worked for you. You could edit your question with the working code and ask for it to be reopened. While Sam's suggestion wouldn't work on openprocessing.org without a way to use async functions, I was able to get setTimeout working in callback mode (I tried it before making the suggestion). \$\endgroup\$ Commented Jul 17 at 3:14
  • 1
    \$\begingroup\$ I'm using a macbook with the Brave Browser similar to Google Chrome; I can remote desktop to my Windows 10 desktop with Google Chrome Version 138.0.7204.158 (Official Build) (64-bit) and see similar results, though the tops and bottoms of the circles are actually outside the viewport... e.g. red circle drawing and white circle drawing \$\endgroup\$ Commented Jul 18 at 5:08

1 Answer 1

2
\$\begingroup\$

A few minor tweaks

EraseStart isn't needed, it's basically InitialframeCount (you could also then get rid of the -1 in the red circle). The second if should be an else which doesn't need to worry about && frameCount < DrawEnd because you change MoveState later on. I'd add clear for the shrinking red circle, as I saw artifacts without.

if( MoveState === 1 ) {
 MoveState = 2;
 InitialframeCount = frameCount;
 EraseEnd = InitialframeCount + CircleDiameter;
 DrawStart = EraseEnd + 1 + 3*60;
 DrawEnd = EraseEnd + CircleDiameter + 3*60;
} else if ( MoveState === 2) {
 if(frameCount <= EraseEnd) {
 clear()
 fill('Red');
 circle(x1,y1, CircleDiameter - (frameCount-InitialframeCount));
 } else if( frameCount >= DrawStart) {
 fill('White');
 circle(x2,y2, (frameCount-DrawStart) + 1 );
 }
 if( frameCount === DrawEnd) {
 MoveState = 999;
 }
}

I believe adding a FrameRate variable at the top would allow you to speed up/slow down the animation speed from one spot:

let FrameRate = 30
function setup() {
 createCanvas(windowWidth, windowHeight);
 frameRate(FrameRate);
...
 DrawStart = EraseEnd + 1 + 3*FrameRate;
 DrawEnd = EraseEnd + CircleDiameter + 3*FrameRate;
...
answered Jul 29 at 14:35
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.