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

Efekty na potworze, implementacja

+1 głos
131 wizyt
pytanie zadane 18 lutego 2017 w C i C++ przez Munvik Dyskutant (8,290 p.)

Mam problem z zaimplementowaniem efektów ( poison, slow, shock, burn ) w klasie monster.
Myślałem nad klasą abstrakcyjną effect i dziedziczące po niej poison slow , ... .

Dodam, że tylko jeden rodzaj danego efektu może być aktywny/

Jak przechowywać te efekty i co gdybym chciał sprawdzić czy nowa trucizna jest silniejsza od poprzedniej.

Już dostałem kilka pomysłów ale nadal nie wiem jak zaimplementować coś takiego :/

2 odpowiedzi

+2 głosów
odpowiedź 18 lutego 2017 przez Ehlert Mędrzec (165,080 p.)

This is my design:

//efekty + SFML

class Effect{
private:

	sf::Time accumulator;
	sf::Time delay;
	
	virtual void hurt() = 0;

	virtual void beginHurt() = 0;

	virtual void endEffect() {

	}

	Hero * target;

public:

	void update(sf::Time _dt) {
		accumulator += _dt;
		if (accumulator >= delay) {
			hurt();
			accumulator = sf::Time::Zero;
		}
	}

	Effect(Hero* _target, sf::Time _delay)
	:	
		accumulator		(sf::Time::Zero),
		delay			(_delay),
		target			(_target)
	{
		beginHurt();
	}
	
	virtual ~Effect() {
		endEffect();
	}

};

class Burned : public Effect {
private:

	virtual void hurt() {
		target->hurt(10);
	}

	virtual void beginHurt() {
		target->hurt(30);
	}

public:
	
	Burned(Hero* _target, sf::Time _delay) : Effect(_target, _dealy) {}

	~Burned() {}

};

class Poisoned : public Effect {
private:

	unsigned lastHp;

	virtual void hurt() {
		unsigned currentHP = target->getHP();
		if (currentHP > lastHP)
			target->hurt(currentHP - lastHP);
	}

	virtual void beginHurt() {
		target->hurt(12);
	}

public:
	
	Poisoned(Hero* _target, sf::Time _delay) 
	: 
		Effect			(_target, _dealy),
		lastHP			(target->getHP())
	{}

	~Poisoned() {}
};

class Frozen : public Effect {
private:

	float beginSpeedScalar;

	virtual void hurt() {
		target->hurt(11);
	}

	virtual void beginHurt() {
		target->setSpeedScalar(beginSpeedScalar*0.5f);
	}

	virtual void endEffect() {
		target->setSpeedScalar(beginSpeedScalar);
	}

public:
	
	Frozen(Hero* _target, sf::Time _delay) 
	: 
		Effect(_target, _dealy),
		beginSpeedScalar		(target->getSpeedScalar())		
	{
		
	}

	~Frozen() {}
}
komentarz 18 lutego 2017 przez Munvik Dyskutant (8,290 p.)

Podoba mi się :)

Tylko jak trzymać Effect * ?

I jak chcę np otruć  lub spowolnić  monsterka to dać jedną metodę

void monster::addEffect(effect *eff);

komentarz 18 lutego 2017 przez Ehlert Mędrzec (165,080 p.)
class Hero{
Effect * burned;
Effect * frozen;
Effect * poisoned;
};

Domyślnie wszystko ustawione na nullptr. Taki zapis gwarantuje Ci istnienie tylko jednego efektu na targecie. Pamiętaj że każdemu new musi odpowiadać delete; Inaczej napisane przeze mnie zamrożenie będzie spowalniać postać do końca gry + wycieki pamięci. 

BTW. Zapomniałem o czymś ważnym. Powinien być zaimplementowany jeszcze jeden accumulator który cały czas gromadzi czas. Jeśli przekroczy np. 20 sekund to target np. poparzenia sprawdza flagę state efektu i widzi że jest skończony. Wtedy Delete.

komentarz 18 lutego 2017 przez Munvik Dyskutant (8,290 p.)

Ok rozumiem, tylko jak metoda addEffect ma wiedzieć do którego wskaznika przypisac efekt ?

