Lazarus 2.2.0 RC1 (2021.02.21.)
Letöltés

  • Oldal:
  • 1
  • 2
  • 3

TÉMA:

Egy kezdő Lazarus használó kérdései 2015 dec. 23 18:13 #1730

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
És az miért van, hogy írtam egy saját eljárást (procedure), amit annak rendje s módja szerint előre deklaráltam az interface részben, majd kidolgoztam az implementation részben a többi fölött, működik is, de olyan változókat nem tudok benne elérni, mint pl. a ClientWidth, vagy éppen a TFoAblak.Caption, mert ha ezeket használnám, akkor a következő hibaüzenetet kapom:
unit1.pas(62,5) Error: Only class methods, class properties and class variables can be referred with class references

Egy kezdő Lazarus használó kérdései 2015 dec. 21 17:48 #1729

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 472
  • Köszönetek: 80
Ez a hibaüzenet arra a sorra vonatkozik ahol a deklaráció van, hiszen az nincs kidolgozva később.
Valószínűleg nem jó a kidolgozás fejléce, például lefelejtetted a kidolgozásnál az osztály-előtagot, esetleg procedure helyett function van vagy ilyesmi...
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64
Megköszönték: Tomi

Egy kezdő Lazarus használó kérdései 2015 dec. 21 17:37 #1728

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
És ezt a hibaüzenetet miért kapom?
unit1.pas(20,15) Error: Forward declaration not solved "TFoAblak.ellensegkirakas;"
Hiszen ezt a saját eljárást ("ellensegkirakas") éppen abban a sorban deklarálom előzetesen, és aztán az implementation rész után részletesen megadom.
Akkor most rossz helyre írok valamit, vagy kihagytam valamit?

Egy kezdő Lazarus használó kérdései 2015 dec. 21 14:47 #1727

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
Köszi, már értem! Betettem a rajzolást az időzítéshez, és így már működik. Így viszont a Form-on TImage-ként eleve elhelyezett kép nem látszik, csak az elmozdulásakor, de ezt már meg tudom oldani, hogy akkor ezt is futásidőben rakom ki.

Egy kezdő Lazarus használó kérdései 2015 dec. 20 16:39 #1726

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 472
  • Köszönetek: 80
Az eseménykezelő eljárások csak és kizárólag valamely esemény bekövetkeztekor vagy "kényszer" hatására futnak le.

Az OnPaint eseménykezelő például akkor fut ha szükség van az adott elem kirajzolására vagy a programozó ezt közvetve vagy közvetlenül kéri: bizonyos műveletek következményeként a Paint metódus meghívásra kerül, ami az OnPaint eseménykezelő futását is előidézi.
A folyamatos frissítést csak időzítővel vagy valamilyen más ismétlődő ciklus (for/repeat) használatával érheted el (ez utóbbi módszert GUI alkalmazásokban nem javaslom).

Minden kirajzolást ugyanabban az időzített eljárásban végezz el. Természetesen az időzítést úgy kell beállítanod, hogy elég időt hagyj a rajzolási és számolási műveletek számára...
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64

Egy kezdő Lazarus használó kérdései 2015 dec. 20 14:05 #1725

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
A főablak, tehát a TMain-nak az OnPaint-eseményében a FormPaint használható a folyamatos kirajzoláshoz? Vagy ez mire jó? Mert ott íratom ki néhány változó értékét, de nem úgy tűnik, hogy folyamatosan frissülne az értékük...

Egy kezdő Lazarus használó kérdései 2015 dec. 16 14:54 #1722

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 472
  • Köszönetek: 80
Canvas.Clear;
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64
Megköszönték: Tomi

Egy kezdő Lazarus használó kérdései 2015 dec. 16 14:39 #1721

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
Az újrarajzoltatáshoz beírtam, hogy:
FoAblak.Canvas.Refresh;
De nem történik rá semmi... :-/

Egy kezdő Lazarus használó kérdései 2015 dec. 16 14:02 #1720

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 472
  • Köszönetek: 80
Ahhoz hogy a képernyőről is eltűnjenek a labdák az képfrissítő eljárásban újra ki kell rajzoltatnod a teljes játékteret, tehát nem csak a labdákat hanem a hátteret is.
Az objektumok megsemmisítésére használhatod a FreeAndNil() eljárást:
mbRight:
    for i:=1 to labdadb-1 do  FreeAndNil(labdatomb[i]);
