kolorowanka delphi 7

IW
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 13 lat
  • Postów:11
0

Próbuję od kilku dni napisać prostą kolorowankę w Delphi 7.
Znalazłam trochę, ale nie daję rady z wypełnieniem.

Kopiuj
 unit koloro;

interface
  {$R RESOURCE.RES RESOURCE.RC}
uses
  Jpeg, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtDlgs, StdCtrls, ExtCtrls, ColorGrd, Grids, ComCtrls,
  Menus, Clipbrd, Buttons, ToolWin;

type
    TForm1 = class(TForm)
    Button4: TButton; //zamyka
    Button8: TButton; //kaczor
    Button9: TButton; //kubuspro
    Button10: TButton;//kubus
    Button11: TButton; //pluto
    Button13: TButton;  //tomjerry
    Button2: TButton; //zapisz
    Button3: TButton; //drukuj
    Button14: TButton; //ust druku
    Button7: TButton; //kolor
    SavePictureDialog1: TSavePictureDialog;
    PrinterSetupDialog1: TPrinterSetupDialog;
    ColorDialog1: TColorDialog;
    PrintDialog1: TPrintDialog;
    GroupBox1: TGroupBox;
    GroupBox2: TGroupBox;
    procedure Button4Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button8Click(Sender: TObject);
    procedure Button10Click(Sender: TObject);
    procedure Button9Click(Sender: TObject);
    procedure Button11Click(Sender: TObject);
    procedure Button13Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button14Click(Sender: TObject);
    procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
end;
var
  Form1: TForm1;
  bm: TBitmap;
  CurrentColor: TColor = clBlack;


implementation
{$R *.dfm}

