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

Efekty na potworze, implementacja

VPS Starter Arubacloud
+1 głos
310 wizyt
pytanie zadane 18 lutego 2017 w C i C++ przez Munvik Dyskutant (9,350 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 Ekspert (212,630 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 (9,350 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 Ekspert (212,630 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 (9,350 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 Ekspert (212,630 p.)

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

komentarz 18 lutego 2017 przez Munvik Dyskutant (9,350 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 (106,230 p.)
Czy to rozwiązanie Cię satysfakcjonuje, Munvik? :)
komentarz 19 lutego 2017 przez Munvik Dyskutant (9,350 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 (106,230 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 (106,230 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 Maniak (51,280 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 (106,230 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 (9,350 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 (9,350 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 Maniak (51,280 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 (9,350 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 737 wizyt
pytanie zadane 28 grudnia 2017 w Java przez bartolinciu Dyskutant (7,580 p.)
0 głosów
1 odpowiedź 217 wizyt
pytanie zadane 6 sierpnia 2017 w C i C++ przez CPP_Newbie Użytkownik (770 p.)
0 głosów
3 odpowiedzi 1,361 wizyt
pytanie zadane 18 listopada 2015 w C i C++ przez Baakoma Użytkownik (780 p.)

92,453 zapytań

141,262 odpowiedzi

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

...