... és ne felejtsd el alapra állítani a labdadb értékét.
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64

Egy kezdő Lazarus használó kérdései 2015 dec. 16 10:54 #1719

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
Hogyan kell megsemmisíteni a létrehozott objektumo(ka)t? Most úgy csinálom, hogy egy tömbbe mentem az objektumazonosítót, majd ha nem kell, akkor a nil értéket adom neki - de valamiért nem jó, mert jobb egérkattintásra még mindig mutatja a labdákat, holott erre kéne eltűnnie az összesnek. Ha odaírom, hogy destroy vagy free, az sem jó neki. Itt a teljes kód:
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls;
 
type
 
  { TFoAblak }
 
  TFoAblak = class(TForm)
    KepFrissito: TTimer;
    //procedure FormClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure KepFrissitoTimer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
type TLabda=class(TObject)
  var xhely,yhely: integer;
  kepe: TBitmap;
  private
  public
    constructor letrehoz(xhelyitt,yhelyitt: integer; kepeitt: Tbitmap);
end;
 
var
  FoAblak: TFoAblak;
  labdakep: Tbitmap;
  egylabda: TLabda;
  labdadb: integer;
  labdatomb: array [1..100] of TLabda;
 
implementation
 
{$R *.lfm}
constructor TLabda.letrehoz(xhelyitt,yhelyitt: integer; kepeitt: Tbitmap);
begin
        xhely:=xhelyitt;
        yhely:=yhelyitt;
        kepe:=kepeitt;
end;
 
{ TFoAblak }
 
{procedure TFoAblak.FormClick(Sender: TObject);
var egerhely: TPoint;
begin
      egerhely:=FoAblak.ScreenToClient(mouse.cursorpos);
      egylabda:=TLabda.letrehoz(egerhely.x,egerhely.y,labdakep);
      FoAblak.Canvas.Draw(egylabda.xhely,egylabda.yhely,egylabda.kepe);
end;  }
 
procedure TFoAblak.FormCreate(Sender: TObject);
begin
  labdakep:=TBitmap.Create;
  labdakep.LoadFromFile('labdabmp.bmp');
  labdadb:=1;
end;
 
procedure TFoAblak.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var i: integer;
begin
        case button of
          mbLeft:
        begin
          egylabda:=TLabda.letrehoz(x,y,labdakep);
          //FoAblak.Canvas.Draw(egylabda.xhely,egylabda.yhely,egylabda.kepe);
          labdatomb[labdadb]:=egylabda;
          inc(labdadb);
        end;
        mbRight:
        begin
             for i:=1 to labdadb-1 do
             begin
               labdatomb[i]:=nil;
             end;
             //labdadb:=1;
        end;
        end;
end;
 
procedure TFoAblak.KepFrissitoTimer(Sender: TObject);
var i: integer;
begin
for i:=1 to labdadb-1 do
begin
     if labdatomb[i]<>nil then
               FoAblak.Canvas.Draw(labdatomb[i].xhely,labdatomb[i].yhely,labdatomb[i].kepe);
end;
KepFrissito.Interval:=10;
end;
 
end.

Egy kezdő Lazarus használó kérdései 2015 dec. 14 16:17 #1711

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
Huhhh, végre sikerült! Köszönöm az újabb segítséget! :cheer:
Így sikerült megoldani:
procedure TFoAblak.FormClick(Sender: TObject);
var egerhely: TPoint;
begin
      egerhely:=FoAblak.ScreenToClient(mouse.cursorpos);
      egylabda:=TLabda.letrehoz(egerhely.x,egerhely.y,labdakep);
      FoAblak.Canvas.Draw(egylabda.xhely,egylabda.yhely,egylabda.kepe);
end;
Az az érdekes, hogy az egerhely változó közbeiktatása nélkül, tehát így:
egylabda:=TLabda.letrehoz(mouse.cursorpos.x,mouse.cursorpos.y,labdakep);
nem működött. Pedig mindenhol így olvastam, és nem tértek ki arra a kiegészítésre, amit írtál.

Egy kezdő Lazarus használó kérdései 2015 dec. 14 16:03 #1710

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 472
  • Köszönetek: 80
A CursorPos így érhető el: Mouse .CursosPos
Ez azonban az egérmutató képernyőn elfoglalt helyét tartalmazza, ezért át kell alakítanod az ablakhoz viszonyított koordinátára, pl így: Form1. ScreenToClient (Mouse.CursorPos);