{
type
  TASPixmap = array of packed array of TRGBQuad;

  TRGB32Array = packed array[0..MaxInt div SizeOf(TRGBQuad)-1] of TRGBQuad;
  PRGB32Array = ^TRGB32Array;

  TScanline = TRGB32Array;
  PScanline = ^TScanline;

function IsIntInInterval(x, xmin, xmax: integer): boolean; 
begin
  IsIntInInterval := (xmin <= x) and (x <= xmax);
end;

function PascalColorToRGBQuad(const Color: TColor): TRGBQuad;
begin
  with Result do
  begin
    rgbBlue := GetBValue(Color);
    rgbGreen := GetGValue(Color);
    rgbRed := GetRValue(Color);
    rgbReserved := 0;
  end;
end;

function RGBQuadEqual(const Color1: TRGBQuad; const Color2: TRGBQuad): boolean;
begin
  RGBQuadEqual := (Color1.rgbBlue = Color2.rgbBlue) and
                  (Color1.rgbGreen = Color2.rgbGreen) and
                  (Color1.rgbRed = Color2.rgbRed);
end;

function PMFloodFill(Pixmap: TASPixmap; const X0: integer; const Y0: integer; const Color: TColor): TASPixmap;
var
  w, h: integer;
  MatchColor, QColor: TRGBQuad;
  Queue: packed array of TPoint;
  cp: TPoint;

  procedure push(Point: TPoint);
  begin
    SetLength(Queue, length(Queue) + 1);
    Queue[High(Queue)] := Point;
  end;

  function pop: TPoint;
  var
    lm1,w: integer;
  begin
    assert(length(Queue) > 0);
    result := Queue[0];
    lm1 := length(Queue) - 1;
    if lm1 > 0 then
      MoveMemory(@(Queue[0]), @(Queue[1]), lm1 * sizeof(TPoint));
    SetLength(Queue, lm1);
  end;
begin
  h := length(Pixmap);
  if h > 0 then
    w := length(Pixmap[0]);
  result := Pixmap;
  if not (IsIntInInterval(X0, 0, w-1) and IsIntInInterval(Y0, 0, h-1)) then Exit;
  MatchColor := Pixmap[Y0, X0];
  QColor := PascalColorToRGBQuad(Color);
  SetLength(Queue, 0);
  push(point(X0, Y0));
  while length(Queue) > 0 do
  begin
    if RGBQuadEqual(result[Queue[0].Y, Queue[0].X], MatchColor) then
      result[Queue[0].Y, Queue[0].X] := QColor;

    cp := pop;

    if cp.X > 0 then
      if RGBQuadEqual(result[cp.Y, cp.X - 1], MatchColor) then
      begin
        result[cp.Y, cp.X - 1] := QColor;
        push(point(cp.X - 1, cp.Y));
      end;

    if cp.X < w-1 then
      if RGBQuadEqual(result[cp.Y, cp.X + 1], MatchColor) then
      begin
        result[cp.Y, cp.X + 1] := QColor;
        push(point(cp.X + 1, cp.Y));
      end;

    if cp.Y > 0 then
      if RGBQuadEqual(result[cp.Y - 1, cp.X], MatchColor) then
      begin
        result[cp.Y - 1, cp.X] := QColor;
        push(point(cp.X, cp.Y - 1));
      end;

    if cp.Y < h-1 then
      if RGBQuadEqual(result[cp.Y + 1, cp.X], MatchColor) then
      begin
        result[cp.Y + 1, cp.X] := QColor;
        push(point(cp.X, cp.Y + 1));
      end;
  end;
end;

function GDIBitmapToASPixmap(const Bitmap: TBitmap): TASPixmap;
var
  scanline: PScanline;
  width, height, bytewidth: integer;
  y: Integer;
begin

  Bitmap.PixelFormat := pf32bit;

  width := Bitmap.Width;
  height := Bitmap.Height;
  bytewidth := width * 4;

  SetLength(Result, height);
  for y := 0 to height - 1 do
  begin
    SetLength(Result[y], width);
    scanline := @(Result[y][0]);
    CopyMemory(scanline, Bitmap.ScanLine[y], bytewidth);
  end;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  bm := TBitmap.Create;
end;

procedure GDIBitmapAssign(Bitmap: TBitmap; const Pixmap: TASPixmap);
var
  y: Integer;
  scanline: PScanline;
  bytewidth: integer;
begin
  Bitmap.PixelFormat := pf32bit;
  bytewidth := Bitmap.Width * 4;

  for y := 0 to Bitmap.Height - 1 do
  begin
    scanline := @(Pixmap[y][0]);
    CopyMemory(Bitmap.ScanLine[y], scanline, bytewidth);
  end;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
bmp:TBitmap;
begin
  Canvas.Draw(0, bmp.Height, bm);
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
    close;
end;
}
procedure TForm1.Button3Click(Sender: TObject);  //drukuj
begin
    PrintDialog1.Execute;
end;


procedure TForm1.Button8Click(Sender: TObject);          
var
  Bitmap : TBitmap;
begin
with form1 do with canvas do
  begin
   brush.Color := color;
   fillrect(rect(0,0,width,height));
  end;
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromResourceName(hInstance, 'kaczor');
  Canvas.Draw(0, 0, Bitmap);
  Bitmap.Free;
end;
procedure TForm1.Button10Click(Sender: TObject); 
var
  Bitmap : TBitmap;
begin
with form1 do with canvas do
  begin
   brush.Color := color;
   fillrect(rect(0,0,width,height));
  end;
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromResourceName(hInstance, 'kubus');
  Canvas.Draw(0, 0, Bitmap);
  Bitmap.Free;
end;
procedure TForm1.Button9Click(Sender: TObject);
var
  Bitmap : TBitmap;
begin
with form1 do with canvas do
  begin
   brush.Color := color;
   fillrect(rect(0,0,width,height));
  end;
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromResourceName(hInstance, 'kubuspro');
  Canvas.Draw(0, 0, Bitmap);
  Bitmap.Free;
end;

procedure TForm1.Button11Click(Sender: TObject);  
var
  Bitmap : TBitmap;
