Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Event problems.  (Read 3402 times)

0 Members and 1 Guest are viewing this topic.

_4004

  • Newbie
  • *
  • Posts: 12
    • View Profile
Event problems.
« on: March 02, 2020, 08:13:17 pm »
Hello. In the application I am trying to make, I move a circle in certain positions. And there is one blue (anacircle) circle. When we hover over and click on this blue circle, the location of the blue circle will change. Okay, so far, everything is normal. However, when the next position of the blue circle is very close to its previous position and I try to click it, it does not detect the second click. In order to perceive the click, the "gezgin" circle must return one more turn. Why? Sorry for my bad English.

This happens only when I speed up the "gezgin" circle . And I'm sure I clicked, I get output with the cout.

I put their variable names according to my head, they don't represent anything.

Code:
#include "stdafx.h"
#include <SFML/Graphics.hpp>
#include <Windows.h>
#include <iostream>
 
 
using namespace std;;
using namespace sf;;
 
 
 
int main()
{
        sf::RenderWindow window(sf::VideoMode(400, 400), "beta");
 
        sf::CircleShape shape(10.f);
        shape.setFillColor(sf::Color::Green);
        shape.setOrigin(7.f, 10.f);
 
        CircleShape gezgin(10.f);
        gezgin.setFillColor(Color::Red);
        gezgin.setOrigin(7.f, 10.f);
 
        vector <sf::CircleShape> anacircle;
        shape.setPosition(205, 40);
        anacircle.push_back(shape);
        shape.setPosition(286, 62);
        anacircle.push_back(shape);
        shape.setPosition(347, 123);
        anacircle.push_back(shape);
        shape.setPosition(369, 205);
        anacircle.push_back(shape);
        shape.setPosition(348, 287);
        anacircle.push_back(shape);
        shape.setPosition(286, 347);
        anacircle.push_back(shape);
        shape.setPosition(205, 369);
        anacircle.push_back(shape);
        shape.setPosition(122, 347);
        anacircle.push_back(shape);
        shape.setPosition(62, 286);
        anacircle.push_back(shape);
        shape.setPosition(41, 206);
        anacircle.push_back(shape);
        shape.setPosition(64, 124);
        anacircle.push_back(shape);
        shape.setPosition(124, 64);
        anacircle.push_back(shape);
 
        Clock clock;
        int random = 0;
        int que = 0;
        int degis = 0;
        int zamanlayici = 1000;
        while (window.isOpen())
        {
                Event olay;
 
                Time zaman = clock.getElapsedTime();
                int speed = zaman.asMilliseconds();
 
                if (que == 0)
                {
                        random = rand() % 11;
                        cout << random << endl;
                        que = 1;
                        anacircle[random].setFillColor(Color::Cyan);
                }
 
                if (speed >= zamanlayici)
                {
                        clock.restart();
                        degis++;
                        if (degis == 12)
                                degis = 0;
 
                }
                for (int i = 0; i < 12; i++) {
                       
                        if (degis == i) {
                                gezgin.setPosition(anacircle[i].getPosition().x, anacircle[i].getPosition().y);
                               
                       
                        }
 
                        else if (zaman.asMilliseconds() >= 12000)
                        clock.restart();
 
        }
 
 
                sf::Event event;
                while (window.pollEvent(event))
                {
                       
                        //      if (event.type == sf::Event::MouseButtonPressed)
                //      {
                        //      if (event.mouseButton.button == sf::Mouse::Left){
                        if(Mouse::isButtonPressed(Mouse::Left)){
                                        if (gezgin.getPosition().x == anacircle[random].getPosition().x && gezgin.getPosition().y == anacircle[random].getPosition().y) {
 
                                                que = 0;
                                                anacircle[random].setFillColor(Color::Green);
//
                                        }
                           }
                        //      if (event.mouseButton.button == sf::Mouse::Right)
                                                if(Mouse::isButtonPressed(Mouse::Right))
                                {
                                        if (zamanlayici <= 100)
                                                zamanlayici -= 10;
 
                                        else
                                                zamanlayici -= 100;;
                                        cout << zamanlayici << endl;
                                }
                       
                        if (event.type == sf::Event::Closed)
                                window.close();
                }
 
 
                window.clear();        
                for (int i = 0; i < anacircle.size(); i++) {
                        window.draw(anacircle[i]);
 
                }
                window.draw(gezgin);
                window.display();
 
 
        }
 
 
        return 0;
}
« Last Edit: March 02, 2020, 08:40:07 pm by _4004 »