A Mouse.CursorPos mindig az egérmutató pillanatnyi helyét tartalmazza, és nem a kattintás helyét. Az onClick esemény kezelője akkor kerül futtatásra ha a lenyomás és a felengedés is ugyanazon elem területén, de nem feltétlenül ugyanazon a ponton történik. A két esemény között (lenyomás és felengedés) az egérmutató ideiglenesen el is hagyhatja az elem területét, mint tudjuk.
Javaslom, hogy ez esetben az OnMouseDown eseménykezelőt használd
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64

Egy kezdő Lazarus használó kérdései 2015 dec. 14 15:19 #1709

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
Igen, a labda fájlneve bizonyult rossznak; köszönöm az észrevételedet. Nálad egyébként rendesen létrejön egérkattintás helyein a labda? Mert nekem csak akkor jelenik meg, ha konkrét számokat írok be a létrehozáshoz, dehát ekkor nem az egérmutatóhoz, hanem az adott koordinátákra.
Ha nem adom meg a mouse unit-ot, akkor nem csinál semmit a program (elindul, de hiába kattintgatok, labdák sehol), míg ha megadom, akkor ezek a hibaüzenetek jelennek meg:
Projekt fordítása, Cél: kepfutidoben.exe: Kilépési kód: 1, Hibák: 2
unit1.pas(50,39) Error: Identifier not found "Cursorpos"
unit1.pas(50,57) Error: Identifier not found "CursorPos"

Tehát nem ismeri a CursorPos nevű azonosítókat - de miért nem? :S

Egy kezdő Lazarus használó kérdései 2015 dec. 14 10:54 #1708

  • JohnnyK
  • JohnnyK profilkép
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 78
  • Köszönetek: 16
A programkódod nálam működik. Akkor sikerült a hibaüzenetet előidéznem, amikor elgépeltem a bmp fájl nevét, vagy nem volt az exe futtatható állománnyal egy könyvtárban.
Szerencsésebb lehet esetleg teljes útvonalakat használni, pl 'c:\valami\ballbmp.bmp', vagy használni az exe mindenkori útvonalát pl SysToUTF8(ExtractFilePath(Application.ExeName)) + 'ballbmp.bmp', noha e nélkül is működik nálam jelen esetben.

Egy kezdő Lazarus használó kérdései 2015 dec. 13 13:27 #1707

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
Most javítottam a programkódon; el is indulna, de már azt írja ki, hogy:
Unable to open file "ballbmp.bmp".
Press OK to ignore and risk data corruption.
Press Cancel to kill the program.

Ilyesmit írt ki, amikor .png volt a labda képformátuma, és most, .bmp-be átkonvertáltan is így kekeckedik. Mi lehet a baja?
Itt az egész kód a labdák megjelenítésére az egérkattintás helyére:
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;
 
type
 
  { TFoAblak }
 
  TFoAblak = class(TForm)
    procedure FormClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
type TLabda=class(TObject)
  var xhely,yhely: integer;
  kepe: TBitmap;
  private
  public
    constructor letrehoz(xhelyitt,yhelyitt: integer; kepeitt: Tbitmap);
end;
 
var
  FoAblak: TFoAblak;
  labdakep: TBitmap;
  egylabda: TLabda;
 
implementation
 
{$R *.lfm}
constructor TLabda.letrehoz(xhelyitt,yhelyitt: integer; kepeitt: Tbitmap);
begin
        xhely:=xhelyitt;
        yhely:=yhelyitt;
        kepe:=kepeitt;
end;
//end;
 
{ TFoAblak }
 
procedure TFoAblak.FormClick(Sender: TObject);
begin
      egylabda:=TLabda.letrehoz(mouse.cursorpos.x,mouse.cursorpos.y,labdakep);
      FoAblak.Canvas.Draw(egylabda.xhely,egylabda.yhely,egylabda.kepe);
end;
 
procedure TFoAblak.FormCreate(Sender: TObject);
begin
  labdakep:=TBitmap.Create;
  labdakep.LoadFromFile('ballbmp.bmp');
end;
 
end.