begin
with form1 do with canvas do
  begin
   brush.Color := color;
   fillrect(rect(0,0,width,height));
  end;
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromResourceName(hInstance, 'pluto');
  Canvas.Draw(0, 0, Bitmap);
  Bitmap.Free;
end;

procedure TForm1.Button13Click(Sender: TObject);       
var
  Bitmap : TBitmap;
begin
 with form1 do with canvas do   
  begin
   brush.Color := color;
   fillrect(rect(0,0,width,height));
  end;
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromResourceName(hInstance, 'tj');
  Canvas.Draw(0, 0, Bitmap);
  Bitmap.Free;
end;
procedure TForm1.Button7Click(Sender: TObject);         
begin
  with TColorDialog.Create(self) do
    try
      Color := CurrentColor;
      Options := [cdFullOpen];
      if Execute then
        CurrentColor := Color;
    finally
      Free;
    end;
end;

procedure TForm1.Button2Click(Sender: TObject);             
begin
      SavePictureDialog1.Execute;
end;

procedure TForm1.Button14Click(Sender: TObject);              
begin
    PrinterSetupDialog1.Execute;
end;

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
  x0, y0: integer;
  pm: TASPixmap;
begin
  x0 := X;
  y0 := Y - GroupBox1.Height;

  if IsIntInInterval(x0, 0, GroupBox1.Width) and IsIntInInterval(y0, 0, GroupBox1.Height) then
  begin
    pm := GDIBitmapToASPixmap(bm);
    pm := PMFloodFill(pm, x0, y0, CurrentColor);
    GDIBitmapAssign(bm, pm);
  end;
end;

end.

To co jest w komentarzu ( {} ) tego nie pojmuję i na 99,9% tam jest błąd.
Obrazki wczytuję z resource'a, działa.
Po uruchomieniu pokazuje się wybór obrazków, po wciśnięci odpowiedniego przycisku pokazuje się dany obrazek, ale po wybraniu koloru dany obszar nie wypełnia się.

Tu pytanie:

  1. Czy da się prościej napisać wypełnienie danych kształtów?
  2. Dlaczego po wybraniu koloru i kliknięciu na obrazek nie wypełnia się?

PS: Bitmapę wczytuję na formularzu, bo w image1 i paintbox1 wywalało mi ciągle błędy.

edytowany 4x, ostatnio: madmike
cimak
kod wklejaj w znacznikach "delphi" a nie "code". popraw to, bedzie bardziej czytelne.
cimak
druga sprawa to nazenictwo komponentow - czytajac kod, nie mamy pojecia od czego jest np "Button7".
madmike
ad. 1 - done :)
cimak
po trzecie: jesli masz problem z kolorowaniem, to wklejaj tylko kod odpowiedzialny za kolorowanie, podawanie kodu odpowiedzialnego za wybieranie i ladowanie pliku, czy za drukowanie nie ma sensu.
cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
0

Canvas udostepnia Ci funkcje odpoiedzialne za wypelnianie danym kolorem. Czemu z nich nie skorzystasz?

IW
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 13 lat
  • Postów:11
0

Musiałabym robić to w paintbox'ie chyba, prawdę mówiąc zaczynam dopiero Delphi (4 TI)
I nie wiem jak na Bmp czy Jpegu ograniczyć miejsce wypełnienia. Chociaż próbowałam używać Canvasa to zupełnie nic z tego nie wyszło..

cimak
wklej tu gdzies przykladowy obrazek do pokolorwania...
IW
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 13 lat
  • Postów:11
0

Obrazek do kolorowania na przykład taki:

user image

edytowany 7x, ostatnio: iwanthim
madmike
ściągnąłem, wstawiłem jako załącznik, a do postu wstawiłem, żeby wyświetlał :) Nowym użytkownikom źle wyświetla obrazki z zewnętrznych serwerów...
IW
ok :) i serdecznie dziękuję za pomoc :)
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:2 minuty
  • Lokalizacja:Tuchów
  • Postów:12164
