Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Przekazywanie efektu naboju do przeciwnika

Ostatnio zmodyfikowano 2015-11-30 18:49
Autor Wiadomość
qest43
Temat założony przez niniejszego użytkownika
Przekazywanie efektu naboju do przeciwnika
» 2015-11-26 20:37:50
Chcę wprowadzić różne efekty do nabojów typu podpalenie,trucizna itp.
Mam klasę weapon:

C/C++
#pragma once

#include "Item.hpp"

class Weapon
    : public Item
{
public:
    Weapon( std::string data, TextureManager & textureManager );
    void update( sf::Time dt );
    void useItem( Statistic & statistic );
   
private:
    int speed;
    int damage, currentDamage;
    bool collision;
    float criticalAttack;
   
    sf::Vector2i bRect, bTileSize;
   
    sf::Clock game_clock;
    sf::Time shot_delay;
    sf::Time last_fire_timestamp;
};

ona tworzy obiekty pocisków podczas użycia:
C/C++
statistic.bullet.emplace_back( new NormalBullet( statistic.playerPosition, statistic.mousePosition, speed, currentDamage, collision,
bRect, bTileSize, effectData, textureManager ) );
C/C++
#pragma once

#include <SFML\Graphics.hpp>
#include "TextureManager.hpp"

#define _USE_MATH_DEFINES
#include <math.h>

class Bullet
    : public sf::Drawable
{
public:
    Bullet();
   
    virtual void update( sf::Time dt );
    void draw( sf::RenderTarget & target, sf::RenderStates states ) const;
   
    void setIsActive( bool isActive );
    bool getIsActive();
    bool getCollision();
   
    sf::FloatRect getGlobalBounds();
    int getDamage();
protected:
    int setItems( std::string & item );
   
    sf::Sprite sprite;
   
    int damage;
    int speed;
    bool collision;
    sf::Vector2f direction;
    float angle;
   
    bool isActive;
};

I chcę właśnie stworzyć te różne efekty, podpalenie,trucizna itd.
Chcę stworzyć klasę główną Effects, i różne dziedziczące od niej, ale np. będzie taki rodzaj efektu że co kilka sekund będzie odbierać ileś tam  HP ogniem/trucizną, albo pocisk co stunuje gracza itd. Zatem konstruktor będzie przyjmował różne parametry.

Nie wiem czy zrobić jakąś strukturę z parametrami typu type,damage,chance itd. i potem te strukturę wypełniać w weapon, przekazywać do bullet, a za jej pomocą tworzyć efekt na przeciwniku. Macie jakieś pomysły?
P-140878
michal11
» 2015-11-27 09:45:21
Musisz pokazać więcej kodu, w szczególności w jaki sposób twoje pociski oddziałują na Playera i jak wyglada klasa Player.
P-140899
qest43
Temat założony przez niniejszego użytkownika
» 2015-11-29 12:31:22
C/C++
#pragma once

#include "Entity.hpp"
#include "Bullet.hpp"

#include "Animation.hpp"
#include "SpriteSheetAnimation.hpp"

class Player
    : public Entity
{
public:
    void draw( sf::RenderTarget & target, sf::RenderStates states ) const;
    Player( std::string data, TextureManager & textureManager );
    void update( sf::Time dt, Cursor & cursor );
    void handleEvent( sf::Event & event );
    void checkCollision( Entity & entity );
   
    void takeItem( std::vector < std::unique_ptr < Item > > & item );
    void dropItem( std::vector < std::unique_ptr < Item > > & item );
private:
    bool inventoryIsOpen;
};

Tutaj jest wysyłany obiekt przeciwnika

C/C++
void Player::checkCollision( Entity & entity )
{
    for( int i = 0; i < entity.statistic.bullet.size(); i++ )
    if( entity.statistic.bullet[ i ]->getGlobalBounds().intersects( sprite.getGlobalBounds() ) )
    {
        statistic.currentHitPoints -= entity.statistic.bullet[ i ]->getDamage();
       
        entity.statistic.bullet[ i ]->setIsActive( false );
       
        showHitPointsBar = true;
        isDamaged = true;
    }
}
P-141059
michal11
» 2015-11-29 13:51:06
Myślę, że twój pierwszy pomysł był całkiem dobry, stwórz sobie klasę Effect, dodaj sobie takie pole do klasy Bullet i dodaj vector efektów do Playera, wtedy przy kolizji przekazuj Effect z Bulleta do Playera (może korzystając z konstruktora przenoszącego albo shered pointera) i w funkcji update obsługuj efekty. Pola w klasie Effect musisz dostosować do tego jakie efekty planujesz zrobić (może tu napisać jaki planujesz efekty to może coś pomogę) jedynie mogę ci doradzić skorzystanie ze wzorca type object który myślę, że tutaj może ułatwić tworzenie wielu różnych efektów.
P-141069
qest43
Temat założony przez niniejszego użytkownika
» 2015-11-29 14:05:39
Michał takie miałem początkowe zamierzenie, wtedy można dodawać efekty do kafli nawet a nie tylko do nabojów, dzięki czemu jest to bardzo elastyczne. Jednak wynikł jeden problem, mianowicie stworzyłem coś takiego w klasie Entity jak klasa Statistic:

