TImage nie znika po ustawieniu Visible

TImage nie znika po ustawieniu Visible
blaCkCaer
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 3 lata
  • Postów:9
0

Wszystkie pliki, screeny z debuggera, film z problemem na dysku gogle
Witam
Tworzę w builderze arkanoida, na początku tworzy obiekt figure i tworzy za pomocą jego metod taką odwróconą piramidkę z bloczków które mamy trafić.
W timerze mam pętlę która sprawdza po kolei wszystkie bloki (wskaźniki do TImage zawarte w vectorze utworzonym wraz z obiektem figure) czy ich Visible==true, potem czy piłka się od któregoś odbije, a następnie jeśli piłka dotknęła którejś ściany bloku to ustawia jego Visible na false (funkcja collReflex używa funkcji wallcheck, więc jeśli jedna się "uaktywni" to druga na pewno też, sprawdzałem to).
Gdy uruchamiam grę (żadnych warningów ani errorów od kompilatora) wszystko jest dobrze, piłka spada, przegrywam, uruchamia się funkcja reset() i gram od nowa.
Za drugim razem czasami (na oko w 70% przypadków) trafiam jakiś blok, piłka się odbija,** jego Visible ustawiane jest na false a blok nie znika.**
Następnie gdy piłka "wleci" w ten blok to przeleci pod nim bez odbicia i trafi następne bloki które zachowają się tak samo.
Blok nie znika pomimo, że na pewno ma ustawione Visible na false, po linijce która to ustawiała wstawiłem ifa który to potwierdził
if(figure->blocks[i]->Visible==false) { Label2->Caption=i;}
oraz sprawdziłem w debuggerze (screeny załączę, w okienku do poglądania zmiennych widać że block[9] visible=false) oraz, żeby było ciekawiej, dla tego bloku wykonuje się później warunek
if(figure->blocks[i]->Visible==true jednak mimo to piłka od tego bloku widmo się nie odbija choć jest wystarczająco blisko.
Nie mam pojęcia o co chodzi, poniżej fragmenty kodu z paroma objaśnieniami

Fragment z timera w głównym pliku, timer porusza obiektem ball i sprawdza kolizje z blokami

Kopiuj
void __fastcall TForm1::ruchTimer(TObject *Sender)
{
//    [CODE]

for(unsigned int i=0;i<figure->num_blocks();i++)
{

if(figure->blocks[i]->Visible==true)                            //ten warunek czasami potrafi się wykonać nawet na bloku którego visible==false
{
        collReflex(figure->blocks[i],ball,x,y,0,wallcheck::out);          // "sprawdź czy blocks[i] jest blisko, sprawdź z której strony bloku i w odpowiedni sposób go odbij"

        if(wallCheck(figure->blocks[i],ball,0,wallcheck::out)!=wallcheck::none)       //jeśli ball nie nie dotyka żadnej ściany blocks[i] (ściana != none) to:
        {
                figure->blocks[i]->Visible=false;                                 //za każdym razem gdy powinien, warunek przepuszcza tutaj kompilator, visible jest zmieniane na false 
                got_hit++;                                                                  //ilość trafionych bloków
                if(figure->blocks[i]->Visible==false)                           //ten warunek zawsze się spełnia wtedy kiedy powinien (bo blok faktycznie został trafiony), jednak ja nadal widzę ten blok
                {Label1->Caption="true"; Label2->Caption=i;}         //drugi caption widać na filmie który też wrzucę tu gdzieś, aby mieć pewność że o ten blok chodzi
                break;
        }
}
}
if(got_hit==figure->num_blocks())
win();
}

Funkcja restart()( która może mieć znaczenie bo przed jej drugim wywołaniem działa poprawnie, pierwsze wywołanie w konstruktorze TForm1, drugie po pierwszej przegranej )

Kopiuj
void restart()
{  delete figure;                                             //ustawione na wszelki wypadek, bo naprawdę już nie wiem co robię źle
   figure=new Figure(Form1,BRICKBMP);      // w pliku nagłówkowym głównego pliku znajduje się deklaracja   Figure * figure;   oraz  #include "SetFigure.h" który załączę poniżej
   figure->set_figure(Form1,Figure::pyramid,3);       //utwórz odwróconą piramidę która ma 3 piętra w Form1 

  //[CODE]  bez znaczenia, ustawianie pozycji ball i paddle
   got_hit=0;

}

SetFigure.h - plik nagłówkowy klasy Figure, załączę kod w całości

Kopiuj
class Figure
{
private:
String BLOCKBMP;               //set_bmp_file(String)
TForm* parent_form;
unsigned int numBlocks;        //num_blocks()
unsigned int levels;                //get_lvls()
unsigned int bmp_width;        //get_bmp_width()
unsigned int bmp_height;      //get_bmp_height()
bool defPosChanged;           //control
bool bmp_changed;             //control
int startTop;                          //
int startLeft;                          //
int between_hor;                 //get_between_hor()
int between_ver;            //get_between_ver()


public:
std::vector <TImage*> blocks;      //vector contains all the blocks in figure

enum choose {pyramid=0 };

//constructor:

Figure(TForm*,String);

//public methods:

unsigned int num_blocks();     //returning number of blocks in figure

unsigned int get_lvls();

unsigned int get_between_hor();

unsigned int get_between_ver();

unsigned int get_bmp_width();

unsigned int get_bmp_height();

void set_bmp_file(String);

void set_block(TImage *,TForm*);

void create_inv_pyr(TForm*);

void set_figure(TForm*,enum choose=pyramid,unsigned int=3);  



};

Plik źródłowy klasy Figure (cały oprócz prostych metod, typu get_jakaśwartość)

Kopiuj
//contructor:
Figure::Figure(TForm* parent,String bmpfile)
{
 this->parent_form=parent;
 set_bmp_file(bmpfile);
 defPosChanged=false;
 bmp_changed=true;

}

void Figure::set_bmp_file(String path)
{
 BLOCKBMP=path;
 bmp_changed=true;
}

void Figure::set_block(TImage * block,TForm* parent_form)          //funkcja pomocnicza, ustawia podstawowe parametry każdego bloku z osobna, pozycja jest ustalana później
{


    block->Parent=parent_form;
    block->Picture->LoadFromFile(BLOCKBMP);
    block->Visible=true;
    block->AutoSize=true;
    block->Transparent=true;
    block->Enabled=true;

}


void Figure::create_inv_pyr(TForm* parent_form)   // lvls- levels of pyramid
{

 numBlocks=(levels*(levels+1));
 blocks.reserve(num_blocks());


 for(unsigned int i=0;i<num_blocks();i++)
 {
        blocks.insert(blocks.begin()+i,new TImage(parent_form));
        set_block(blocks[i],parent_form);
 }

 unsigned int num=0;
 
 for(unsigned int i=get_lvls();i>0;i--)    //ustawianie pozycji bloków, funkcja notmin() to zwraca po prostu wartość bezwględną, static cast ze względu na unsigned int
 {                                                         // tak, wiem że wystarczyłoby notmin<int>() ale to chyba rzutowanie niejawne a to podobno nieładnie
        for(unsigned int j=(i*2);j>0;j--)                                                
                {
                 blocks[num]->Top=startTop+(get_between_ver()+get_bmp_height())*somth::notmin<int>(static_cast<unsigned int>(i)-static_cast<unsigned int>(get_lvls()));
                 blocks[num]->Left=startLeft+(get_between_hor()+get_bmp_width())*somth::notmin<int>(static_cast<unsigned int>(j)-static_cast<unsigned int>(i)*2)+get_bmp_width()*somth::notmin<int>(static_cast<unsigned int>(i)-static_cast<unsigned int>(get_lvls()));
                 num++;
                }

 }

}


void Figure::set_figure(TForm* parent_form, enum choose choice,unsigned int lvls)              //w tej funkcji wybierasz jedną z figur, na razie jest tylko piramida
{
 levels=lvls;

     if(bmp_changed==true)              //jeśli wywołasz funkcję  set_bmp_file() (czyli zmienisz podaną w konstruktorze ścieżke do grafiki) to zmierz jej wielkość na nowo
    {
    TImage * block=new TImage(parent_form);
    block->Parent=parent_form;
    block->Picture->LoadFromFile(BLOCKBMP);
    block->AutoSize=true;
    
    bmp_width=block->Width;
    bmp_height=block->Height;
    bmp_changed=false;
    delete block;
    }

 switch(choice)
 {
 case 0:                                      //pyramid

         if(defPosChanged==false)
         {                                 //setting defaults                    jeśli ustawisz jakieś  swoje wartości to raczej nie chcesz aby funkcja ponownie ustawiła ci defaultowe, po to jest ten if
                between_hor=5;
                between_ver=5;
                startTop=parent_form->Height/16;
                startLeft=parent_form->Width/2-get_lvls()*get_bmp_width()-get_between_hor()*get_lvls()+get_between_hor()/2;
                defPosChanged=true;
                
         }
         create_inv_pyr(parent_form);
         break;
 default:
         ShowMessage("Error in choosing right figure");
         break;

 }
}


Proszę, nie zapominajcie o średnikach po klasie..
edytowany 1x, ostatnio: blaCkCaer
blaCkCaer
Mógłby ktoś napisac jak się włącza kolorowanie składni? bo coś sposób podany przy pisaniu tego mi nie chce działać.. a z pewnością by się przyjemniej czytało
_13th_Dragon
```cpp <Enter> twój kod <Enter>```
CL
  • Rejestracja:ponad 15 lat
  • Ostatnio:7 miesięcy
1
  1. Nie piszę w C++
  2. Bez analizy kodu po odpaleniu gierki widać że wszystko działa w sensie znika co ma znikać. Po restarcie natomiast nie usuwasz pozostałych bloków tylko nadpisujesz nowe. Daje to efekt jakby cześć bloków nie znikała.
  3. Po analizie kodu (nie piszę w C++) block->Parent=parent_form; dla bloku ustalasz rodzica jako formatkę. Jeśli kasujesz delete figure; to dla mnie nie usuwa to pozostałych bloków. Żeby to potwierdzić możesz po restarcie nadać nowym blokom inny kolor (np. załadować inną bitmapę albo jakoś je wyróżnić). Trzeba pewnie pousuwać bloki w pętli po restarcie albo przypisać jako rodzica figure i wtedy przy zwalnianiu może tez pousuwa bloki.
blaCkCaer
  • Rejestracja:ponad 4 lata
  • Ostatnio:ponad 3 lata
  • Postów:9
0

@Clarc: Parent może być tylko TFormem, bo nie chciało mi działać jak podmieniłem, ale faktycznie miałeś rację z tym co się dzieje. Napisałem destruktor dla Figure z pętlą usuwającą wszystkie elementy vectora z TImage od bloków i teraz wszystko śmiga, zapomniałem o nim wcześniej, miałem przeświadczenie że delete samo usunie wszystko co z obiektem związane. Dzięki za pomoc


Proszę, nie zapominajcie o średnikach po klasie..
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)