1
iwanthim napisał(a)

I nie wiem jak na Bmp czy Jpegu ograniczyć miejsce wypełnienia. Chociaż próbowałam używać Canvasa to zupełnie nic z tego nie wyszło..

Z reguły jeżeli wypełniasz jakiś obszar, to granicą obszaru są piksele o innym kolorze; Choćby kolor był inny tylko o 1, to już jego nie piwinien algorytm wypełniający pomalować; Stąd jeżeli znajdziesz sposób na wypełnianie danym kolorem w miejscu o dokładnych współrzędnych, grafika w formacie JPEG nie zostanie prawidłowo wypełniona, gdyż algorytm konwertujący grafikę do tego formatu kompresuje zawartość i tworzy bloki o jednym kolorze, więc tło zawsze jest nieregularne; Gołym okiem tego nie widać, ale w powiększeniu owszem; Stosuj grafikę, która nie wspiera konwersji stratnej, taka jak BMP czy PNG, jednak dla tej drugiej opracowanie algorytmu wypełniania będzie trudniejsze;


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
cimak
do tego to chyba najprostszym rozwiazaniem bedzie 2bit bmp.
flowCRANE
Owszem, wszystko zależy od tego jakim się algorytmem wypełniającym dysponuje;
cimak
wlasciwie 1bit. algorytm... zwykly floodFill canvasa sobie poradzi.
cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
1
Kopiuj
 image1.Canvas.Brush.Color:=clRed;
 image1.Canvas.FloodFill(x,y, clWhite, fsSurface);

w tym przypadku clRed to kolor ktorym zastąpisz clWhite.
wiec clWhite powinien byc kolorem pobieranym spod kursora (kolor:=canvas.pixels[x,y];)
x y to oczywiscie pozycja kursora na obrazku.

edytowany 1x, ostatnio: cimak
IW
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 13 lat
  • Postów:11
0

czy zamiast clRed mogę dać ColorDialog1.Color żeby odczytało ten, który zostanie wybrany?

cimak
zamiast zadawac takie pytanie to zwyczajnie sprawdz sam. komputer Ci sie od takiego kombinowania nie spali.
IW
wybacz :) poza tym miło mi, jestem Agnieszka
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:2 minuty
  • Lokalizacja:Tuchów
  • Postów:12164
0

A czy między TColor a TColor jest jakaś różnica..?


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
IW
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 13 lat
  • Postów:11
0

Nie. Zadaję takie pytania bo chcę wiedzieć. Jak pisałam, dopiero zaczynam pracę z Deplhi. Na zajęciach go nawet nie mam, tylko staram się w miarę samodzielnie..

Dziękuję wszystkim za dotychczasową pomoc

flowCRANE
Kombinuj dalej, bo optymizm to klucz do sukcesu;
IW
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 13 lat
  • Postów:11
0

Jeszcze pytanie: czy

Kopiuj
 image1.canvas... 

mam dawać jako reakcję na image1, czy źle myślę?

IW
jak klikam na obrazek to jego pewna część koloruje//wypełnia się na granatowo - są postępy :)
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:2 minuty
  • Lokalizacja:Tuchów
  • Postów:12164
0
iwanthim napisał(a)

mam dawać jako reakcję na image1, czy źle myślę?

Możesz jaśniej...? Co znaczy reakcję w Twoim rozumieniu?


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
IW
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 13 lat
  • Postów:11
0

Reakcja- zdarzenie na dany bodziec, w tym przypadku kliknięcie w danym miejscu. Chodzi mi o to, że muszę przypisać FloodFill'a do Image.

Z tym już nie mam problemu, ale chyba muszę odczytać pozycję myszki x,y..

Kopiuj
procedure TForm1.Image1Click(Sender: TObject);
var
  x,y:integer;