Fx8qkaoy

  • Newbie
  • *
  • Posts: 42
    • View Profile
Re: Event problems.
« Reply #1 on: March 03, 2020, 09:35:11 am »
Hello. In the application I am trying to make, I move a circle in certain positions. And there is one blue (anacircle) circle. When we hover over and click on this blue circle, the location of the blue circle will change. Okay, so far, everything is normal. However, when the next position of the blue circle is very close to its previous position and I try to click it, it does not detect the second click. In order to perceive the click, the "gezgin" circle must return one more turn. Why? Sorry for my bad English.

This happens only when I speed up the "gezgin" circle . And I'm sure I clicked, I get output with the cout.

I put their variable names according to my head, they don't represent anything.

Code:
#include "stdafx.h"
#include <SFML/Graphics.hpp>
#include <Windows.h>
#include <iostream>
 
 
using namespace std;;
using namespace sf;;
 
 
 
int main()
{
        sf::RenderWindow window(sf::VideoMode(400, 400), "beta");
 
        sf::CircleShape shape(10.f);
        shape.setFillColor(sf::Color::Green);
        shape.setOrigin(7.f, 10.f);
 
        CircleShape gezgin(10.f);
        gezgin.setFillColor(Color::Red);
        gezgin.setOrigin(7.f, 10.f);
 
        vector <sf::CircleShape> anacircle;
        shape.setPosition(205, 40);
        anacircle.push_back(shape);
        shape.setPosition(286, 62);
        anacircle.push_back(shape);
        shape.setPosition(347, 123);
        anacircle.push_back(shape);
        shape.setPosition(369, 205);
        anacircle.push_back(shape);
        shape.setPosition(348, 287);
        anacircle.push_back(shape);
        shape.setPosition(286, 347);
        anacircle.push_back(shape);
        shape.setPosition(205, 369);
        anacircle.push_back(shape);
        shape.setPosition(122, 347);
        anacircle.push_back(shape);
        shape.setPosition(62, 286);
        anacircle.push_back(shape);
        shape.setPosition(41, 206);
        anacircle.push_back(shape);
        shape.setPosition(64, 124);
        anacircle.push_back(shape);
        shape.setPosition(124, 64);
        anacircle.push_back(shape);
 
        Clock clock;
        int random = 0;
        int que = 0;
        int degis = 0;
        int zamanlayici = 1000;
        while (window.isOpen())
        {
                Event olay;
 
                Time zaman = clock.getElapsedTime();
                int speed = zaman.asMilliseconds();
 
                if (que == 0)
                {
                        random = rand() % 11;
                        cout << random << endl;
                        que = 1;
                        anacircle[random].setFillColor(Color::Cyan);
                }
 
                if (speed >= zamanlayici)
                {
                        clock.restart();
                        degis++;
                        if (degis == 12)
                                degis = 0;
 
                }
                for (int i = 0; i < 12; i++) {
                       
                        if (degis == i) {
                                gezgin.setPosition(anacircle[i].getPosition().x, anacircle[i].getPosition().y);
                               
                       
                        }
 
                        else if (zaman.asMilliseconds() >= 12000)
                        clock.restart();
 
        }
 
 
                sf::Event event;
                while (window.pollEvent(event))
                {
                       
                        //      if (event.type == sf::Event::MouseButtonPressed)
                //      {
                        //      if (event.mouseButton.button == sf::Mouse::Left){
                        if(Mouse::isButtonPressed(Mouse::Left)){
                                        if (gezgin.getPosition().x == anacircle[random].getPosition().x && gezgin.getPosition().y == anacircle[random].getPosition().y) {
 
                                                que = 0;
                                                anacircle[random].setFillColor(Color::Green);
//
                                        }
                           }
                        //      if (event.mouseButton.button == sf::Mouse::Right)
                                                if(Mouse::isButtonPressed(Mouse::Right))
                                {
                                        if (zamanlayici <= 100)
                                                zamanlayici -= 10;
 
                                        else
                                                zamanlayici -= 100;;
                                        cout << zamanlayici << endl;
                                }
                       
                        if (event.type == sf::Event::Closed)
                                window.close();
                }
 
 
                window.clear();        
                for (int i = 0; i < anacircle.size(); i++) {
                        window.draw(anacircle[i]);
 
                }
                window.draw(gezgin);
                window.display();
 
 
        }
 
 
        return 0;
}

