Błąd widoczny w załączniku. Zatrzymuje się program w miejscu gdzie chce załadować obrazek do pola (z innej klasy).
Czy przypadkiem to ładowanie nie wepchnąłeś do konstruktora TForm1
?
Witam,
Mój samochód nie działa.
Pozdrawiam.
Twój post mówi mniej-więcej tyle samo, co mój.
Na oko null pointer exception. Zapewne twoje pole
w Form1 nie ma nadanej wartości.
btw @xavi_sof wiesz ze BCB 6 jest pewnie starsze od ciebie? :D
http://4programmers.net/Pomoc/Forum_dyskusyjne/Dlaczego_nikt_nie_odpowiada_w_moim_w%C4%85tku
najwyraźniej to się powinno nazywać "dlaczego każdy odpowiada w moim wątku" :/
Załączam kod:
Logika.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Logika.h"
#include "Unit1.h"
#include "Unit2.h"
#include "Unit3.h"
#include "Unit4.h"
#include "Unit6.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
Logika::Logika()
{
//przypisanie poczatkowych wartosci 'n'
for(int i=1; i<10; i++){
this->p[i]='n';
}
//kto rozpoczyna
this->kto='o';
//wynik poczatkowy
this->wynik_kolko=0;
this->wynik_krzyzyk=0;
//do ilu gramy
this->do_ilu_gramy=2;
};
Logika::~Logika(){}
//ustawianie jakiegos pola na kolko lub krzyzyk
void Logika::ustawPole(int ktore, char jak){
this->p[ktore]=jak;
}
//ustawianie kto wykonuje teraz ruch
void Logika::ustawKto(char i){
this->kto=i;
}
//dodaj punkt do wyniku kolka
void Logika::dodajPunktKolko(){
this->wynik_kolko++;
Form1->kolko_w->Caption=IntToStr(this->wynik_kolko);
}
//dodaj punkt do wyniku krzyzyka
void Logika::dodajPunktKrzyzyk(){
this->wynik_krzyzyk++;
Form1->krzyzyk_w->Caption=IntToStr(this->wynik_krzyzyk);
}
//ustaw do ilu gramy
void Logika::ustawDoIluGramy(int i){
this->do_ilu_gramy=i;
}
//stworzenie nowej gry
void Logika::nowaGra(){
Form1->pole1->Picture->LoadFromFile("img/nic.bmp");
Form1->pole2->Picture->LoadFromFile("img/nic.bmp");
Form1->pole3->Picture->LoadFromFile("img/nic.bmp");
Form1->pole4->Picture->LoadFromFile("img/nic.bmp");
Form1->pole5->Picture->LoadFromFile("img/nic.bmp");
Form1->pole6->Picture->LoadFromFile("img/nic.bmp");
Form1->pole7->Picture->LoadFromFile("img/nic.bmp");
Form1->pole8->Picture->LoadFromFile("img/nic.bmp");
Form1->pole9->Picture->LoadFromFile("img/nic.bmp");
Form1->tura->Picture->LoadFromFile("img/osmall.bmp");
for(int i=1; i<10; i++){
this->p[i]='n';
}
kto='o';
Form1->pole1->Enabled = true;
Form1->pole2->Enabled = true;
Form1->pole3->Enabled = true;
Form1->pole4->Enabled = true;
Form1->pole5->Enabled = true;
Form1->pole6->Enabled = true;
Form1->pole7->Enabled = true;
Form1->pole8->Enabled = true;
Form1->pole9->Enabled = true;
}
void Logika::sprawdzWygrana(char i){
//sprawdzenie tylko dla kolka
if(i=='o'){
if(this->wynik_kolko==this->do_ilu_gramy){
//informacja ze ktos wygral caly pojedynek
Application->MessageBox("WYGRYWA KÓŁKO", "KONIEC GRY", MB_OK | MB_ICONWARNING);
//uruchomienie nowej gry
this->nowaGra();
//reset wynikow
this->wynik_kolko=0;
this->wynik_krzyzyk=0;
Form1->kolko_w->Caption=IntToStr(wynik_kolko);
Form1->krzyzyk_w->Caption=IntToStr(wynik_krzyzyk);
//Form1->Visible=false;
//Form2->Visible=true;
//return;
}
//koniec rundy, wygrywa kolko
Application->MessageBox("Wygrywa kółko!", "Koniec rundy", MB_OK);
//nowa runda-gra
this->nowaGra();
}
//sprawdzenie tylko dla krzyzyka
if(i=='x'){
if(this->wynik_krzyzyk==this->do_ilu_gramy){
//informacja ze ktos wygral caly pojedynek
Application->MessageBox("WYGRYWA KRZYŻYK", "KONIEC GRY", MB_OK | MB_ICONWARNING);
//uruchomienie nowej gry
this->nowaGra();
//reset wynikow
this->wynik_kolko=0;
this->wynik_krzyzyk=0;
Form1->kolko_w->Caption=IntToStr(this->wynik_kolko);
Form1->krzyzyk_w->Caption=IntToStr(this->wynik_krzyzyk);
//Form1->Visible=false;
//Form2->Visible=true;
//return;
}
//koniec rundy, wygrywa krzyzyk
Application->MessageBox("Wygrywa krzyżyk!", "Koniec rundy", MB_OK);
//nowa runda-gra
this->nowaGra();
}
}
//sprawdzanie czy kto wygrał
void Logika::sprawdzPunkt(){
//szukam 3 kolek lub 3 krzyzykow w odpowiednim ulozeniu
if((this->p[1]==this->p[2] && this->p[2]==this->p[3] && this->p[1]!='n') ||
(this->p[4]==this->p[5] && this->p[5]==this->p[6] && this->p[4]!='n') ||
(this->p[7]==this->p[8] && this->p[8]==this->p[9] && this->p[7]!='n') ||
(this->p[1]==this->p[4] && this->p[4]==this->p[7] && this->p[7]!='n') ||
(this->p[2]==this->p[5] && this->p[5]==this->p[8] && this->p[2]!='n') ||
(this->p[3]==this->p[6] && this->p[6]==this->p[9] && this->p[3]!='n') ||
(this->p[1]==this->p[5] && this->p[5]==this->p[9] && this->p[1]!='n') ||
(this->p[3]==this->p[5] && this->p[5]==this->p[7] && this->p[3]!='n'))
{
//JEZELI WYGRALO KOLKO
if (kto=='x') {
//dodaje punkt
this->dodajPunktKolko();
//sprawdzam czy KOLKO wygralo caly pojedynek
this->sprawdzWygrana('o');
}else {
//CZYLI WYGRAL KRZYZYK
//dodaje punkt
this->dodajPunktKrzyzyk();
//sprawdzam czy KRZYZYK wygral caly pojedynek
this->sprawdzWygrana('x');
}
}else{
//SPRAWDZAM CZY JEST REMIS
if(p[1]!='n' && p[2]!='n' && p[3]!='n' && p[4]!='n' && p[5]!='n' && p[6]!='n' && p[7]!='n' && p[8]!='n' && p[9]!='n'){
Application->MessageBox("Nikt nie wygrał", "Koniec rundy", MB_OK);
this->nowaGra();
}
}
}
//zaznaczenie pola krzyzykiem albo kolkiem
void Logika::zaznaczPole(int i){
//sprawdzam w ogole moge zaznaczyc to pole
if(this->p[i]=='n')
{
//sprawdzam kogo jest tura
if(this->kto=='o')
{
//zmieniam obrazek pola
Form1->pole1->Picture->LoadFromFile("img/o.bmp");
//ustawiam odpowiednia zmienna
this->ustawPole(i,'o');
//ustawiam kto teraz bedzie wykonywal ruch
this->ustawKto('x');
//zmieniam obrazek kto bedzie wykonywal ruch
Form1->tura->Picture->LoadFromFile("img/xsmall.bmp");
}
else
{
//zmieniam obrazek pola
Form1->pole1->Picture->LoadFromFile("img/x.bmp");
//ustawiam odpowiednia zmienna
this->ustawPole(i,'x');
//ustawiam kto teraz bedzie wykonywal ruch
this->ustawKto('o');
//zmieniam obrazek kto bedzie wykonywal ruch
Form1->tura->Picture->LoadFromFile("img/osmall.bmp");
}
//wylaczam to pole z uzywania
Form1->pole1->Enabled=false;
//sprawdzam komu przyznac ew. punkt jezeli ktos juz wygral
this->sprawdzPunkt();
}
}
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Unit2.h"
#include "Unit3.h"
#include "Unit4.h"
#include "Logika.h"
#include "Logika.cpp"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
/*void nowa_gra();
char p1,p2,p3,p4,p5,p6,p7,p8,p9;
//p1..p9 pola w grze (ich zawartosc: p1='n'; nic lub 'x' lub 'o' )
char kto;
int wynik_kolko=0, wynik_krzyzyk=0;
int do_ilu_gramy = 2; */
/*void sprawdz()
{
if((p1==p2 && p2==p3 && p1!='n') ||
(p4==p5 && p5==p6 && p4!='n') ||
(p7==p8 && p8==p9 && p7!='n') ||
(p1==p4 && p4==p7 && p7!='n') ||
(p2==p5 && p5==p8 && p2!='n') ||
(p3==p6 && p6==p9 && p3!='n') ||
(p1==p5 && p5==p9 && p1!='n') ||
(p3==p5 && p5==p7 && p3!='n'))
{
char * w;
if (kto=='x') {
wynik_kolko++;
Form1->kolko_w->Caption=IntToStr(wynik_kolko);
if(wynik_kolko==do_ilu_gramy){
Application->MessageBox("WYGRYWA KÓŁKO", "KONIEC GRY", MB_OK | MB_ICONWARNING);
nowa_gra();
wynik_kolko=0;
wynik_krzyzyk=0;
Form1->kolko_w->Caption=IntToStr(wynik_kolko);
Form1->krzyzyk_w->Caption=IntToStr(wynik_krzyzyk);
Form1->Visible=false;
Form2->Visible=true;
return;
}
Application->MessageBox("Wygrywa kółko!", "Koniec rundy", MB_OK);
nowa_gra();
}else {
wynik_krzyzyk++;
Form1->krzyzyk_w->Caption=IntToStr(wynik_krzyzyk);
if(wynik_krzyzyk==do_ilu_gramy){
Application->MessageBox("WYGRYWA KRZYŻYK", "KONIEC GRY", MB_OK | MB_ICONWARNING);
nowa_gra();
wynik_kolko=0;
wynik_krzyzyk=0;
Form1->kolko_w->Caption=IntToStr(wynik_kolko);
Form1->krzyzyk_w->Caption=IntToStr(wynik_krzyzyk);
Form1->Visible=false;
Form2->Visible=true;
return;
}
Application->MessageBox("Wygrywa krzyżyk!", "Koniec rundy", MB_OK);
nowa_gra();
}
}else{
if(p1!='n' && p2!='n' && p3!='n' && p4!='n' && p5!='n' && p6!='n' && p7!='n' && p8!='n' && p9!='n'){
Application->MessageBox("Nikt nie wygrał", "Koniec rundy", MB_OK);
nowa_gra();
}
}
}*/
/*void nowa_gra(){
Form1->pole1->Picture->LoadFromFile("img/nic.bmp");
Form1->pole2->Picture->LoadFromFile("img/nic.bmp");
Form1->pole3->Picture->LoadFromFile("img/nic.bmp");
Form1->pole4->Picture->LoadFromFile("img/nic.bmp");
Form1->pole5->Picture->LoadFromFile("img/nic.bmp");
Form1->pole6->Picture->LoadFromFile("img/nic.bmp");
Form1->pole7->Picture->LoadFromFile("img/nic.bmp");
Form1->pole8->Picture->LoadFromFile("img/nic.bmp");
Form1->pole9->Picture->LoadFromFile("img/nic.bmp");
Form1->tura->Picture->LoadFromFile("img/osmall.bmp");
p1='n'; p4='n'; p7='n';
p2='n'; p5='n'; p8='n';
p3='n'; p6='n'; p9='n';
kto='o';
Form1->pole1->Enabled = true;
Form1->pole2->Enabled = true;
Form1->pole3->Enabled = true;
Form1->pole4->Enabled = true;
Form1->pole5->Enabled = true;
Form1->pole6->Enabled = true;
Form1->pole7->Enabled = true;
Form1->pole8->Enabled = true;
Form1->pole9->Enabled = true;
}*/
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Logika gra;
gra.nowaGra();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::pole1Click(TObject *Sender)
{
;
}
//---------------------------------------------------------------------------
Logika.h
//---------------------------------------------------------------------------
#ifndef LogikaH
#define LogikaH
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
class Logika{
private:
char p[9], kto;
int wynik_kolko, wynik_krzyzyk, do_ilu_gramy;
public:
Logika();
~Logika();
void ustawPole(int ktore, char jak);
void ustawKto(char i);
void dodajPunktKolko();
void dodajPunktKrzyzyk();
void ustawDoIluGramy(int i);
void nowaGra();
void sprawdzPunkt();
void sprawdzWygrana(char i);
void zaznaczPole(int i);
};
#endif
Unit1.h
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include "Logika.h"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
TImage *pole1;
TImage *pole2;
TImage *pole3;
TImage *pole4;
TImage *pole5;
TImage *pole6;
TImage *pole7;
TImage *pole8;
TImage *pole9;
TLabel *Label1;
TImage *tura;
TLabel *Label2;
TLabel *Label3;
TLabel *kolko_w;
TLabel *Label5;
TLabel *krzyzyk_w;
void __fastcall FormCreate(TObject *Sender);
void __fastcall pole1Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
To gdzie mogę użyć tej funkcji nowaGra(), jeżeli nie w konstruktorze? Użyłem jej w momencie kliknięcia przycisku w innej Form (oknie). Lecz teraz jest problemz przesłaniem stworzonego obiektu i wykonywaniu na nim funkcji... Trochę się to skomplikowane robi. Jakaś rada dla beginnera?
To jest efekt zgubnego działania zmiennych globalnych - masz jedną a już nie panujesz:
- w Logika.h:
...
class TForm1;
class Logika{
private:
TForm1 *Form1;
...
public:
Logika(TForm1 *Form1);
...
- w Logika.cpp:
...
Logika::Logika(TForm1 *Form1):Form1(Form1)
{
...
- w Unit1.h:
...
Logika gra(this);
...
- Jeżeli stworzyłem sobie obiekt "Logika gra" w klasie Unit2.h jako publiczne pole.
- I teraz we wszystkich innych klasach itp odwołuje się do niego Form2->gra.jakasfunkcja()
- To jest to mega niepoprawne?
- Bzdura, bo z samej nazwy
Form2
- to każdy idiota będzie wiedział co to takiego i z czym to się je. - Bzdura, bo niby czemu logika ma być zależna od jakieś tam formy?
- Zorganizuj jakiś singleton (lub coś podobnego) albo zwyczajnie użyj ten sam mechanizm co już ma Builder - te głupie zmienne globalne Form1, Form2 itd (pamiętaj że to bardzo zła praktyka)
_13th_Dragon napisał(a):
Zorganizuj jakiś singleton (lub coś podobnego) albo zwyczajnie użyj ten sam mechanizm co już ma Builder - te głupie zmienne globalne Form1, Form2 itd (pamiętaj że to bardzo zła praktyka)
Ja bym po prostu zamiast używania zmiennych globalnych jak piszesz zrobił to w ten sposób, że wskaźnik na obiekt logiki przekazał w konstruktorze do formatki. A tam można już sobie trzymać jako zmienna prywatna.