• 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?

VPS Starter Arubacloud
0 głosów
348 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,630 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 92 wizyt
pytanie zadane 8 marca w C i C++ przez TOWaD Mądrala (5,700 p.)
0 głosów
0 odpowiedzi 885 wizyt
pytanie zadane 11 września 2022 w Systemy operacyjne, programy przez regiss Nowicjusz (140 p.)
+1 głos
1 odpowiedź 105 wizyt

92,453 zapytań

141,262 odpowiedzi

319,087 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...