I have an background image that I want users to think they're interacting with through Processing. The image has a list of words on it and when the user clicks on the region surrounding the word, I want sound to play and a serial number sent to Arduino.
All that aside, I can't get the mousePressed code right. I'm testing it with println("yikes") right now, and now matter where I click on the screen I get "yikes".
On top of all of that, I'm getting errors on else that I can't figure out. Help appreciated.
void setup() {
size(1475, 995);
// The image file must be in the data folder of the current sketch
// to load successfully
img = loadImage("PaceTaker.jpg"); // Load the image into the program
}
void draw() {
// Displays the image at its actual size at point (0,0)
image(img, 0, 0);
}
void mousePressed() {
if (mouseX>105 && mouseX<337 && mouseY>696 && mouseY<714);
{
println("yikes");
stroke(0);
}
else println("hello"));
}
Pay close attention to this line:
if (mouseX>105 && mouseX<337 && mouseY>696 && mouseY<714);
Notice that it ends in a ; semicolon.
This basically says "if the mouse is inside the region, do nothing." Then it gets to the next block of code and always runs it, which is why you're always seeing the "yikes" printed out.
You also have a compilation error on this line:
else println("hello"));
Because it has an extra ) closing parenthesis.
To fix both these problems, get into the habit of always using { } curly brackets with your if and else statements, even if they're just one line, and always check for stray ; semicolons:
if (mouseX>105 && mouseX<337 && mouseY>696 && mouseY<714) {
println("yikes");
stroke(0);
} else {
println("hello");
}
Related
When running my C++/Qt5 program under gdb I experienced what seems like an impossibility:
while(totalAvailable > (sizeof(quint32)+sizeof(quint16))){
if(nullptr!=c){
// POINT-A
qDebug()<<rct<<"Courier message with ID "<<octomy_message_type_int<<" was received with name "<<c->getName()<<" and "<<bytesAvailable<<" bytes available";
const quint16 bytesSpent=c->dataReceived(*ds, bytesAvailable);
const int left=bytesAvailable-bytesSpent;
totalAvailable-=bytesSpent;
if(left>=0){
if(left>0){
ds->skipRawData(left);
totalAvailable-=left;
}
else{
// POINT-B
qDebug()<<rct<<"LOLBOB";
}
}
else{
qWarning()<<"BAR";
return;
}
}
else{
qWarning()<<"FOO";
return;
}
}
In short, when I step from //POINT-A to //POINT-B everything is as expected, but as soon as I step past //POINT-B debugger jumps up to the first line of the program (while statement). But there are no break or continue or other flow-altering statements in the code. How is this possible?
I have tried rebuilding my code from scratch to eliminate a bogus linkage or similar problems, but the bug is reproducible still.
Any input is welcomed.
At POINT-B, you are inside an else, which is inside an if, which is inside an if. Once this else is done, there is nothing more to do in the whole tree.
Where would you expect the pointer to jump to??
Technically, it would go to the closing bracket two lines behind POINT-B, then to the closing bracket three lines behind POINT-B, and then to closing bracket eight lines behind POINT-B, and then to the closing bracket at the very end. All those do nothing, so they are skipped.
Take a paper and pencil, and diagram the logical flow of this chunk of code.
You will make a surprising discovery that the only statement that could possibly execute, after the statement you marked "POINT B", is the condition at the beginning of the while loop. After executing the "POINT B" statement, there are no more statements to execute in the body of the loop, so execution winds back to the while condition, for the next iteration.
Basically the loop just re-iterates. I believe it is functioning as it is supposed to. From Point-A the control goes like such:
If no.1 (Point-A) -> If no.2 -> Else corresponding to If no.3 -> back to end of If no.2 -> back to end of If no.1 -> back to end of while loop.
As the loop is over, the execution checks the loop's condition, (if it is satisfied) re-iterates, and eventually you reach Point-A again.
while()
{
if() // If no.1
{
// Point-A *****************************
if() // If no.2
{
if() // If no.3
{
}
else()
{
// Point-B *****************
}
}
else
{
}
}
else
{
}
}
To improve debugging and readability, do not keep nesting if blocks or loops - It is very hard to trace the execution.
Look if you write it this equivalent way:
while(totalAvailable > (sizeof(quint32)+sizeof(quint16))){
if(nullptr==c){
qWarning()<<"FOO";
return;
}
// POINT-A
qDebug()<<rct<<"Courier message with ID "<<octomy_message_type_int<<" was received with name "<<c->getName()<<" and "<<bytesAvailable<<" bytes available";
const quint16 bytesSpent=c->dataReceived(*ds, bytesAvailable);
const int left=bytesAvailable-bytesSpent;
totalAvailable-=bytesSpent;
if(left<0){
qWarning()<<"BAR";
return;
}
if(left>0){
ds->skipRawData(left);
totalAvailable-=left;
}
else{
// POINT-B
qDebug()<<rct<<"LOLBOB";
}
}
I'm trying to build simple painter (i.e. points, lines, circles ...etc) in glut. Each line must have two points of Point type, so every time the user enter the left button of the mouse, the chosen command is executed. For drawing a line, I need to track how many times the user click the mouse, so this is what I'v done
if ( command == 1 ){ // drawing a line
static int count(0); // track click no.
static std::vector<Point> p;
//static Point startPoint(mouseX, mouseY);
p.push_back(Point(mouseX, mouseY));
if ( count == 1 ){
Point endPoint(mouseX, mouseY);
Point startPoint = p[0];
shapes->addLine(Line(startPoint, endPoint));
count = 0;
p.clear();
}else{
count++;
}
I'm using std::vector only to use clear() so that I can delete startPoint which I need it to be static. My question is is there a way to destroy an object without making more lines by using vector? I've tried to call the destructor but it didn't help.
You could use a unique_ptr<Point>. Then you can use reset to set or destroy the Point:
static std::unique_ptr<Point> startPoint;
if (startPoint){
Point endPoint(mouseX, mouseY);
shapes->addLine({*startPoint, endPoint});
startPoint.reset();
} else {
startPoint.reset(new Point(mouseX, mouseY));
}
Your code is fine. If you're worried about the number of lines then this is a shorter version:
if ( command == 1 ){ // drawing a line
static std::vector<Point> p;
p.push_back(Point(mouseX, mouseY));
if (p.size() == 2){
shapes->addLine(Line(p[0], p[1]));
p.clear();
}
}
Note however that using less lines is only a good thing if this improves readability. If instead it becomes harder to understand the code then it's a bad idea.
Most code is written only once but read many times... saving time when writing is not such a big deal.
In this specific case in my opinion this shorter version is easier to understand, but your mileage may vary.
This is one of those times where something like std::optional<Point> would've been nice.
But regarding to the destruction and reconstruction part, placement new can be helpful here:
static int count(0);
// ('aligned_storage' requires C++11 and '#include <type_traits>')
static std::aligned_storage<sizeof(Point), alignof(Point)>::type startPointBuffer;
Point& startPoint = *static_cast<Point*>(static_cast<void*>(&startPointBuffer));
if (count == 1) {
Point endPoint(mouseX, mouseY);
shapes->addLine(Line(startPoint, endPoint));
count = 0;
startPoint.~Point();
} else {
new (&startPoint) Point(mouseX, mouseY);
count++;
}
I had my program running smoothly, and then after commenting it and adding some final touches, it stopped working on me. The function that I am having problems with is using several objects/functions defined elsewhere, so I am just wondering if someone can affirm that my logic is correct and that the infinite loop is not a product of a syntax error. Thanks for your time, here is the problem I'm having:
If the cashier started a new order and wants to close his order, T is typed in. However, when trying to exit an order and loop back to the start of while(moreCustomers), nothing is happening. I am trying to exit the while(moreItems) loop by setting moreItems = false;, but after doing that, it gets stuck in the while(moreItems) loop and does not go back to while(moreCustomers). Does the syntax make sense, and should I be able to break the loop by setting moreItems = false;?
bool moreCustomers = true;
while (moreCustomers)
{
// get input to start new order or close register
drawInstruct("Enter N to start a new order or E to\n close the register.");
char* setFmt = "#"; // the input must be a letter
char input[7]; // char array that stores input from cashier
s.GetStr(xLeftCoord + 1, yTopCoord + 1, input, 1, setFmt, true);
for(int x = 1; x < 10; x++) // clear the input field
{
s.ClearScreenPos(x, 1);
}
if (input[0] == 'N') // if a new order is requested
{
bool moreItems = true;
while (moreItems)
{
getInput(input);
if(input[1]) // if input is not a single char
{
if (input[0] == 'M') // get the desired number of multiples for the current item and update the tape and display area accordingly
{
custTape.handleMultiples(atoi(input)); // adds multiples to tape
curVal = isUPC->price * (atoi(input)); // updates the current item price
drawDisplayArea(curVal); // updates the display area
}
else // invalid number of multiples, prompt for new multiple
{
drawInstruct("Invalid command. Please try again.");
s.Delay();
}
}
else if (input[0] == 'T') // close the order
{
drawInstruct("Order cancelled.");
s.Delay();
moreItems = false; // customer order is complete, exit loop
}
else // invalid command, get new input from the cashier
{
drawInstruct("Invalid command. Please try again.");
s.Delay();
}
}
}
else if (input[0] == 'E') // close the register
{
moreCustomers = false; // no more customers, exit the program
}
else // invalid command, get new input from the cashier
{
drawInstruct("Invalid Command. Please try again.");
s.Delay();
}
}
I can't exit else if(input[0] == 'T'), and any commands I enter in after moreItems = false; work correctly.
I'd set a breakpoint on the first moreItems = false; line to see if it is ever being hit. My guess is that it is not. You've tagged the question with Visual Studio, so if that is what you're using see this link for how to set a breakpoint:
http://msdn.microsoft.com/en-us/library/vstudio/k80ex6de%28v=vs.100%29.aspx
Basically a breakpoint causes your program to stop at that line. Also try setting a breakpoint on this line:
if (input[0] == 'N')
Run the program, press a key, and wait for the breakpoint to be hit. Then use the "Step Over" option on the Debug menu. This runs your program line by line, each time you press "Step Over" (F10 does this too, much quicker). Keep stepping to see what path of execution occurs through your code. You may also be able to hover over variables to see their values.
Theres loads on the net about debugging with visual studio, but if you master the above you'll be well away
I am making a 2D game where we are supposed to control the character through arrow keys.
if((win.GetInput().IsKeyDown(sf::Key::Down)))
{
y = y + Speed;
}
if((win.GetInput().IsKeyDown(sf::Key::Left)))
{
x = x - Speed;
}
I have set Speed to 10. And then a i use the Sprite.SetPosition(x,y) to actually animate my character.
Everything works fine. But the problem is whenever i press an arrow key, the character moves for 1/2 seconds, stops for about 1/2 seconds and then moves again smoothly. This happens whenever i press any arrow key.
And yes, i am using a while loop on top to handle multiple events simultaneously.
I hope my question was clear enough. Please help me out!
Thanks.
I think you're not handling events the right way. What you're doing here is checking on each event (which could be keyboard input or not) whether the sf::Key::Down key is pressed (and the same for sf::Key::Left).
Firstly, it's not effective, because you don't get the result you want.
Secondly, it performs useless checks admitting that the events could be mouse moves, mouse clicks or anything else : checking whether those keys are pressed in such cases is pointless for your program.
I can't see your whole code, but you should try something of this taste as your main loop :
bool isMovingLeft = false;
bool isMovingDown = false;
sf::Event event;
while (win.IsOpen())
{
// While window catches events...
while(win.GetEvent(event))
{
// If the caught event is a click on the close button, close the window
if (event.Type == sf::Event::Closed)
win.Close();
// If it's a key press, check which key and move consequently
else if (event.Type == sf::Event::KeyPressed)
{
if(event.Key.Code == sf::Key::Left)
isMovingLeft = true;
else if(event.Key.Code == sf::Key::Down)
isMovingDown = true;
}
// If it's a key release, stop moving in the following direction
else if (event.Type == sf::Event::KeyReleased)
{
if(event.Key.Code == sf::Key::Left)
isMovingLeft = false;
else if(event.Key.Code == sf::Key::Down)
isMovingDown = false;
}
}
// Now that we have caught events, we move the lil' thing if we need to.
if(isMovingLeft)
x = x - SPEED;
if(isMovingDown)
y = y - SPEED;
win.Clear();
// Draw things on the screen...
win.Display();
}
In this code, the whole process is split in two parts :
We first intercept the user input to see if we need to change the moving state of the thing.
Then, once every event has been caught and thoroughly analyzed, we move the thing if it has to. It is done through two bools (that you may need to increase to four if you want a four-direction control. If you want to handle diagonal directions, it would be wiser to use an enum than eight bool, which begins to be rather memory-consuming for such a simple task.)
Note : you will maybe notice that I changed "Speed" to "SPEED". I can't see if it was a define, a const var or simply a var from the code you have given, but the best option would be one of the two first ones. I prefer using #define for such things, to make constants easily reachable (as they're put in the preprocessor) and the fully capped writing make it more differentiable from classic vars once in the code. But that's just coding style we're talking of here :)
Hello I am trying to get enemies to move left and right as if they are sliding backwards and forwards I know this can be done with the following code:
slide += slide_incr;
if(abs(slide)>30) slide_incr = -slide_incr;
However this is of no use to me as I need to set a boolean so I can cycle through the frames for when the enemy is going right or going left.
Ive tried the follow code with no luck:
if(abs(eSlide)<=0)
{
eSlide += eSlide_incr;
}
if(abs(eSlide)>30)
{
eSlide_incr = -eSlide_incr;
}
Any ideas on how I can implement it?
Thanks
You want to hold a hysteresis state for if you're sliding forward or backward. You are also mixing up how to use the abs() function when bounds checking. Try something along the lines of:
eSlide += eSlide_incr;
if (abs(eSlide) >= 30) {
eSlide_incr = -eSlide_incr;
}
the first thing that stands out for me is that the contents of the block:
if (abs(eSlid) <= 0) {
eSlide += eSlide_incr;
}
will never ever run (the absolute value will always be greater than or equal to 0)
as for your boolean facing, that can be achieved with:
bool isSlidingRight = eSlide_incr > 0;
(note: this would still use the left animation set for values of 0)