begin
    image1.canvas.Brush.Style := bsSolid;
    image1.Canvas.Brush.Color := ColorDialog1.Color;
    image1.Canvas.FloodFill(x,y, clWhite, fsSurface );
end; 

Jak w miejsce x i y wstawiłam 1,1 to wypełniło mi tło, ale kolorem granatowym i nie w miejscu gdzie kliknęłam, ale to pewnie dlatego, że określiłam współrzędne.. I stąd pytanie czy muszę w takim przypadku określić położenie wskaźnika myszy?

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:2 minuty
  • Lokalizacja:Tuchów
  • Postów:12164
1
iwanthim napisał(a)

Jak w miejsce x i y wstawiłam 1,1 to wypełniło mi tło, ale kolorem granatowym i nie w miejscu gdzie kliknęłam, ale to pewnie dlatego, że określiłam współrzędne.. I stąd pytanie czy muszę w takim przypadku określić położenie wskaźnika myszy?

Możesz to zrobić dwojako:

  1. ręcznie pobrać położenie kursora
  2. skorzystać ze zdarzenia OnMouseDown komponentu
    Wykorzystaj, którą chcesz;

Jeśli chcesz ręcznie pobrać pozycję kursora - skorzystaj z funkcji GetCursorPos:

Kopiuj
procedure GetCursorPos(var P: TPoint);

gdzie jako argument podajesz zmienną typu TPoint;


Jeśli chodzi o zdarzenie OnMouseDown:

Kopiuj
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
                                 Shift: TShiftState; X, Y: Integer);

W argumentach X i Y masz podaną aktualną pozycję kursora na ekranie;


Jeśli chodzi o kolor, @cimak napisał Ci jak posługiwać się metodą FloodFill:

Kopiuj
Image1.Canvas.Brush.Color := clRed;
Image1.Canvas.FloodFill(X, Y, clWhite, fsSurface);

w tym przypadku clRed to kolor ktorym zastąpisz clWhite.
wiec clWhite powinien byc kolorem pobieranym spod kursora (Kolor := Image1.Canvas.Pixels[X, Y];)
x y to oczywiscie pozycja kursora na obrazku.

Przykładowy kod:

Kopiuj
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
                                 Shift: TShiftState; X, Y: Integer);
var
  dlgColor: TColorDialog;
begin
  dlgColor := TColorDialog.Create(Self);

  try
    with dlgColor do
      begin
        Options := [cdFullOpen];

        if Execute() then
          begin
            Image1.Canvas.Brush.Color := dlgColor.Color;
            Image1.Canvas.FloodFill(X, Y, Image1.Canvas.Pixels[X, Y], fsSurface);
          end;
      end;
  finally
    FreeAndNil(dlgColor);
  end;
end;

Powinien działać;


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 2x, ostatnio: flowCRANE
IW
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 13 lat
  • Postów:11
0

Dzisiaj miałam programowanie i właśnie nauczyciel mi to podpowiedział :) ale niestety program się później zwiesił, a nie zapisałam, bo myślałam, że mi się przy kompilowaniu zapisze no i utraciłam to co podpowiedział.

Dziękuję, że to wstawiłeś, dzięki Tobie odzyskałam :)

i mam pytanie. W image daję stretch na true, żeby obrazek się dopasował, ale wtedy nie koloruje tam, gdzie kliknę. Wiecie jak to ogarnąć?
Nauczyciel pokazał mi przy wczytywaniu obrazka odczytanie współrzędnych bitmapy, tak że czyta jak myszką ruszam po bitmapie a nie po image i potem podmieniał te wartości
przykładowo: zmienne

Kopiuj
ax, ay:real;

potem odczytał szerokość i wysokość bitmapy i podstawił pod zmienne ax, ay, a następnie zrobił coś w tym stylu:

Kopiuj
 [Round(ax/x),Round(ay/y)]; //przy pixel
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:2 minuty
  • Lokalizacja:Tuchów
  • Postów:12164
1
iwanthim napisał(a)