Egy kezdő Lazarus használó kérdései 2015 dec. 10 13:39 #1705

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
Köszi; tegnap egyébként letöltöttem a YouTube-on keresztül egy Lazarus példajátékot: egy orosz illető készítette, valami 1945-klón lenne, "Szamolet" néven. Átnézve a kódját elég sokmindent ki tudok belőle puskázni remélhetőleg. :whistle:
Ami az OOP-t illeti, azt tudom róla, hogy ellentétben a régebbi programozási nyelvek felfogásával, itt az események váltják ki a cselekvéseket és az egyes objektumok maguk gondoskodnak magukról, változóik, adataik kezeléséről, és nem mindig az egész kód pörög folyamatosan (bár lehet, nem jól fogalmazok :silly: ).
Ennek Lazarusos alkalmazásánál azt nem tudtam, hogy képek futásidejű betöltése és egy objektumhoz hozzárendelése milyen kódolást igényel és hogy mely részei milyen típusúak (pl. a képet tároló változó, aztán meg a LoadFromFile hova tölti és az is milyen típusú, stb.). Szóval volt kavarodás rendesen és még most sem tiszta minden, de bízom ebben a szerzeményben. :)
Kiegészítés: valami megint rossz;ez a kódom:
unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, mouse;
 
type
 
  { TFoAblak }
 
  TFoAblak = class(TForm)
    procedure FormClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
type TLabda=class(TObject)
  private
    xhely,yhely: integer;
    kepe: TBitmap;
  public
    constructor letrehoz(xhely0,yhely0: integer; kepe0: Tbitmap);
end;
 
var
  FoAblak: TFoAblak;
  labdakep: TBitmap;
  egylabda: TLabda;
 
implementation
 
{$R *.lfm}
constructor TLabda.letrehoz(xhely0,yhely0: integer; kepe0: Tbitmap);
begin
        xhely:=xhely0;
        yhely:=yhely0;
        kepe:=kepe0;
end;
//end;
 
{ TFoAblak }
 
procedure TFoAblak.FormClick(Sender: TObject);
begin
      egylabda:=Tlabda.letrehoz(getmousex,getmousey,labdakep);
      FoAblak.Canvas.Draw(egylabda.xhely,egylabda.yhely,egylabda.kepe);
end;
 
procedure TFoAblak.FormCreate(Sender: TObject);
begin
  labdakep:=TBitmap.Create;
  labdakep.LoadFromFile('labdabmp.bmp');
end;
 
end.
és most az a hibaüzenet egérkattintás után (merthogy a program elindulni sikeresen elindul):
External (azaz: külső) SIGSEGV osztályú kivételt okozott a 77BFD174 címen. :S

Egy kezdő Lazarus használó kérdései 2015 dec. 09 10:59 #1692

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 472
  • Köszönetek: 80
A TImage a TCustomImage lezármazottja, melynek van Picture néven TPicture típusú/osztályú tulajdonsága (property). Tehát ahová TImage kell oda a TImage típusú változót adod meg, ahová pedig TPicture oda a TImage típusú változó Picture nevű (TPicture típusú) elemét. Illetve ha TGraphic típusra van szükség oda mehet a Picture tulajdonság Graphic eleme (vagy szükség szerint a Bitmap, Icon, Jpeg, Pixmap, PNG, PNM mivel ezek mind a TGraphic leszámazottai).

Error: Incompatible type for arg no. 1: Got "TImage", expected "TPicture"
Hint: Found declaration: TCustomImage.SetPicture(const TPicture);

kep.SetPicture(masikkep.Picture);

Error: Incompatible type for arg no. 3: Got "TPicture", expected "TGraphic"
Hint: Found declaration: TCanvas.Draw(LongInt,LongInt,TGraphic);

valami.Canvas.Draw(0,0,masikkep.Picture.Graphic);

Ha megnézed a súgót vagy a használt unitok forráskódját akkor megtalálhatod a választ az ezekhez hasonló problémákra. A forráskódszerkesztőben jobb egérgombbal kattintva egy azonosítóra a "Delaráció megkeresése" lehetőség is elérhető.

Mielőtt elmegy a kedved ismerkedj meg az objektum központú programozás (OOP - Object Oriented Programming) alapjaival és az osztályok egymásba/egymásra épülésének mikéntjével is. Ezek nélkül újabb és újabb olyan problémákba ütközöl majd, melyek valójában nem azok. A világháló tele van OOP cikkekkel, nem kevés ObjectPascal témájú is akad, pl. egyik fórumtársunk (dfeher) fordításában: Objektum-orientált programozás Free Pascal-lal és Lazarus-szal
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64

