I want to write a function to let labels in the GUI fade in. I use a for loop. Each step in that loop i set the color values of that label higher. After each step i have a time delay of 200 milliseconds.
The following code works, except that the changes in label-color are only visible after the loop is done.
```
void fade(System::Windows::Forms::Label^ label) {
for (int i = 0; i < 10; i++) {
label->ForeColor = System::Drawing::Color::FromArgb(0, (i + 1) * 20, 0);
Sleep(200); // milliseconds
}
}
```
Is there a way to force the GUI to show changes immediately?
Or is there another way to let labels fade in?
label->Update(); did the trick. Thank you very much Hans.
void fade(System::Windows::Forms::Label^ label) {
for (int i = 0; i < 100; i++) {
label->ForeColor = System::Drawing::Color::FromArgb(0, (i + 1) * 2, 0);
Sleep(1); // milliseconds
label->Update();
}
}
Related
I wanted to make a servomotor oscilate between 0-90 degrees when i push a button, but when i push another one, it stops oscillating and then remains in its latest position.
i started with this:
#include <Servo.h>
Servo myservo;
int pos = 0;
const int button1 = 5;
const int button2 = 6;
int lastpos = pos;
void setup() {
myservo.attach(3);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
}
void loop() {
if(digitalRead(button1) == HIGH)
{for(pos = 0; pos <= 90; pos += 1)
{myservo.write(pos);
for(pos = 90; pos >= 0; pos -= 1)
{myservo.write(pos);
delay(36);
} } if(digitalRead(button2) == HIGH){ myservo.write(lastpos);}}}
To start, take a look at how to format code inside a question. It makes it a lot easier to read and help you out. See below for how I formatted for the site, but also readability.
Servo myservo;
int pos = 0;
const int button1 = 5;
const int button2 = 6;
int lastpos = pos;
void setup() {
myservo.attach(3);
pinMode(button1, INPUT);
pinMode(button2, INPUT);
}
void loop() {
if(digitalRead(button1) == HIGH) {
for(pos = 0; pos <= 90; pos += 1) {
myservo.write(pos);
for(pos = 90; pos >= 0; pos -= 1) {
myservo.write(pos);
delay(36);
}
}
if(digitalRead(button2) == HIGH) {
myservo.write(lastpos);
}
}
}
There are several issues with your code based on your description of what you are trying to achieve. First, let's start with the button presses. You are ready the button state, but your code will only detect the button if it is pressed at the exact moment you are doing the digital read. Here's a good resource for reading up on how to properly implement buttons on Arduino: https://www.logiqbit.com/perfect-arduino-button-presses
The second objective is to have the servo sweep back and forth, but stop when you press a button. Your for loops won't let that happen. As currently written, you will always do a sweep to one end and back and then check the next button.
You should update the position of the servo once each time through the loop so you can check on the status of the buttons. In pseudo-code, what I suggest you do is:
void loop() {
//Check button statuses
if(button1), start sweep
if(button2), stop sweep
//Update sweep position
if(ascending && pos < 90) {
//You should be increasing in angle and you haven't reached 90 yet
ascending = TRUE;
pos += 1
myservo.write(pos);
delay(36); //Or whatever delay you need for the servo
} else if(pos > 0) {
//You already reached 90 and are coming back down to 0
ascending = FALSE;
pos -= 1;
delay(36);
}
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.
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.
I am trying to develop a program that can help me to find the Beats Per Minute of a song by clicking, or tapping a button.
I have worked out that I need a dynamic array that saves the time (in milliseconds) of each tap, adding a new element on to the end of the Arraylist every time.
After a certain amount of elements are added, the BPM is worked out by finding the sum of all elements and dividing that by the amount of elements in the list.
I am not very familiar with Arraylists and was wondering whether somebody could help me implement these steps.
I will be using processing for this program.
something like this?
ArrayList <Integer> diffs = new ArrayList<Integer>();
int last, now, diff;
void setup() {
last = millis();
}
void draw() {
}
void mouseClicked() {
now = millis();
diff = now - last;
last = now;
diffs.add(diff);
int sum = 0;
for (Integer i : diffs) {
sum = sum + i;
}
int average = diffs.size() > 0 ? sum/diffs.size() : 0;
println ("average = " + average);
}
Actually if you don't need to access each entrie, you don't even need an arraylist...
int last, now, diff, entries, sum;
void setup() {
last = millis();
}
void draw() {
}
void mouseClicked() {
now = millis();
diff = now - last;
last = now;
sum = sum + diff;
entries++;
int average = sum/entries ;
println ("average = " + average);
}
Need to animate a sorting algorithm, with source code line by line visualization.
INTRO:
For the begining, there is a FORM (see it in the picture attached). On top of that form is displayed a dinamicaly created array of Edit components, containing the array to sort.
A little below, on the right is placed a Memo component, containing the algorithm. At the left of each line of that algorithm, dinamicaly is placed a Label, that indicates the line number in algorithm.
The idea is to highlight line by colouring that label, where is the execution at the moment. Sorting starts when "Start" button is clicked. The action for it is following:
int n = 10;
bool swapped = true; hl(1);
int j = 0; hl(2);
int tmp; hl(3);
while (swapped) { hl(4);
swapped = false; hl(5);
j++; hl(6);
for (int i = 0; i < n - j; i++) { hl(7);
if (arr[i] > arr[i + 1]) { hl(8);
tmp = arr[i]; hl(9);
arr[i] = arr[i + 1]; hl(10);
arr[i + 1] = tmp; hl(11);
swapped = true; hl(12);
} hl(13);
} hl(14);
} hl(15);
The hl function must colour labels and pause execution by using Sleep() function
void TForm2::hl(int l)
{
for (int i = 0; i < 24; i++) {
Form2->lines[i]->Font->Color = clGray;
}
Form2->lines[l-1]->Font->Color = clRed;
Sleep(300);
}
PROBLEM:
Code execution is pausing (sleep function works properly), but the labels are still gray, with no visible changes, except the last one, when event finishes. The 15th line is red.
QUESTION:
Can anybody tell me, where I'm wrong, and how to do it right?
http://i.stack.imgur.com/crGyC.jpg
You need to allow the paint message to be processed in order to visually update the display. You can do that with either the Refresh or Update procedures:
Form2->Lines[l-1]->Font->Color = clGray;
Form2->Update(); // or Form2->Refresh();