C/C++
#pragma once

#include <SFML\Graphics.hpp>
#include <memory>
#include "Bullet.hpp"

class Statistic
{
public:
    sf::Vector2f velocity, mousePosition, playerPosition;
    float moveSpeed;
    int jumpAmount, currentJumpAmount;
    float jumpSpeed, currentJumpSpeed, jumpAcceleration;
    float currentFallSpeed, maxFallSpeed, fallSpeed, fallAcceleration;
   
    bool falling, ableToJump, jumping, onGround;
    bool collision;
   
    int collisionDamage;
    float currentHitPoints, maxHitPoints;
    bool isDead;
   
    float fireProtection, poisonProtection;
   
    std::vector < std::shared_ptr < Bullet > > bullet;
};

I stworzyłem obiekt tej klasy w Entity, dzięki czemu mogę wysyłać ten obiekt do różnych funkcji i zmieniać parametry. Jest tam też kontener z nabojami.

No i efekty
C/C++
void Effect::update( sf::Time dt, Statistic & statistic )

odbierają te statystki do modyfikacji, jednak tam też znajduje się kontener z pociskami, przez co kod oczywiście się nie kompiluję, ponieważ w pocisku są podlinkowane efekty.

Jeśli chodzi o rodzaje efektów, na razie zrobiłem taki typ że co jakiś czas przez x czasu odbiera y HP danego rodzaju, OGIEŃ,TRUCIZNA itd.

C/C++
void ElementalEffect::update( sf::Time dt, Statistic & statistic )
{
    float currentDamage = damage;
    sf::Time now = clock.getElapsedTime();
   
    if( duration <= now ) isActive = false;
   
    if( isActive )
    if(( now - last_timestamp ) >= delay )
    switch( elementalEffectType )
    {
    case Fire:
        {
            if( statistic.fireProtection >= 0 )
            {
                currentDamage =( 100 /( 100 + statistic.fireProtection ) ) * damage;
                statistic.currentHitPoints -= currentDamage;
            }
            else
                 statistic.currentHitPoints -= currentDamage;
           
            damageEffect.emplace_back( new DamageEffect( currentDamage, sf::Color::Red, statistic.playerPosition ) );
            last_timestamp = now;
            break;
        }
    case Poison:
        {
            if( statistic.poisonProtection >= 0 )
            {
                currentDamage =( 100 /( 100 + statistic.poisonProtection ) ) * damage;
                statistic.currentHitPoints -= currentDamage;
            }
            else
                 statistic.currentHitPoints -= currentDamage;
           
            damageEffect.emplace_back( new DamageEffect( currentDamage, sf::Color::Green, statistic.playerPosition ) );
            last_timestamp = now;
            break;
        }
    }
   
    for( int i = 0; i < damageEffect.size(); i++ )
         damageEffect[ i ]->update( dt );
   
    for( int i = 0; i < damageEffect.size(); i++ )
    if( !damageEffect[ i ]->getIsActive() )
         damageEffect.erase( damageEffect.begin() + i );
   
}

I miałem jeszcze w planach osobne klasy, do stunowania,rootowania,itd. itd.[/i][/i]
Te damageEffect to tylko wyświetla ilość obrażeńzadanych, nic istotnego w tym momencie.
P-141072
michal11
» 2015-11-29 18:14:23
Zrobiłeś właśnie coś odwrotnego do tego o czym ja pisałem, nadałeś Effectowi zachowanie, czyli funkcję update(). A moim zdaniem efekt powinien tylko przechowywać dane, np. rodzaj efektu, ile życia ma odjąć, czas cooldownu itp. Wtedy Effect będzie tylko danymi które posiada Bullet i które przekazuje Playerowi, i które będziesz musiał obsłużyć w funkcji Update Playera, będziesz pobierał dane z Effectu i odpowiednio je stosował. W takim rozwiązaniu Effect może "trzymać" zarówno Bullet jak i kafelek, potwór, przedmiot itd.
P-141108
Monika90
» 2015-11-29 18:30:17
C/C++
statistic.bullet.emplace_back( new NormalBullet( /*...*/ ) );
To jest potencjalny wyciek pamięci. Gdy emplace_back zgłosi wyjątek podczas próby zrobienia miejsca w wektorze na nowy obiekt, to tracisz na zawsze wskaźnik do NormalBullet.
P-141109
qest43
Temat założony przez niniejszego użytkownika
» 2015-11-29 18:40:34
michal11
To gdzie jeśli nie w update obliczać kiedy ponownie odjąć HP, lub dezaktywować efekt?
Czas CD musi się gdzieś wyliczać.

Monika90
To w jaki sposób dodawać nowe obiekty unique ptr jeżeli nie tak?

Z tego co czytam będę musiał i tak przepisać kod od nowa.
P-141111
« 1 » 2
  Strona 1 z 2 Następna strona