Nauczyciel pokazał mi przy wczytywaniu obrazka odczytanie współrzędnych bitmapy, tak że czyta jak myszką ruszam po bitmapie a nie po image i potem podmieniał te wartości

Nie rozumiem o czym piszesz...

iwanthim napisał(a)

ruszam po bitmapie a nie po image

Co to znaczy po bitmapie? Jeśli masz komponent z klasy TImage, możesz przecież przechwycić współrzędne kursora myszy w kilku zdarzeniach:

Kopiuj
procedure TForm1.Image1MouseUp(Sender: TObject; Button: TMouseButton;
                               Shift: TShiftState; X, Y: Integer);

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
                                 Shift: TShiftState; X, Y: Integer);

procedure TForm1.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
                                 Y: Integer);

więc także podczas przesuwania kursora po komponencie;

Jeżeli chodzi o właściwość Stretch, nauczyciel pokazał Ci w jaki sposób pobrać współrzędne kursora w momencie kliknięcia, po czym przetłumaczyć je na grafikę o normalnych rozmiarach (którą komponent przechowuje we właściwościach Width i Height) i obsłużyć;

Sprawa jest prosta, jeśli masz grafikę o rozmiarach 100x100px, a komponent ma rozmiar 200x200px (czyli jest dwa razywiększy) oraz właściwość Stretch na True, to jeżeli klikniesz w punkcie o współrzędnych [100, 100], to tak, jak być kliknął w punkt [50, 50] na tej zmniejszej grafice; Trzeba po prostu znaleźć kliknięty punkt na mniejszej grafice; Dlatego posłużył się typem zmiennoprzecinkowym; Po obliczeniu współrzędnych punku na mniejszej grafice ich wartości trzeba zaokrąglić (patrz: funkcja Round), ponieważ współrzędne to liczby całkowite;

Ot cała historyja :-P


iwanthim napisał(a)

ale niestety program się później zwiesił, a nie zapisałam, bo myślałam, że mi się przy kompilowaniu zapisze no i utraciłam to co podpowiedział.

Moim nawykiem z nauki pascala (na TP7) było każdorazowe zapisywanie projektu przed (kompilacją i) uruchomieniem, ponieważ jak program się zawiesił i trzeba było go awaryjnie zamknąć - wyłączał się razem z konsolą i traciłem nowe niezapisane dane; Dobry nawyk, nigdy nie tracę nowo napisanego kodu; Polecam zawsze przed kompilacją wciśnąć kombinacje Shift + Ctrl + S - zapisane zostaną wszystkie otwarte i zmodyfikowane pliki;


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 1x, ostatnio: flowCRANE
pelsta
D7: Tools -> Environment Options -> Autosave options
flowCRANE
Można i tak; Ja mimo wszystko odruchowo przed kompilacją zapisuje wszystko przed ww kombinację;
IW
też zawsze zapisywałam, ale teraz sekunda zapomnienia się i ekscytacji ,,bo program zaczął w 100% działać" i klops..
cimak
  • Rejestracja:ponad 22 lata
  • Ostatnio:ponad 9 lat
  • Postów:1668
0
Furious Programming napisał(a)

Jeżeli chodzi o właściwość Stretch, nauczyciel pokazał Ci w jaki sposób pobrać współrzędne kursora w momencie kliknięcia, po czym przetłumaczyć je na grafikę o normalnych rozmiarach (którą komponent przechowuje we właściwościach Width i Height) i obsłużyć;

rozmiary "normalnej" grafiki, tj nierozciągniętej, komponent nie trzyma w width i height (w sensie image1.width).
tam sa trzymane "rozciągnięte" wymiary.
"normalne" bedą -dla bitmapy- w image1.picture.bitmap.width;

flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:2 minuty
  • Lokalizacja:Tuchów
  • Postów:12164
0
cimak napisał(a)