Egy kezdő Lazarus használó kérdései 2015 dec. 09 09:49 #1691

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
A hibaüzeneteket nagyjából értem, csak az nem világos, hogy a TGraphic, a TPicture és a TImage hogyan épülnek egymásra, azaz ezek közül milyen típust kell megadni a képváltozó deklarálásakor, a kép létrehozásakor, a felhasználásakor...
Enélkül csak sötétben tapogatózok, mert a különböző próbálkozásaimra különböző hibaüzeneteket kapok (pl. egyik helyre a hibaüzenet alapján TPicture-t adok meg, akkor máshonnan a TImage típus fog az elvárt és hiányolt lenni, stb.).

Egy kezdő Lazarus használó kérdései 2015 dec. 09 07:53 #1688

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 472
  • Köszönetek: 80
A hibaüzenetek után tippeket (hint) is kapsz, melyek segítenek a hiba pontos okának felderítésében.

Error: Incompatible type for arg no. 1: Got "TImage", expected "TPicture"
Hint: Found declaration: TCustomImage.SetPicture(const TPicture);

Hiba: Nem megfelelő típus az 1. argumentumban: Megadva "TImage", szükséges "TPicture"
Tipp: Talált deklaráció: TCustomImage.SetPicture(const TPicture);

Az ilyen üzenetek azt jelentik, hogy az általad paraméterként átadni szándékozott változó típusa nem egyezik meg azzal amit az adott eljárás/függvény a deklarációja szerint fel tud dolgozni.

Error: identifier idents no member "LoadFromFile"

Hiba: az azonosító nem nevez meg tagot: "LoadFromFile"
Ez azt jelenti hogy az adott osztály/rekord nem rendelkezik az adott nevű taggal: mezővel, tulajdonsággal vagy metódussal.

A súgóban részletes információkat találhatsz egy-egy elemmel kapcsolatban ha a beszúrási jelet egy érvényes azonosítóra viszed és lenyomod az F1 gombot. A súgó hálózaton elérhető (aktuális) változata a "Súgó / Online súgó" menüpontra kattintva érhető el, a helyi chm változat pedig a "Súgó / Súgó" által (ha telepítve van).
E mellet az "Eszközök / Példa projektek" menüpontban is sok hasznos dologra, melyek segítenek megismerni a lehetőséget és megérteni azok használatának mikéntjét.
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64

Egy kezdő Lazarus használó kérdései 2015 dec. 08 18:30 #1685

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1
Köszönöm, a háttér most már megfelelő nagyságban rajzolódik ki.
De ami nem megy még, az a kép kirajzolása futásidőben, ugyanis ilyen hibaüzeneteket kapok:
Projekt fordítása, Cél: spdef.exe: Kilépési kód: 1, Hibák: 3, Tippek: 2
unit1.pas(63,32) Error: Incompatible type for arg no. 1: Got "TImage", expected "TPicture"
customimage.inc(69,24) Hint: Found declaration: TCustomImage.SetPicture(const TPicture);
unit1.pas(68,56) Error: Incompatible type for arg no. 3: Got "TPicture", expected "TGraphic"
canvas.inc(20,19) Hint: Found declaration: TCanvas.Draw(LongInt,LongInt,TGraphic);
unit1.pas(79,13) Error: identifier idents no member "LoadFromFile"

És így próbálok képet beolvasni, illetve hozzárendelni egy objektumhoz:
1. A FoAblak FormCreate-jében:
jatlovkep:=TImage.Create(FoAblak);
jatlovkep.LoadFromFile('kepek\lovedek.bmp');

2. A lövés eseményben:
var jatlov: TImage;
...
if (jatekoslo=true) and (jatlohet=true) then
begin
jatlov:=TImage.create(FoAblak);
jatlov.picture:=jatlovkep;
jatlov.width:=5;
jatlov.height:=10;
jatlov.Top:=Jatekos.Top-8;
jatlov.Left:=Jatekos.Left+Jatekos.Width div 2;
canvas.draw(jatlov.Left,jatlov.top,jatlov.picture);
end;

Plusz még az egész Unit1 implementation része előtt megadtam: var jatlovkep: TImage;
Már bő 2 órája bújom a netet, de nem találtam megoldást vagy példaprogramot, ami megválaszolná a kérdésemet... :angry:

Egy kezdő Lazarus használó kérdései 2015 dec. 08 10:30 #1678

  • Gábor
  • Gábor profilkép
  • Adminisztrátor
  • Adminisztrátor
  • Hozzászólások: 472
  • Köszönetek: 80
