• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Płynniejszy ruch - jakieś pomysły?

Object Storage Arubacloud
0 głosów
351 wizyt
pytanie zadane 30 sierpnia 2017 w C i C++ przez WireNess Stary wyjadacz (11,240 p.)
Cześć

Piszę sobie remake paint-a w SFML i mam dość poważny problem z pomysłem na rysowanie elementów.

Załóżmy, że mam kilka możliwości rysowania (punkt,linia,kwadrat,koło) i w jaki sposób zrobić miejsce do rysowania? Wiem, że dosyć niezrozumiale tłumacze, ale mam tak od zawsze :D

Próbowałem z tablicą vector i dodawaniem na jej ostatni element wybrany kształt, ale gdy szubciej ruszymy myszką rysuje - zamiast lini kwadratów - kwadraty oddalone od siebie o kilkadziesiąt px :D

Jak zrobić taki ruch, jaki posiada oryginalny paint? (Gdzie mamy myszkę tam rysuje, niezależnie od szybkości poruszania)

Jeżeli coś jest niezrozumiałe, proszę - nie krytykujcie :D

Pozdrawiam
komentarz 30 sierpnia 2017 przez niezalogowany
Może mógłbyś podać kod co już masz? ;)

3 odpowiedzi

+1 głos
odpowiedź 30 sierpnia 2017 przez maly Nałogowiec (37,190 p.)
Rysuj linie od wcześniejszej pozycji myszy do bieżącej.
0 głosów
odpowiedź 30 sierpnia 2017 przez Ehlert Ekspert (212,790 p.)
Przecież RectangleShape ma metody setPosition i setSize. Zapisujesz punkt kiedy nastąpi MousePressed (dodajesz do vectora narysowanych figur prostokąt i nadajesz mu setPosition z tym punktem) i potem wywołujesz setSize dopóki nie nastąpi MouseRelease (badając pozycję myszki)

Moim zdaniem to bardzo prosta rzecz. Jeśli dalej nie kumasz podrzuć kod.
komentarz 30 sierpnia 2017 przez WireNess Stary wyjadacz (11,240 p.)

Problem w tym, że tak właśnie robiłem.

Gdy lewy klawisz nyszy jest wciśnięty, pobieram pozycje x i y myszki. Ustawiam pozycje RectangleShape na te właśnie koordynaty i dodaje do tablicy vector.

Lecz nie działa to jak bym chciał, ponieważ gdy poruszymy myszką szybciej, kwadraty są od siebie oddalone o kilkadziesiąt px. Chciałbym, aby było tak, że wszędzie tam, gdzie będzie myszka pojawi się ten kwadrat.

Pozdrawiam

0 głosów
odpowiedź 30 sierpnia 2017 przez niezalogowany
edycja 30 sierpnia 2017

Czy chodzi o taki przypadek?

#include <iostream>
#include <vector>
#include <SFML/Graphics.hpp>

int main()
{
	sf::RenderWindow window(sf::VideoMode(1024, 720), "Witam");
	window.setFramerateLimit(60);

	std::vector<sf::RectangleShape> rects;
	sf::RectangleShape rect;
	rect.setSize({ 50, 50 });
	rect.setOrigin({ 25, 25 });
	rect.setFillColor(sf::Color::Red);

	while (window.isOpen())
	{
		sf::Event event;
		sf::Vector2f mouse_pos(sf::Mouse::getPosition(window));

		while (window.pollEvent(event))
		{
			if (event.type == sf::Event::Closed) window.close();

			if (event.type == sf::Event::MouseMoved)
			{
				rect.setPosition(mouse_pos);
			}

			if (event.type == sf::Event::KeyPressed)
			{
				if (event.key.code == sf::Keyboard::C)
					rects.clear();
			}
		}

		if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
		{
			if (rects.size() != rects.max_size())
			rects.push_back(rect);
		}

		window.clear();
		window.draw(rect);
		for (auto& i : rects) window.draw(i);
		window.display();
	}
}

Wymyśliłem coś takiego:

#include <iostream>
#include <vector>
#include <SFML/Graphics.hpp>

namespace hip // bede potrzebowal 2 funkcje:
{
	template <typename T>
	T length(sf::Vector2<T> v)
	{
		return std::hypot(v.x, v.y);
	}

	template <typename T>
	sf::Vector2<T> norm(sf::Vector2<T> v)
	{
		return length(v) != 0 ? v / length(v) : sf::Vector2<T>(0, 0);
	}

	template<typename T>
	T dot(sf::Vector2<T> v1, sf::Vector2<T> v2)
	{
		return v1.x*v2.x + v1.y*v2.y;
	}

	template<typename T>
	T crossed(sf::Vector2<T> v1, sf::Vector2<T> v2)
	{
		return v1.x*v2.y - v1.y*v2.x;
	}
}

int main()
{
	sf::RenderWindow window(sf::VideoMode(1024, 720), "Witam");
	window.setFramerateLimit(60);

	std::vector<sf::RectangleShape> rects;
	sf::RectangleShape rect;
	rect.setSize({ 50, 50 });
	rect.setOrigin({ 25, 25 });
	rect.setFillColor(sf::Color::Red);

	bool czy_przycisk_ostatnio_byl_wcisniety = false;

	while (window.isOpen())
	{
		sf::Event event;
		sf::Vector2f mouse_pos(sf::Mouse::getPosition(window));

	
		while (window.pollEvent(event))
		{
			if (event.type == sf::Event::Closed) window.close();

			if (event.type == sf::Event::MouseMoved)
			{
				rect.setPosition(mouse_pos);
			}

			if (event.type == sf::Event::KeyPressed)
			{
				if (event.key.code == sf::Keyboard::C)
					rects.clear();
			}
		}


		if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
		{
			if (czy_przycisk_ostatnio_byl_wcisniety) 
			if (rects.size() > 1)
			{
				sf::RectangleShape copy = rect;
				sf::Vector2f distanse = rect.getPosition() - rects[rects.size() - 1].getPosition(); 

				sf::Vector2f direction = hip::norm(distanse);
				float length = hip::length(distanse);
				float rectSize = rect.getSize().x; // zakladam kwadrat
				float delta_length_it = rectSize / 4.f; // dlugosc odstepu pomiedzy prostokatami - mozesz zmieniac

				if (length > delta_length_it)
				{
					for (float length_it = 0.f; length_it < length; length_it += delta_length_it)
					{
						// rects.size() to iteracja ostatnio dodanego kwadratu
						sf::Vector2f new_pos = rects[rects.size() - 1].getPosition() + delta_length_it*direction;
						copy.setPosition(new_pos);
						rects.push_back(copy);
					}
				}
			}
			rects.push_back(rect); // dodanie wlasciwego kwadratu
			czy_przycisk_ostatnio_byl_wcisniety = true;
		}
		else czy_przycisk_ostatnio_byl_wcisniety = false;

		window.clear();
		window.draw(rect);
		for (auto& i : rects) window.draw(i);
		window.display();
	}
}

Podobne pytania

0 głosów
0 odpowiedzi 101 wizyt
pytanie zadane 8 marca w C i C++ przez TOWaD Mądrala (6,000 p.)
0 głosów
0 odpowiedzi 968 wizyt
pytanie zadane 11 września 2022 w Systemy operacyjne, programy przez regiss Nowicjusz (140 p.)
+1 głos
1 odpowiedź 114 wizyt

92,615 zapytań

141,465 odpowiedzi

319,783 komentarzy

61,997 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...