rozmiary "normalnej" grafiki, tj nierozciągniętej, komponent nie trzyma w width i height (w sensie image1.width).
tam sa trzymane "rozciągnięte" wymiary.
"normalne" bedą -dla bitmapy- w image1.picture.bitmap.width;

Dokładnie; Kolega pisał wcześniej właśnie o Bitmap, więc napisałem same identyfikatory właściwości; Mój błąd, mogłem napisać pełną ścieżkę;

W każdym razie chodzi właśnie o te dwie właściwości:

Kopiuj
Image.Picture.Bitmap.Width;
Image.Picture.Bitmap.Height;

Dzięki za sprostowanie @cimak;


Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
IW
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 13 lat
  • Postów:11
0
Furious Programming napisał(a)

W każdym razie chodzi właśnie o te dwie właściwości:

Kopiuj
Image.Picture.Bitmap.Width;
Image.Picture.Bitmap.Height;

Dzięki za sprostowanie @cimak;

to wiem właśnie, tylko dać to przy wczytywaniu bitmapki, czy przy kolorowaniu?
Przy kolorowaniu mam to:

Kopiuj
image1.Picture.Bitmap.Canvas.FloodFill(x,y, Image1.Picture.Bitmap.Canvas.Pixels[Round(ax/x), Round(ay/y)], fsSurface );
edytowany 4x, ostatnio: iwanthim
adf88
  • Rejestracja:ponad 21 lat
  • Ostatnio:prawie 12 lat
1
Kopiuj
procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  { najpierw zamien wspolrzedne ekranowe na wspolrzedne piksela bitmapy }
  X := X * Image1.Picture.Bitmap.Width / Image1.Width;
  Y := Y * Image1.Picture.Bitmap.Height / Image1.Height;

  { pozniej malujemy }
  Image1.Picture.Bitmap.Canvas.FloodFill(X, Y, Image1.Picture.Bitmap.Canvas.Pixels[X, Y], fsSurface);
end;
edytowany 1x, ostatnio: adf88
flowCRANE
Moderator Delphi/Pascal
  • Rejestracja:ponad 13 lat
  • Ostatnio:2 minuty
  • Lokalizacja:Tuchów
  • Postów:12164
1

@adf88, nie można w ten sposób dzielić liczb całkowitych... Trzeba skorzystać z operatora div:

Kopiuj
X := X * Image1.Picture.Bitmap.Width div Image1.Width;
Y := Y * Image1.Picture.Bitmap.Height div Image1.Height;

lub funkcji MulDiv():

Kopiuj
X := MulDiv(X, Image1.Picture.Bitmap.Width, Image1.Width);
Y := MulDiv(Y, Image1.Picture.Bitmap.Height, Image1.Height);

Pracuję nad własną, arcade'ową, docelowo komercyjną grą z gatunku action/adventure w stylu retro (pixel art), programując silnik i powłokę gry od zupełnych podstaw, przy użyciu Free Pascala i SDL3. Więcej informacji znajdziesz na moim mikroblogu.
edytowany 2x, ostatnio: flowCRANE
pelsta
W takich przypadkach używam funkcję MulDiv
flowCRANE
Można i tak; Nie wiem czy jest sens optymalizować ten kod; Klikać i tak pewnie nikt nie będzie 100x/sek; Ale dobrze wiedzieć :P
flowCRANE
Post poprawiony :)
IW
  • Rejestracja:około 13 lat
  • Ostatnio:prawie 13 lat
  • Postów:11
0

Dziękuję kochani, wszystko działa! :*

pozdrawiam, Agnieszka

Mariusz Bruniewski
Mariusz Bruniewski
  • Rejestracja:ponad 19 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Świecie
0

Umysł pozytywny szuka sposobów, jak coś wykonać; umysł negatywny wyszukuje sposoby, by uzasadnić, że czegoś nie można zrobić.
~~ Napoleon Hill ~~
edytowany 1x, ostatnio: Mariusz Bruniewski
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)