Az ablak kirajzolását szükség esetén a TForm.Paint metódus meghívásával kényszerítheted, ekkor fut a TForm.FormPaint eseménykezelő. Itt is rajzolhatsz, de ahogy lassan összeállnak a részletek inkább azt javaslom kezd elölről és e programban ne legyen saját TForm.FormPaint metódusod.

A játéktér, így a háttér, a labdák, a lövedék és a többiek kirajzolását is időzített eljárásban csináld. Amit szeretnél megjeleníteni az ablakban azt a TForm.Canvas-ra kell rajzolnod (megfelelő sorrendben: háttér először). A játéktér pillanatnyi állapotának kirajzolása után kell hívnod a TForm.Paint metódust hogy az egész megjelenjen a képernyőn.

terulet := TRect.Create(0, 0, FoAblak.Width, FoAblak.Height);
Canvas.StretchDraw(terulet, hatterkep);

Nem írtad milyen "hibát ír ki"... Hiba esetén mindig írd meg a hibaüzenetet is! Különben jó eséllyel nem tudnak segíteni akiktől ezt várod.
Ez esetben azonban biztosra veszem, hogy ez volt a hibaüzenet: identifier idents no member "Create"
Ennek az az oka, hogy a TRect nem class (osztály), hanem record aminek nincs se Create nevű mezője se metódusa. Ez utóbbi nem is lehet neki.

Így csináld:
terulet := Rect(0, 0, Width, Height);
Canvas.StretchDraw(terulet, hatterkep);
vagy még rövidebbre véve a forráskódot, inkább így:
Canvas.StretchDraw(Rect(0, 0, Width, Height), hatterkep);

... és még valami fontos: a képeket (háttér, labda, lövedék stb.) ne akkor töltsd be amikor kirajzolod, hanem a program indításakor (Pl. Form.OnCreate eseménykezelőben), különben feleslegesen terheled a gépet.
Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64

Egy kezdő Lazarus használó kérdései 2015 dec. 08 09:14 #1677

  • Tomi
  • Tomi profilkép Témaindító
  • Haladó forumozó
  • Haladó forumozó
  • Hozzászólások: 54
  • Köszönetek: 1