Before pointing what could be wrong is worth to note that the way u are developing is faulty and may make someone who reads the post to go insane or point wrong solution. Before responding back, please change ur codebase by following these tips which "in general" are good practice:
- don't write code in ur native language; this is the perfect example why u shouldn't: others can't understand, be they helpers on forums or people in a possibly company
- don't name variables with descriptive names if they don't describe the object; is better to just name "a", "b" or "tmp" so someone who reads the code doesn't associate by mistake; these names shall be temporary and changed when u found out a good description for them
- try to avoid excesive nesting when u can; most of times u can combine 2 "if" statements in only 1
- for boolean vars use "bool", not "int"; don't threat memory as inexistent (4 bytes rather than 1 bit), but don't do premature optimizations either (short - 2 bytes)

Ur uncommented way of checking if a mouse button is clicked is faulty, as u're not making use of "event" at all. If u keep it pressed, doesn't it gets triggered tons of times? It says in documentation that Mouse class is independent of events

_4004

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Event problems.
« Reply #2 on: March 03, 2020, 11:03:26 pm »
Yes. I read what you say. Thanks but this project was a little urgent. Either I need to pay attention to urgent projects or arrange a little while asking for help because those who have difficulties in understanding do not could to help. Also, as far as I understand from your last sentence, holding the mouse down does not triggered tons of times if in the event loop.

Actually I want to say:
Consider two circles. One of them is moving and the other is constant position. When the moving circle over to the fixed one, you click the mouse and the fixed one teleports to a random position. However, if the incoming position is the next position of the circle, it does not detect when you click. It is necessary to wait for the circle to return one turn.

Fx8qkaoy

  • Newbie
  • *
  • Posts: 42
    • View Profile
Re: Event problems.
« Reply #3 on: March 04, 2020, 07:18:43 am »
Yes. I read what you say. Thanks but this project was a little urgent. Either I need to pay attention to urgent projects or arrange a little while asking for help because those who have difficulties in understanding do not could to help. Also, as far as I understand from your last sentence, holding the mouse down does not triggered tons of times if in the event loop.

Actually I want to say:
Consider two circles. One of them is moving and the other is constant position. When the moving circle over to the fixed one, you click the mouse and the fixed one teleports to a random position. However, if the incoming position is the next position of the circle, it does not detect when you click. It is necessary to wait for the circle to return one turn.

If u have stuff in event loop DOES NOT mean it will be executed only when the desired event triggers. I expect in ur code that if u keep the mouse pressed and move it (which triggers move events), the behaviour that I explained earlier will happen, contrary to what u just mentioned

What u mean by "return"? Like u have to do a useless click before so the next one can count?

_4004

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Event problems.
« Reply #4 on: March 04, 2020, 09:05:11 pm »
My translation skills are not good. So I will summarize my problem again. Thank you for the answer. If you want to find a solution to the problem, you can help me with an edit on the code. My problem is that if we click the mouse, the position of the circle that randomly changes position does not detect that we click on it if it is in the position immediately after the previous one. I hope I explained.

Fx8qkaoy

  • Newbie
  • *
  • Posts: 42
    • View Profile
Re: Event problems.
« Reply #5 on: March 05, 2020, 02:55:38 pm »
My translation skills are not good. So I will summarize my problem again. Thank you for the answer. If you want to find a solution to the problem, you can help me with an edit on the code. My problem is that if we click the mouse, the position of the circle that randomly changes position does not detect that we click on it if it is in the position immediately after the previous one. I hope I explained.

I solved the problem and refactored the code so u will have an example of good practices. Maybe u're a beginner, but u will see that an organized code is suggestive and tells u by itself how to optimize and debug. Make sure to read every comment (if possible copy the code in an editor, don't read there)