void monster::addEffect(effect *eff)
{
   // burned = eff ?
   // frozen = eff ?
   // poisoned = eff ?
}
komentarz 18 lutego 2017 przez Ehlert Mędrzec (165,080 p.)

addEffect nie jest konieczna. Możesz dodać metody addBurned itp.

komentarz 18 lutego 2017 przez Munvik Dyskutant (8,290 p.)
Ok no to już chyba mam z głowy to bo od wczoraj nie daje mi to spokoju :)

Dzięki
komentarz 19 lutego 2017 przez draghan VIP (102,870 p.)
Czy to rozwiązanie Cię satysfakcjonuje, Munvik? :)
komentarz 19 lutego 2017 przez Munvik Dyskutant (8,290 p.)

Wiele założeń miałem podobnych ale miałem dużo też niepewności. Już poison zaimplementowany i śmiga ;)

komentarz 19 lutego 2017 przez draghan VIP (102,870 p.)
W takim razie sprawa zamknięta i nie potrzeba kolejnej wersji wymyślać. :) Miłego wieczoru.
0 głosów
odpowiedź 18 lutego 2017 przez draghan VIP (102,870 p.)

Myślałem nad klasą abstrakcyjną effect i dziedziczące po niej poison slow , ... .

Twoje rozwiązanie brzmi rozsądnie.

Dodam, że tylko jeden rodzaj danego efektu może być aktywny/

To znaczy? Podaj, proszę, jakiś konkret.

komentarz 18 lutego 2017 przez obl Nałogowiec (45,940 p.)
Jemu chyba chodzi o to, że na stworku powinien tylko jeden efekt działać, czyli jak działa spowolnienie to nie może równocześnie działać na niego trucizna.
komentarz 18 lutego 2017 przez draghan VIP (102,870 p.)

Jemu chyba chodzi

No właśnie - chyba. :) Poczekam aż sam wyjaśni, bo to dość istotna kwestia przy projektowaniu implementacji.

komentarz 18 lutego 2017 przez Munvik Dyskutant (8,290 p.)
Na stworku może oddziałowywać krwawienie / spowolnienie / trucizna w tym samym czasie, tylko chodzi mi to, żeby nowa trucizna zastąpiła starą.
komentarz 18 lutego 2017 przez Munvik Dyskutant (8,290 p.)

Nie wiem czy odpowiednia będzie metoda 

void monster::addEffect(effect *eff);

bo wykonując ją metoda nie wie jaki efekt się kryje w argumencie i co ma z nim zrobić, np sprawdzić czy trucizna istnieje 

komentarz 18 lutego 2017 przez obl Nałogowiec (45,940 p.)
Ja to bym zrobił w klasie pola zawierające współczynniki:

zatrucia

krwawienia

spowolnienia

Jak współczynnik jest równy zero to dany efekt nie został nałożony na stwora.
komentarz 18 lutego 2017 przez Munvik Dyskutant (8,290 p.)

Ok a możesz przedstawić swoją wizję jakby miała wyglądać metoda 

void monster::addEffect(effect *eff);

według Ciebie ? I co trzymać w klasie monster ? std::vector<effect *> nie wydaje mi się, żeby działał w tym przypadku, ale może się mylę.

Podobne pytania

0 głosów
0 odpowiedzi 100 wizyt
pytanie zadane 28 grudnia 2017 w Java przez bartolinciu Mądrala (7,110 p.)
0 głosów
1 odpowiedź 96 wizyt
pytanie zadane 6 sierpnia 2017 w C i C++ przez CPP_Newbie Użytkownik (780 p.)
0 głosów
3 odpowiedzi 842 wizyt
pytanie zadane 18 listopada 2015 w C i C++ przez Baakoma Użytkownik (780 p.)
Porady nie od parady
Publikując kody źródłowe korzystaj ze specjalnego bloczku koloryzującego składnię (przycisk z napisem code w edytorze). Nie zapomnij o ustawieniu odpowiedniego języka z rozwijanego menu oraz czytelnym formatowaniu kodu.Przycisk code

64,830 zapytań

111,290 odpowiedzi

234,054 komentarzy

46,702 pasjonatów

Przeglądających: 234
Pasjonatów: 9 Gości: 225

Motyw:

Akcja Pajacyk

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

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...