crash Temat założony przez niniejszego użytkownika |
[C++, SFML1.6] Wprowadzanie obiektów w ruch » 2013-01-28 17:08:00 edit: Przepraszam za nieprawidłowy dział, mało snu, dużo monitora :x Przeczytałem kurs DejaVu@ odnośnie wprowadzania obiektów w ruch i przystąpiłem do pisania zmodyfikowanej wersji, w której zamiast sf::Shape przemieszczam obiekt swojej klasy. Klasa ta zawiera prywatnie sf::Image oraz Sprite, który wczytywany jest z Image, a Image z pliku png. Obiekt za pomocą kilku metod reaguje na strzałki, tylko kurka zostaje po nim ślad w starym miejscu. Jako że nie wysiliłem się i nie skopiowałem kodu DejaVu, nie widziałem efektu jak on działa w praktyce, ale coś mi mówi, że... obiekt się odrysowuje a w starym miejscu nie ma po nim śladu. Nie lubię kopiuj-wklej, za to wszelkie próby i modyfikacje jak najbardziej, dlatego cudaczę. W ostateczności skopiuję cały kod i skompiluję, póki co chcę pokombinować po swojemu. Wymyśliłem takie coś, że do pamięci jako mapa piksli byłby kopiowany fragment ekranu odpowiednio większy od sprajta po to, że gdy się sprajta przemieści w którymś z czterech kierunków, to wtedy byłoby odmalowanie części danej ekranu, gdzie był on przed chwilą. Jestem święcie przekonany, że to droga naokoło. W kodzie znajduje się nieco zbędnych rzeczy, na które proszę nie zwracać uwagi - to forma pewnych wskazówek dla mnie. Plik main.cpp: #include <SFML/Graphics.hpp> #include <SFML/Window.hpp>
#include <iostream>
#include "hero.hpp"
using namespace std; using namespace sf;
int main() { RenderWindow RW( VideoMode( 800, 600, 32 ), "SFML test" ); RW.Clear( Color( 0, 255, 0 ) ); HeroesVector Heroes; Hero MainHero(( string ) "Main",( string ) "./k1.png" ), Hero2(( string ) "Evil",( string ) "./k2.png", 700, 500 ); while( RW.IsOpened() ) { Event Ev; while( RW.GetEvent( Ev ) ) { if( Ev.Type == Event::KeyPressed && Ev.Key.Code == 256 ) return 0; if( Ev.Type == Event::KeyPressed ) { if( Ev.Key.Code == sf::Key::Down ) MainHero.Down( 10 ); if( Ev.Key.Code == sf::Key::Up ) MainHero.Up( 10 ); if( Ev.Key.Code == sf::Key::Left ) MainHero.Left( 10 ); if( Ev.Key.Code == sf::Key::Right ) MainHero.Right( 10 ); MainHero.RefreshLocation(); RW.Draw( MainHero.GetSprite() ); } } RW.Display(); } }
Plik Hero.hpp #ifndef HERO_HPP_INCLUDED #define HERO_HPP_INCLUDED
using namespace std; using namespace sf;
class Hero { string name; Image image; Sprite sprite; int x, y, speed, xmove, ymove; bool CanBeOutside; Hero(); public: Hero( string name, string path, int x = 0, int y = 0 ); void SetOutsidePossibility( bool IsPossible ); void SetSpeed( int NewSpeed ); void MoveTo( int newx, int newy ); void Up( int pos ); void Down( int pos ); void Left( int pos ); void Right( int pos ); void RefreshLocation(); Sprite & GetSprite(); };
typedef vector < Hero > HeroesVector;
#endif
Plik Hero.cpp #include <SFML/Graphics/Sprite.hpp> #include <SFML/Graphics/Image.hpp>
#include <iostream> #include <vector>
#include "hero.hpp"
using namespace std; using namespace sf;
Hero::Hero() { }
Hero::Hero( string name, string path, int x, int y ) : name( name ) , x( x ) , y( y ) { image.LoadFromFile( path ); sprite.SetImage( image ); sprite.SetPosition( x, y ); speed = 1; CanBeOutside = false; }
void Hero::SetOutsidePossibility( bool IsPossible ) { CanBeOutside = IsPossible; }
void Hero::SetSpeed( int NewSpeed ) { speed = NewSpeed; }
void Hero::MoveTo( int newx, int newy ) { x = newx; y = newy; }
void Hero::Up( int pos ) { y -= pos; if( y < 0 ) y = 0; }
void Hero::Down( int pos ) { y += pos; if( y > 600 ) y = 600; }
void Hero::Left( int pos ) { x -= pos; if( x < 0 ) x = 0; }
void Hero::Right( int pos ) { x += pos; if( x > 800 ) x = 800; }
void Hero::RefreshLocation() { sprite.SetPosition( x, y ); }
Sprite & Hero::GetSprite() { return sprite; }
typedef vector < Hero > HeroesVector;
Jakie macie sugestie poza skopiowaniem i skompilowaniem kodu DejaVu :D ? |
|
SeaMonster131 |
» 2013-01-28 17:19:26 Jako że nie wysiliłem się i nie skopiowałem kodu DejaVu, [...] Nie lubię kopiuj-wklej, za to wszelkie próby i modyfikacje jak najbardziej, dlatego cudaczę. |
Taką postawę lubię i pochwalam! :) A co do problemu - pewnie nie czyścisz ekranu w pętli gry, a powinieneś. // edit: Okno renderujące grafikę |
|
crash Temat założony przez niniejszego użytkownika |
» 2013-01-28 18:00:41 Jesteś wielki FireMonster@ ! Pomogło. Zaraz przed:
RW.Draw( MainHero.GetSprite() );
Zapodałem RW.Clear( Color( 0, 255, 0 ) ); i działa jak człowiek. Najlepsze są najprostsze rozwiązania... Odnośnie jeszcze mam małe pytanie początkującego. W moim przypadku scena jest zielona i jest tylko jeden sprajt. Jak rozumiem gdy sprajtów będzie więcej, będą przeszkody, nie wiem - chmurki, cokolwiek, to w pętli należy je odrysowywać wszystkie. A czy rozwiązanie polegające na kopiowaniu niewielkich wycinków ekranu i własnoręcznym odświeżaniu tylko tych fragmentów, które się zmieniają gdy reszta sceny "stoi" w miejscu, jest dobrą techniką? Wydaje mi się, że nie i wiem, że przekonałbym się po prostu to pisząc, nie mniej wolę zapytać o opinię ;) |
|
RazzorFlame |
» 2013-01-29 18:55:05 BTW. On ma nick SeaMonster131 O co ci chodzi... Chcesz żeby po sprajcie zostawał taki ślad który daje efekt przyspieszenia czy cos? Tak jak w grze Exit Path? |
|
crash Temat założony przez niniejszego użytkownika |
» 2013-01-29 23:52:16 Widzę, jaki ma nick.
RazzorShame@ chcę maksymalnej prędkości gry dla wielu małych nieustannie animowanych naraz sprite'ów, stąd takie dywagacje z pominięciem odświeżania całego ekranu. Podsunąłeś mi ciekawą myśl, którą spróbuję zaimplementować w swoim czasie.
PS: apropos Twojego postu o funkcje trygonometryczne z innego tematu, mój nauczyciel trylion lat temu w liceum rzekł taki oto wierszyk:
"W pierwszej ćwiartce wszystkie funkcje są dodatnie, w drugiej tylko sinus. W trzeciej tangens i cotangens, a w czwartej cosinus".
Miał, cholera, rację :D Pierwsza ćw. to ta, gdzie (x++,y++), druga gdzie (x++,y--), trzecia (x--, y--), czwarta (x--, y++). Dobrze znać tę własność wymienionych funkcji. |
|
RazzorFlame |
» 2013-01-30 20:09:58 Hmm, coś mi mówi że sf::View może zdziałać to co ty chcesz. Nie za bardzo się przyglądałem temu ale chyba można mieć wiele "view'ów" i na każdym coś wyświetlać :P
EDIT: I JAKI RAZZORSHAME! XD troche mnie to irytuje jak zmieniasz nazwy nicków :P
EDIT: I moje "coś mi mówisie" dobrze radziło. Klasa sf::RenderTarget (którą dziedziczy sf::RenderWindow) posiada metodę SetView. Chyba tym coś zdziałasz o ile sie nie myle :P |
|
crash Temat założony przez niniejszego użytkownika |
» 2013-02-01 18:23:50 Kupiłem dwa zeszyty, jeden na notatki co mi ślina przeleje na klawiaturę, a drugi na spis metod klas z dokumentacji, żeby szybciej ogarnąć w zeszycie niż w trylionie zakładek. Tak więc nauka SFML ostro.
Poczytam o klasach, które wspomniałeś. Pewnie znów wyjdzie na to, że kod konstruowałem naokoło, wymyślając koło na nowo, sprowadzając go dodatkowo do kwadratury :) Dziękuję za uwagi Razzor@
offtop mode on:
Idę przez życie z humorem kompletnie bez spiny, czego m.in wyrazem jest zmiana nicków i to nie tylko na tym forum ;) Luzuj chłopak, ciesz się, żem nie troll, hehe |
|
RazzorFlame |
» 2013-02-12 17:52:43 Skoro nie zamkneleś tematu, to pozwole sobie zacytować twoją wypowiedź: chcę maksymalnej prędkości gry dla wielu małych nieustannie animowanych naraz sprite'ów |
Otóż może nie wiesz, ale ja spotkałem się z takim choby błędem. Nie jest to błąd w kodzie czy coś, ale przez nieumiejętność pisania, zauważyłem że wiele osób pisze lub pisało (np. ja) w taki sposób że do każdego obiektu jest dodawany obiekt sf::Image - BŁĄD! - Pomyśl sobie że jako obiekt chcesz żeby był jakiś kafelek w map edytorze, czy co tam. W grze zapewne nie będzie do 50 kafelków, mało co się spotyka kilka tysięcy kafelków, a średnio kilkadziesiąt/kilkaset tysięcy kafelków (w bardziej rozbudowanych grach). Pomyśl sobie ile czasu zajmie wczytanie kilkudziesięciu/kilkuset tysięcy kafelków (a raczej ich obrazków) do bufora sf::Image! Otóż można to załatwić bardzo łatwo. Jako że sf::Sprite zawiera tylko wskaźnik (czyli sam adres) pixeli z sf::Image które sie podaje w "SetImage" zajmuje on bardzo bardzo mało. Tak więc można spokojnie zrobić tak: class Creature { public: sf::Sprite mSprite; int x, y, w, h; string name; void LoadFromImage( sf::Image & ); };
class Hero : public Creature { public: InventorySlot invSlots[ 8 ]; };
class Monster : public Creature { public: std::vector < string > odglosy; void wydajOdglos(); };
Jak widzisz w każdym jest tylko sf::Sprite, a reszta jest nie potrzebna :) |
|
« 1 » |