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

question-closed System poruszania | SFML

VPS Starter Arubacloud
0 głosów
299 wizyt
pytanie zadane 27 marca 2017 w Inne języki przez WireNess Stary wyjadacz (11,240 p.)
zamknięte 27 marca 2017 przez WireNess

Witam

Mam problem ze stworzeniem systemu poruszania w SFML

Chcę zrobić tak aby po kliknięciu "w" obiekt poruszył się o 10 pikseli do góry.

Próbowałem z x,y ale nie działa tak jakbym tego oczekiwał

Pomożecie?

 

Oto część kodu: 

(...)


If(Keyboard::isKeyPressed(Keyboard::W))
{
    //tu zaczynają się schody
}

(...)

 

komentarz zamknięcia: Z racji tego iż problem został rozwiązany - zamykam - rozwiązanie: Maciej Szostak
komentarz 27 marca 2017 przez Ehlert Ekspert (212,630 p.)
1
komentarz 27 marca 2017 przez Maciej Szostak Początkujący (290 p.)

Generalnie to w SFML masz kilka opcje poruszania się obiektem:
(opiszę kilka prostszych z nich)

1.Oparta na ewentach: 
Dzięki tej metodzie możliwe jest uzyskanie ruchu "kratka po kratce". 

#include <SFML/Window.hpp>
#include <SFML\Graphics.hpp>

sf::RenderWindow win(sf::VideoMode(400, 400), "x");

int main()
{
    sf::RectangleShape rec;
    rec.setSize(sf::Vector2f(10,10));
    rec.setOrigin(5,5);
    rec.setPosition(20,20);

    while (win.isOpen())
    {
        sf::Event e;
        while (win.pollEvent(e))
        {
            if (e.type == sf::Event::KeyPressed && e.key.code == sf::Keyboard::Up)
            {
                rec.move(0, -10);
            }
            if (e.type == sf::Event::KeyPressed && e.key.code == sf::Keyboard::Down)
            {
                rec.move(0, 10);
            }
            if (e.type == sf::Event::KeyPressed && e.key.code == sf::Keyboard::Right)
            {
                rec.move(10,0);
            }
            if (e.type == sf::Event::KeyPressed && e.key.code == sf::Keyboard::Left)
            {
                rec.move(-10,0);
            }
        }

        win.clear(sf::Color::Black);
        win.draw(rec);
        win.display();
    }


    return 0;
}


2.Oparta na bezpośrednim dostępie do klawiszy, i tutaj pojawia się to co ktoś już opisał o przytrzymaniu klawisza (gracz przesunie się o 10 * ilość_obrotów_pętli...)
Aby temu zapobiec zaleca się zastosowanie np. pętli stało krokowej.  
(W tym miejscu możesz regulować prędkość obiektu) 
 

#include <SFML/Window.hpp>
#include <SFML\Graphics.hpp>

sf::RenderWindow win(sf::VideoMode(400, 400), "x");

int main()
{
	sf::RectangleShape rec;
	rec.setSize(sf::Vector2f(10, 10));
	rec.setOrigin(5, 5);
	rec.setPosition(20, 20);

	win.setFramerateLimit(60);

	sf::Clock clock;
	sf::Time lastTime = sf::Time::Zero;
	sf::Time time = clock.restart();

	const sf::Time StepTime = sf::seconds(1.f / 60.f);
	const float speed = 10.f;

	while (win.isOpen())
	{

		time = clock.restart();
		lastTime += time;

		while (lastTime > StepTime)
		{
			lastTime -= StepTime;

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

			if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
			{
				rec.move(sf::Vector2f(0, -10) * StepTime.asSeconds() * speed);
			}

			if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
			{

				rec.move(sf::Vector2f(0, 10) * StepTime.asSeconds() * speed);
			}

			if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
			{
				rec.move(sf::Vector2f(-10, 0) * StepTime.asSeconds() * speed);
			}

			if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
			{
				rec.move(sf::Vector2f(10, 0) * StepTime.asSeconds() * speed);
			}
		}


		win.clear(sf::Color::Black);
		win.draw(rec);
		win.display();
	}


	return 0;

}

3.Poruszanie za myszką/innym obiektem:
W tym miejscu nie ma chyba sensu kopiować pracy kogoś innego polecam więc ten artykuł: http://szymonsiarkiewicz.pl/poradniki/goto/podazanie-za-obiektem-w-przestrzeni-2d/

Po za tym polecić ci mogę jeszcze dokumentacje: 
https://www.sfml-dev.org/learn.php

Jeśli masz jeszcze jakieś pytanie - pytaj.O ile to możliwe postaram się pomóc :)
Pozdrawiam.
 

komentarz 27 marca 2017 przez WireNess Stary wyjadacz (11,240 p.)

Dzięki wielkie! Zrobiłem wszystko tak jak w pierwszym sposobie, ale obiekt.setPosition umieściłem w pętli głównej przez co powodował problem.

Jeszcze raz dzięki laugh

komentarz 27 marca 2017 przez Ehlert Ekspert (212,630 p.)

@Maciej Szostak co to za dziwne metody? Od kiedy to logikę mieszamy z renderingiem i czytaniem eventów?

while (app.isRunning())
{
handleInputs();
delta = timer.restart();
update(delta);
draw();
}

Zanim dasz komuś kawałek kodu upewnij się, że to coś sensownego a nie jest, bo działa.

komentarz 28 marca 2017 przez adrian17 Ekspert (344,100 p.)

Od kiedy to logikę mieszamy z renderingiem i czytaniem eventów?

To akurat bardzo klasyczny prosty przykład z całym kodem w main() - czepiasz się. Z tym, że powinno się działać na delcie, a nie na "liczbie stepów" to się zgadzam.

komentarz 28 marca 2017 przez Ehlert Ekspert (212,630 p.)
IMHO nie jest to czepianie się, a podstawy.

Zgodnie z pierwszym kodem kolegi, za kilka miesięcy jak da swoje dzieło koledze będzie się zastanawiać czemu obiekt zwalnia przy spadku fpsów.

1 odpowiedź

+1 głos
odpowiedź 27 marca 2017 przez niezalogowany

Możesz skorzystać z metody move na obiekcie:

object.move(0, -10);

Tylko używasz funkcji isKeyPressed, która odnosi się do ciągłego naciskania klawisza. Dlatego przy jednym naciśnięciu klawisza on przesunie się de facto o więcej niż 10 px. Dokładnie o 10 * tyle_ile_wykonala_sie_petla_z_window_is_open w trakcie naciśnięcia klawisza. 

PS. W SFML masz wiele udostępnionych metod i nie wszystkie wartości niektórych obiektów są publiczne (x,y ). Masz za to settery i gettery (czy jak to się tam zwało), którymi możesz sobie ustawiać co chcesz np setPosition() .

Podobne pytania

0 głosów
0 odpowiedzi 133 wizyt
pytanie zadane 18 lutego 2019 w C# przez niezalogowany
0 głosów
1 odpowiedź 128 wizyt
pytanie zadane 23 czerwca 2023 w OpenGL, Unity przez Eniggme Nowicjusz (230 p.)
0 głosów
1 odpowiedź 237 wizyt
pytanie zadane 27 kwietnia 2021 w JavaScript przez Nabuchadonozor Gaduła (3,120 p.)

92,454 zapytań

141,262 odpowiedzi

319,099 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!

...