Kirajzoláskor (ezt amúgy is időzítővel kell/illik megoldani LCL és SDL esetén is)
  • A labda új helyének kiszámítása az irányváltozó pillanatnyi értéke alapján
  • A játéktér szükséges elemeinek kirajzolása. (pl háttér és labda/labdák az új helyre)

  • A kirajzolása a dolgoknak az ablak FormPaint eseményében van?
    Jó, hogy szóbahoztad ezt a kirajzolásos dolgot, mert most éppen próbálkozom egy űrhajós-lövöldözős játékocska készítésével Lazarusban, és az a gondom, hogy nem tudom, hol, hogyan rajzoltassam ki a futásidőben létrehozott lövedékeket (és egyéb ilyen objektumokat).
    A lövedék betöltésére ezt a kódot használom, mikor lő a játékos:
    if (jatekoslo=true) and (jatlohet=true) then
      begin
          jatlov:=TImage.create(FoAblak);
          jatlov.picture.bitmap.LoadFromFile('kepek\lovedek.bmp');
          jatlov.width:=5;
          jatlov.height:=10;
          jatlov.Top:=Jatekos.Top-8;
          jatlov.Left:=Jatekos.Left+Jatekos.Width div 2;
      end;
    Hibát nem okoz, viszont a lövedék nem látható. Gondolom, még nem rajzolódik ki - de nem tudom, ezt hol kell megoldani, melyik eseménybe rakjam? És hasonló módon kell kirajzolni, mint egy hátteret, tehát canvas.draw(jatlov) vagy picture.draw(jatlov) ?
    Meg még az a gond, hogy a hátteret nem tudom az ablak teljes méretére kiterjesztetten kirajzoltatni, ugyanis erre a kóddarabra:
    ...
    terulet := TRect.Create(0, 0, FoAblak.Width, FoAblak.Height);
    Canvas.StretchDraw(terulet, hatterkep);

    ...
    hibát ír ki.

    Egy kezdő Lazarus használó kérdései 2015 dec. 08 08:25 #1676

    • Gábor
    • Gábor profilkép
    • Adminisztrátor
    • Adminisztrátor
    • Hozzászólások: 472
    • Köszönetek: 80
    A következőkre van szükség:
    1. Billentyűlenyomás elkapásakor (LCL-ben pl. TForm.OnKeyDown)
      • Irányváltozó beállítása a kívánt irányra
    2. Billentyűfelengedés elkapásakor (LCL-ben pl. TForm.OnKeyUp)
      • Irányváltozó beállítása, hogy azt jelentse "semerre"
    3. Kirajzoláskor (ezt időzítővel kell/illik megoldani LCL és SDL esetén is, LCL-ben pl. TTimer.OnTimer)
      • A labda új helyének kiszámítása az irányváltozó pillanatnyi értéke alapján
      • Szükség esetén a játéktér elemeinek kirajzolása. (pl háttér és labda/labdák az új helyre)

    + A Timer nem Delay(). A Timer (időzítő) adott időközönként futtat egy felhasználó által megírt eljárást, a Delay pedig 'felfüggeszti' a kód futását a paraméterben megadott ideig.
    Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64

    Egy kezdő Lazarus használó kérdései 2015 dec. 07 19:34 #1674

    • Tomi
    • Tomi profilkép Témaindító
    • Haladó forumozó
    • Haladó forumozó
    • Hozzászólások: 54
    • Köszönetek: 1

    Mihez kell a változók értékét "ciklusosan" ellenőrizni? Mire használnád az értékeket ilyenkor?


    Arra, hogy elmozdulhatnak-e a labdaobjektumok. Vagy ez a TTimer ugyanaz lenne, mint a Delay a sima Pascalban?

    Egy kezdő Lazarus használó kérdései 2015 dec. 07 19:08 #1673

    • Gábor
    • Gábor profilkép
    • Adminisztrátor
    • Adminisztrátor
    • Hozzászólások: 472
    • Köszönetek: 80
    Mihez kell a változók értékét "ciklusosan" ellenőrizni? Mire használnád az értékeket ilyenkor?
    Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64

    Egy kezdő Lazarus használó kérdései 2015 dec. 07 14:59 #1670

    • Tomi
    • Tomi profilkép Témaindító
    • Haladó forumozó
    • Haladó forumozó
    • Hozzászólások: 54
    • Köszönetek: 1

    Ha "folyamatosan" ellenőrizni akarod a változók értékét akkor szerinted azok "folyamatosan" változhatnak. A változást azonban csak valamilyen esemény okozhatja.
    Az egyik kérdés tehát az, hogy hol és mitől változnának az értékek... a másik pedig, hogy mire használod és hol van ténylegesen szükség a változók értékére...


    Az a helyzet, hogy készítettem egy kis mintaprogramocskát, amelyben a felhasználó(k) egyidejűleg két labdát is tud(nak) irányítani, tehát az alkalmazás képes egynél több billentyű egyidejű kezelésére. Ez már régi problémám volt Turbo Pascalban is, és úgy néz ki, Lazarusban sikerült megoldanom. Dióhéjban a felépítése annyi, hogy vannak a 4 mozgásirányhoz rendelt logikai változók (a 2 labdánál összesen 8), amelyek az adott gomb lenyomásakor IGAZ értékűek lesznek és a gomb felengedéséig azok is maradnak, utána pedig HAMIS értékűek lesznek. Ez eddig teljesen eseményvezérelten megoldható. Viszont a változók kiértékelése ciklusosan kéne, hogy legyen, és erre egyelőre a TTimer eseményt találtam (próbáltam ezeket az IF-eket beszúrni a program elejére vagy végére a használt függvények elé vagy mögé, de úgy nem működött; mindig hibát írt ki.). Ez a legjobb megoldás vagy van ilyenre külön esemény a Lazarusban?
    Egyébként ezt a programomat majd közzétenném majd itt a honlapon a Letöltőközpontban, ha lehet, hiszen hátha szolgálhat másoknak is segítség gyanánt.

    ?!
    Ugye nem egy vagy több a FreePascal/Lazarus unit-jaiban már deklarált változót akarsz újra deklarálni?


    Nem, csupán néhány saját boolean (logikai) változóról van szó (labda1fel, labd1le, stb.), amelyek igaz vagy hamis voltát talán lehetne az Időzítő (TTimer) eseményen kívül is valahogy folyamatosan ellenőrizni.

    Egy kezdő Lazarus használó kérdései 2015 dec. 06 18:58 #1662

    • Gábor
    • Gábor profilkép
    • Adminisztrátor
    • Adminisztrátor
    • Hozzászólások: 472
    • Köszönetek: 80
    Ha "folyamatosan" ellenőrizni akarod a változók értékét akkor szerinted azok "folyamatosan" változhatnak. A változást azonban csak valamilyen esemény okozhatja.
    Az egyik kérdés tehát az, hogy hol és mitől változnának az értékek... a másik pedig, hogy mire használod és hol van ténylegesen szükség a változók értékére...

    Mert most akárhová raktam (implementation elé, mögé vagy akár az interface-hoz), mindenütt volt valami baja: hol a BEGIN-t hiányolta, hol "duplicate identifier"-t ír ki a változók nevére, hol "identifier not found"-ot... :unsure:
    (RÉSZBEN MEGOLDOTTAM! (Elfelejtettem az OnCreate-be rakni a változók inicializálását!)

    ?!
    Ugye nem egy vagy több a FreePascal/Lazarus unit-jaiban már deklarált változót akarsz újra deklarálni?
    Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64

    Egy kezdő Lazarus használó kérdései 2015 dec. 06 16:10 #1660

    • Tomi
    • Tomi profilkép Témaindító
    • Haladó forumozó
    • Haladó forumozó
    • Hozzászólások: 54
    • Köszönetek: 1
    Még egy fontos megoldandó kérdés bukkant fel: ha valami olyan kódot akarok elhelyezni, amelyet semmi más felsorolt eseménybe (se kattintás, se gombnyomás, stb.) nem tudok beilleszteni, mert nem illik oda eseményileg, akkor azt hová tegyem, hová tehetem a forráskódszerkesztőben?
    Néhány logikai (boolean) változó értéket szeretném leellenőrizni a program futása során folyamatosan és ehhez kellene valami ciklusos esemény. Mert most akárhová raktam (implementation elé, mögé vagy akár az interface-hoz), mindenütt volt valami baja: hol a BEGIN-t hiányolta, hol "duplicate identifier"-t ír ki a változók nevére, hol "identifier not found"-ot... :unsure:
    (RÉSZBEN MEGOLDOTTAM! (Elfelejtettem az OnCreate-be rakni a változók inicializálását!) DE: kérdéses még számomra, hogy lehet-e és ha igen, akkor hogyan ciklusosan leellenőrizni valami(ke)t, a TTimer objektum használatán kívül?)

    Egy kezdő Lazarus használó kérdései 2015 dec. 06 10:51 #1657

    • Tomi
    • Tomi profilkép Témaindító
    • Haladó forumozó
    • Haladó forumozó
    • Hozzászólások: 54
    • Köszönetek: 1
    Köszönöm szépen a hasznos útmutatást, mely alapján végre sikerült zöldágra vergődnöm vele; most már csak át kell ültetnem egy konkrét programba, de ez remélhetőleg már menni fog.
    Nem volt könnyű rávenni a Lazarust, hogy halmazból kiírassam az elemeket, de azért megoldottam. Ehhez persze kellett a segítséged is, mert még eléggé kezdő vagyok sokmindenben.
    Van nekem egy Lazarus-jegyzetem is (Kálcza Tamás és Nagy Balázs írták), de az csak a felület bemutatására szorítkozik, magára a nyelv ismeretére és használatára nem - igaz, ez nem is várható el egy jegyzettől, hiszen ahhoz egy könyv is kevés lenne.

    Egy kezdő Lazarus használó kérdései 2015 dec. 05 19:37 #1656

    • Gábor
    • Gábor profilkép
    • Adminisztrátor
    • Adminisztrátor
    • Hozzászólások: 472
    • Köszönetek: 80
    Az interface (felület) részben deklarált változók a unit-ot használó más unitok és programok által is elérhetők, az implementation (kidolgozás) részben deklaráltak csak az adott unitban, a deklarációt követő kódrészekben hozzáférhető. Az hogy "jó helyen vannak-e" csak attól függ mi a célod velük...

    A Pascal/ObjectPascal nyelv alapvető részei a megvalósítástól függetlenül szinte teljesen ugyanazok. Segítségként ajánlom szíves figyelmedbe a következő dokumentációs oldalakat:

    Free Pascal 3.0.0 Documentation
    RTL, FCL, LCL Dokumentation

    ... és Google a barátod!
    Hogyan kérdezzünk okosan? / Mit kell tennünk kérdezés előtt? -- Lazarus 2.3.0 -- FPC 3.3.1-- GNU/Linux 5.4.0 x86_64
    Megköszönték: Tomi

    • Oldal:
    • 1
    • 2
    • 3