// Cleaned the headers
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace std;
using namespace sf;
int main() {
    // In this block comes the bug fix, please first accustome to the rest of the code, run it, and when u're done uncomment the line below
    // srand(time(nullptr)); // Maybe u would like to edit the line so u don't get the the warning when compiling
    // There was no randomness because the seed was not set. Permanent random sequence started with 8 9 9 1
    // U may consider to get random positions until it is not equal to the previous one, so u don't get repeated ones

    sf::RenderWindow window({400, 400}, "beta");
    window.setFramerateLimit(60); // Don't burn ur GPU

    sf::CircleShape slot(10);
    auto emptySlotColor = Color::Green;
    slot.setFillColor(emptySlotColor);
    slot.setOrigin(7, 10);

    CircleShape spinSprite(10);
    spinSprite.setFillColor(Color::Red);
    spinSprite.setOrigin(7, 10);

    vector<sf::CircleShape> slots;
    for(auto& pos : vector<Vector2f> {
        {205, 40},
        {286, 62},
        {347, 123},
        {369, 205},
        {348, 287},
        {286, 347},
        {205, 369},
        {122, 347},
        {62, 286},
        {41, 206},
        {64, 124},
        {124, 64}
    }) {
        slot.setPosition(pos);
        slots.push_back(slot);
    }

    int markedCursor = 0;
    int spinCursor = 0;
    float switchEvery = 1; // Secs
    auto switchSlot = [&] { // I'm using a lambda so I won't change the vars arrangement, so u can recognize the code and compare it. A strong typed fct would've been better
        markedCursor = rand() % (slots.size() - 1); // Make the max number dependent, so if u change the number of them u don't have to update here
        cout << markedCursor << endl;
        slots[markedCursor].setFillColor(Color::Cyan);
    };

    switchSlot();
    spinSprite.setPosition(slots[0].getPosition());

    Clock clock;
    Event event;
    while (window.isOpen()) {
        // First time poll events before changing states
        while (window.pollEvent(event))
            if (event.type == sf::Event::Closed)
                window.close();
            else if(event.type == Event::MouseButtonPressed)
                // This is the right way to check events
                // If the button is left but pos differents, the code will do a useless check for right. Chosed this design for readability
                if(event.mouseButton.button == Mouse::Left && spinSprite.getPosition() == slots[markedCursor].getPosition()) { // Vector2f has == operator
                    slots[markedCursor].setFillColor(emptySlotColor); // If u use the same value in 2 locations, use a var (const how people prefer)

                    // No need to store a int (it should've been a bool), do the stuff right away
                    // It wouldn't work with previous event handling methods
                    switchSlot();
                }
                else if(event.mouseButton.button == Mouse::Right) {
                    switchEvery -= (switchEvery < .1f ? .01f : .1f); // One line
                    cout << switchEvery << endl;
                }
        window.clear();

        // Do the check in one line. Good formatted code doesn't need (in general) explications
        if (clock.getElapsedTime().asSeconds() >= switchEvery) { // I'm quite sure u want >= rather than >
            clock.restart();
            spinCursor = (spinCursor == 11 ? 0 : spinCursor + 1); // One line, easier to read

            // Don't follow this with another "for" loop. U already have everything u need
            // Don't do every frame either, u wanna change the pos only when u're in this "if"
            spinSprite.setPosition(slots[spinCursor].getPosition()); // Interchanging positions doesn't need to explicit both x and y
        }

        for(auto& slot : slots)
            window.draw(slot);
        window.draw(spinSprite); // U should use same technique as the cyan circle

        window.display();
    }
}
 
« Last Edit: March 05, 2020, 03:41:43 pm by Laurent »

_4004

  • Newbie
  • *
  • Posts: 12
    • View Profile
Re: Event problems.
« Reply #6 on: March 05, 2020, 08:29:29 pm »
OMG. Thank you very much. I wrote the code like this because I was in a hurry. But what I want to tell is this: Watch out for 14th and 28th seconds. Why has the position not changed? Look at the text "clicked" .Thanks again.

https://streamable.com/4xdw2

Fx8qkaoy

  • Newbie
  • *
  • Posts: 42
    • View Profile
Re: Event problems.
« Reply #7 on: March 05, 2020, 10:08:43 pm »
OMG. Thank you very much. I wrote the code like this because I was in a hurry. But what I want to tell is this: Watch out for 14th and 28th seconds. Why has the position not changed? Look at the text "clicked" .Thanks again.

https://streamable.com/4xdw2

As I mentioned in one of the comments, it's possible that the next random position to be the exact last one, which visually looks like nothing happened, but the "cout" notices u that the change was made