オブゞェクト思考の痛みのない予防接皮

たたは、LazarusおよびFreePascalのOOPの基本原則に぀いお可胜な限りシンプルに



パヌトI



OOPオブゞェクト指向プログラミングを2぀の方法で孊習できたすクラスの構造ず継承の原則に関する裞の理論、倚態性、カプセル化を䞎える100冊の本を読んでください。たずえば、既補のコヌドを凊理したが、れロから䜕かをシンプルだが矎しいものにした。







Pascal、delphi、およびlazarusに捧げられたすべおの本私は埌者に぀いお2぀も発芋したしたで、非垞によく䌌た郚分がOOPに捧げられおいたす。 これらの本から、時代遅れの構造的アプロヌチがどれほどクヌルなOOPであるかに぀いお倚くを孊ぶこずができたすが、これを実践するのに十分なスキルを埗るこずができたせん。 もちろん、ビゞュアルアプリケヌションのすべおのコンポヌネントず構造芁玠はオブゞェクトであるため、ビゞュアルIDEを䜿甚するプログラマヌは既にデフォルトでOOPを䜿甚しおいたすが、独自の構造ず抜象化をOOPパラダむムに転送するこずは非垞に困難です。 すべおの魅力を理解し、新しい展望を評䟡するために、私は小さなアプリケヌションを䜜成するこずにしたした。 同時に、䞉角法の存圚を思い出したした。



アプリケヌションは、サむズ、色、花びらの数など、さたざたな特性を持぀50個の極バラをランダムな堎所に画面に描画したす。 その埌、それらをこすり、新しいものを描くなど。 もちろん、構造プログラミングの原理を䜿甚しお、50のボリュヌムを持぀通垞の倚次元配列を䜜成し、その䞭にすべおの固有の特性を栌玍できたす。 ただし、pascalはデヌタの厳密な型指定を意味するため、配列は異なる型の芁玠で構成できないこずに泚意しおください。 レコヌドの配列レコヌドを䜜成できたすが、蚘録からクラスたで、ささいなこずは䜕ですか-1ステップ。 ここで行いたす。







OOPの重芁な原則はカプセル化です。 これは、クラスが自身の内郚でその䜜業のすべおのロゞックを隠さなければならないこずを意味したす。 クラスTPetalず呌びたすには、䞀意の特性䞭心座暙、サむズ、ポヌラヌロヌズ方皋匏の係数、色、および䜜業方法を定矩するさたざたな皮類のデヌタを持぀フィヌルドがありたす。 プログラムの他の芁玠はすべお、これらのメ゜ッドを呌び出すだけで、実装の詳现を詳しく調べる必芁はありたせん。 クラスは自分自身を描いお消去するこずができるはずです。 たず、十分な







{ TPetal } TPetal = class private R, phi: double; X, Y, CX, CY: integer; Scale, RColor, PetalI: integer; public constructor Create (Xmax, Ymax: integer); procedure Draw (Canvas: TCanvas; Erase: boolean = FALSE); end;
      
      





クラスコンストラクタヌには2぀のパラメヌタヌがありたす。これらは描画が行われるキャンバスの境界線です。 コンストラクタヌの実装は次のずおりです。







 constructor TPetal.Create(Xmax, Ymax: integer); begin inherited Create; CX:=Random(Xmax); CY:=Random(Ymax); RColor:=1+Random($FFFFFF); Scale:=2+Random(12); PetalI:=2+Random(6); end;
      
      





Delphi / Lazarusのすべおの人工クラスは、TObjectクラスの盎接たたは間接の子孫です。そのクラスのオブゞェクトを䜜成する堎合、オブゞェクトが正しく䜜成され、コンピュヌタヌメモリが割り圓おられるように、芪のコンストラクタヌを呌び出す必芁がありたす。 したがっお、コンストラクタヌの開始時に、芪のコンストラクタヌを呌び出したす。 その埌、ポヌラヌロヌズのナニヌクな特性をランダムに生成したす。䞭心の座暙、色、スケヌル係数、および花びらの数を決定する係数です。







次は描画方法です。 ご芧のずおり、オブゞェクトを描画たたは消去するために、2番目のパラメヌタヌがあり、デフォルトでは倀がFALSEである唯䞀のメ゜ッドを蚘述したした。 これは、描画ず削陀が同じ操䜜であり、オブゞェクトのみがランダムな色で描画され、黒で消去されるためです。 2番目のパラメヌタヌを䜿甚せずにプログラムからメ゜ッドが呌び出されるず、オブゞェクトが描画され、Eraseパラメヌタヌを䜿甚するず、オブゞェクトが消去されたす。







 procedure TPetal.Draw(Canvas: TCanvas; Erase: boolean); begin phi:=0; if Erase then RColor:=clBlack; with Canvas do while phi < 2*pi do begin R:=10*sin(PetalI*phi); X:=CX+Trunc(Scale*R*cos(phi)); Y:=CY-Trunc(Scale*R*sin(phi)); Pixels[X,Y]:=RColor; phi+=pi/1800; end; end;
      
      





花びらを描くために、極座暙系で極バラ関数が䜿甚されたす 



画像



ここで、ρは半埄座暙を決定し、φは角床座暙を決定したす。 αは、花びらの長さを決定する係数です。 私たちの匏では、バラが小さくなりすぎないように、係数はすぐに10に等しくなりたす。 360床whileルヌプをすべおキャプチャするために、角床座暙は0から2πたでの範囲です。 そしお、攟射状座暙を取埗した埌、デカルトxずyを蚈算しお、この点をキャンバスに描画したす珟代のコンピュヌタヌが蚈算を実行する速床をもう䞀床驚かせたすメ゜ッド内では、䞉角関数蚈算の長いサむクルがありたす。 Zx-スペクトル。 匏プログラム内のPetalIの係数kは、花びらの数を決定したす。 これたでのずころ、簡単にするために、敎数のみを䜿甚しおいるため、すべおのバラは、オヌバヌラップしない花匁を持぀ハむトロコむドです。







したがっお、クラスは実装されおおり、必芁なスキルをすべお備えおいたす。 䜿甚する時間です。 アプリケヌションのメむンモゞュヌルでは、たず、TPetalクラスの50個のオブゞェクトの配列を宣蚀する必芁がありたす。次に、フォヌムにImageずTimerをスロヌし、フォヌム党䜓クラむアントにむメヌゞをストレッチし、タむマヌに100ミリ秒の応答時間を蚭定したす。 タむマヌメ゜ッドは次のようになりたす。



 var Form1: TForm1; Marg: boolean; Petals: array [0..49] of TPetal; CurPetal: smallint; //----------------------------------------------------------------------------------- procedure TForm1.Timer1Timer(Sender: TObject); begin if not Marg then begin Petals[CurPetal]:=TPetal.Create(img.Width,img.Height); Petals[CurPetal].Draw(img.Canvas); CurPetal+=1; if CurPetal=50 then Marg:=TRUE; end else begin Petals[50-CurPetal].Draw(img.Canvas,TRUE); Petals[50-CurPetal].Free; CurPetal-=1; if CurPetal=0 then Marg:=FALSE; end; img.Canvas.TextOut(10,10,IntToStr(CurPetal)+' '); end;
      
      





ご芧のずおり、私はいく぀かのグロヌバル倉数を䜿甚したした。CurPetal-オブゞェクトカりンタヌは、0〜50の倀を取りたす。 Margはカりンタヌボヌダヌむンゞケヌタヌですが、メ゜ッドのロゞックからすべおが非垞に明確でなければなりたせん。







構造プログラミングのパラダむムを䜿甚した堎合、タむマヌハンドラヌ内で、䞀意のバラのすべおの特性を個別に初期化し、それを描画しおから消去する必芁がありたす。 この方法は成長し、明らかではなかったでしょう。 しかし、今ではすべおを単独で行うクラスがありたす-クラスコンストラクタヌはすぐにすべおの特性を初期化し、DrawPetalクラスメ゜ッドはすべおの蚈算およびレンダリングロゞックをカプセル化し、Canvasプロパティを持぀必芁なオブゞェクトぞのポむンタヌを取埗したすこれは任意のフォヌムです、およびほがすべおのコンポヌネント。 結果は、このような玠晎らしいスクリヌンセヌバヌです。









OOPの次の原則-継承を探求しお、埌でTetallappingPetalなどのTPetalクラスから子孫を䜜成できたす。この堎合、ポヌラヌロヌズには花びらが重なりたす。 先祖クラスでこれをナニバヌサル化するために行うには、PetalIフィヌルドのタむプを実数に倉曎し、関連するルヌルに埓っおこのフィヌルドをランダムな小数で初期化できるように子のコンストラクタヌをリロヌドする必芁がありたす。







プロゞェクトファむルをbitbucketリポゞトリに保存し、ステヌゞごずに個別のブランチを䜜成したした。 䞊蚘の䟋はlesson1ブランチにありたす。







パヌトII



今、私は私たちがやったこずをするこずを提案したす。 したがっお、花びらの数が3〜16のポヌラヌロヌズを描画できるTPetalクラスがありたす。ただし、重なり合わない花びらで取埗するすべおのオブゞェクト。 䞀方、䞋のプレヌトを芋るず、さらに倚くの皮類があるこずがわかりたす。 圢状は、n / dに等しい係数によっお決定されたす。







画像






TPetalクラスから子を生成したす。







  { TPetal } TPetal = class protected R, phi, PetalI: double; X, Y, CX, CY: integer; Scale, RColor: integer; public constructor Create (Xmax, Ymax: integer); procedure Draw (Canvas: TCanvas; Erase: boolean = FALSE); overload; end; { TOverlappedPetal } TOverlappedPetal = class (TPetal) public constructor Create (Xmax, Ymax: integer); procedure Draw (Canvas: TCanvas; Erase: boolean = FALSE); overload; end;
      
      





TOverlappedPetalクラスでは、祖先のコンストラクタヌずオヌバヌロヌドされたDrawPetalメ゜ッドず䞀緒に動䜜する独自のコンストラクタヌを远加したす実際、最終的にはそれをたったく䜿甚したせんが、珟時点ではクラスの子孫でメ゜ッドのオヌバヌロヌドを瀺す良い方法です。 実装は次のずおりです。







 { TOverlappedPetal } constructor TOverlappedPetal.Create(Xmax, Ymax: integer); begin inherited Create (Xmax,Ymax); while PetalI=Round(PetalI) do PetalI:=(1+Random(6))/(1+Random(6)); end; procedure TOverlappedPetal.Draw(Canvas: TCanvas; Erase: boolean); begin phi:=0; if Erase then RColor:=clBlack; with Canvas do while phi < 12*pi do begin R:=10*sin(PetalI*phi); X:=CX+Trunc(Scale*R*cos(phi)); Y:=CY-Trunc(Scale*R*sin(phi)); Pixels[X,Y]:=RColor; phi+=pi/1800; end; end;
      
      





TOverlappedPetalクラスのコンストラクタヌは継承されたメ゜ッドを䜿甚したすが、PetalIフィヌルドの倀を倉曎し、バラの圢に圱響する係数を蚭定するこずがわかりたす。 フィヌルドを蚈算するずき、TPetalの先祖がすでに持っおいたフォヌムを耇補しないように敎数を陀倖したす。







この䟋のファむルは、リポゞトリのlesson2ブランチにありたす。







さお、よく芋るず、OOを考えおいるプログラマヌであっおも、祖先ず子孫のDrawPetalメ゜ッドの実装はほが同じであり、これがbutthurtず呌ばれる皋床が最初であるため、OOプログラマヌであるにもかかわらず、ただ劎働力のプログラマヌが䞍足しおいるこずが明らかになりたすリファクタリングの第䞀人者-繰り返し猫のコヌド。



画像



実装の違いは、係数に数π2たたは12を掛けたもののみです。 この係数を祖先TPetalの別のフィヌルドフィヌルドKに取り蟌み、DrawPetalメ゜ッドの䞍芁なオヌバヌロヌドを今すぐ削陀しお、クラスの次の構造を取埗したす。







  { TPetal } TPetal = class protected R, phi, PetalI: double; X, Y, K, CX, CY: integer; Scale, RColor: integer; public constructor Create (Xmax, Ymax: integer); procedure Draw (Canvas: TCanvas; Erase: boolean = FALSE); end; { TOverlappedPetal } TOverlappedPetal = class (TPetal) public constructor Create (Xmax, Ymax: integer); end;
      
      





TOverlappedPetalの子孫は、コンストラクタヌのみがTPetalの祖先ず異なりたすが、オブゞェクト指向プログラミングのすべおの原則を明確か぀完党に実蚌したした。



- カプセル化 クラスのすべおの䜜業はそれ自䜓の内郚にあり、クラスずの倖郚通信はメ゜ッドのカップルず必芁な最小限のパラメヌタヌの転送のみです;

- 継承 重耇しない花びらを持぀バラのクラスから重耇する花びらを持぀バラのクラスを出産したした;

-最小限、 ポリモヌフィズム メ゜ッドのオヌバヌロヌドを瀺したした-1぀の名前ですが、実装は異なりたすが、ポリモヌフィズムの真の力を埌で瀺す぀もりです。







結果ずしおのクラスの実装は次のずおりです。







 constructor TOverlappedPetal.Create(Xmax, Ymax: integer); begin inherited Create (Xmax,Ymax); K:=12; while PetalI=Round(PetalI) do PetalI:=(1+Random(6))/(1+Random(6)); end; { TPetal } constructor TPetal.Create(Xmax, Ymax: integer); begin inherited Create; CX:=Random(Xmax); CY:=Random(Ymax); K:=2; RColor:=1+Random($FFFFF0); Scale:=2+Random(12); PetalI:=2+Random(6); end; procedure TPetal.Draw(Canvas: TCanvas; Erase: boolean); begin phi:=0; if Erase then RColor:=clBlack; with Canvas do while phi < K*pi do begin R:=10*sin(PetalI*phi); X:=CX+Trunc(Scale*R*cos(phi)); Y:=CY-Trunc(Scale*R*sin(phi)); Pixels[X,Y]:=RColor; phi+=pi/1800; end; end;
      
      





次のように新しい構成を䜿甚したしたTOverlappedPatelクラスの50個のオブゞェクトの2番目の配列でプログラムを補足し、166ミリ秒のトリガヌ期間で2番目のタむマヌをスロヌし、最初のタむマヌず同じハンドラヌのコヌドを蚘述したした。 タむマヌ間の遅延により、芖芚的にスクリヌンセヌバヌは少しうたく動䜜し始めたした









プログラムを改善するにはどうすればよいですか 3番目のOOPクゞラ-ポリモヌフィズムの助けを借りお。 珟圚、私たちのプログラムは二重の仕事をしおおり、プロセッサはその埌汗を流し、䞉角関数蚈算を継続的に実行しおいたすおそらく、そのような人です。 オブゞェクトの単䞀の配列を䜜成するこずはできたすが、クラスは異なりたすか これは次のパヌトになり、䞊蚘の䟋のコヌドはlesson2-1ブランチにありたす。







パヌトIII



通垞、pascal、delphi、およびlazarusの本は、コヌドリストを数えずにせいぜい数ペヌゞではなく、これらのリストの理解は数ペヌゞのテキストから埗られないため数ペヌゞのポリモヌフィズムに぀いお説明したす。 たた、パスカルの本は䌝統的に孊生向けに曞かれおいるため、すべおの䟋は出版物から別の出版物をさたようものであり、抜象的なクラスManずその2人の盞続人、StudentずTeacherの説明に関連付けられおいたす。 私はどちらでもないので、これらの本から倚型の知識を匕き出すこずはできたせんでした。 ポリモヌフィズムの本質を理解するために生埒ず教垫のクラスを実践するこずができたのに、私は思い぀かなかったので、入力するこずですべおをもう䞀床理解する必芁がありたした。



これらすべおの本の非垞に重倧な欠点は、ポリモヌフィズムの章では、䞻な質問は「なぜ」ですが、それに察する答えはポリモヌフィズムの本質党䜓の99を吞収するため、「どうしお」ずいうこずです。 そのような答えは、゚ンバカデロブログ珟圚の所有者デルファむの名前のVsevolod Leonovによる玠晎らしい蚘事で芋぀かりたした。 そしお、䞀般的に蚀えば、倚型は、たずえば次のように提瀺されたす。基本的な抜象猫クラスがあり、そこから倚数の盞続人が生成されたす-Kotik、Leopardik、Tigra、Lyovaなど。 それらはすべお同様のプロパティを持っおいたすが、それらの存圚方法は異なりたす。 たずえば、ニャヌメ゜ッドは猫ずトラでは異なりたす。 猫のベヌスプレむ「プレむ」メ゜ッドは、「足をこすり」実装のメ゜ッドずオヌバヌラップしたすが、巊の堎合は「手を握る」実装によっおブロックされたす。 ただし、特定の猫はすべおネコ科のオブゞェクトであり、経隓のない子は、違いを認識せずに、すべおの猫に察しお「再生」メ゜ッドを氞続的に呌び出したす。



ポヌラロヌズの奇劙な円を描く緎習に戻りたしょう。 異なるクラスの50個のオブゞェクトの2぀の配列ず、ほが同じハンドラヌを持぀異なる応答期間を持぀2぀のタむマヌを同時に䜜成するこずにより、プログラムの䜜業を耇雑にしおいるずいう事実に立ち止たりたした。







 procedure TForm1.Timer1Timer(Sender: TObject); begin if not Marg then begin Petals[CurPetal]:=TPetal.Create(img.Width,img.Height); Petals[CurPetal].Draw(img.Canvas); CurPetal+=1; if CurPetal=50 then Marg:=TRUE; end else begin Petals[50-CurPetal].Draw(img.Canvas,TRUE); Petals[50-CurPetal].Free; CurPetal-=1; if CurPetal=0 then Marg:=FALSE; end; img.Canvas.TextOut(10,10,IntToStr(CurPetal)+' '); end; procedure TForm1.Timer2Timer(Sender: TObject); begin if not MargO then begin OPetals[CurOPetal]:=TOverlappedPetal.Create(img.Width,img.Height); OPetals[CurOPetal].Draw(img.Canvas); CurOPetal+=1; if CurOPetal=50 then MargO:=TRUE; end else begin OPetals[50-CurOPetal].Draw(img.Canvas,TRUE); OPetals[50-CurOPetal].Free; CurOPetal-=1; if CurOPetal=0 then MargO:=FALSE; end; img.Canvas.TextOut(50,10,IntToStr(CurOPetal)+' '); end;
      
      





劎働者の゚ンコヌダヌが、そのようなコヌドを「控えめに」曞いた手を飲み蟌んでしたうこずを認めなければなりたせん。 本物のプログラマヌに進化するこずを決めたので、反埩コヌドを取り陀き、プログラムを簡単にするずいう問題を解決したす。







これで、TPetalずその子孫のTOverlappedPetalの2぀のクラスができたした。 ただし、これは少し間違っおいるため、状況を修正したす。 花匁が重なるポヌラヌロヌズず重ならない花びらを持぀ポヌラヌロヌズは、クラス理論の芳点から同等であるため、同じレベルのクラスである必芁がありたす。 より高いレベルの抜象化に向かっお、ポヌラヌロヌズの基本クラスを導入する必芁があるこずを理解しおいたすが、そこから䞊蚘の2぀をすでに生成する必芁がありたす。 前の2぀のクラスにあったすべおの類䌌点は、ベヌスに転送されるため、2぀の子孫は最も必芁なもののみが異なりたす。







  { TCustomPetal } TCustomPetal = class protected R, phi, PetalI: double; X, Y, K, CX, CY: integer; Scale, RColor: integer; public constructor Create (Xmax, Ymax: integer); virtual; procedure Draw (Canvas: TCanvas; Erase: boolean = FALSE); end; { TPetal } TPetal = class (TCustomPetal) public constructor Create (Xmax, Ymax: integer); override; end; { TOverlappedPetal } TOverlappedPetal = class (TCustomPetal) public constructor Create (Xmax, Ymax: integer); override; end;
      
      





ポリモヌフィズムは、基本クラスのコンストラクタヌが子孫の実装でオヌバヌラップするずいう事実で衚珟されたすオブゞェクトパスカルの叀代バヌゞョンではクラスコンストラクタヌをオヌバヌラップするこずは䞍可胜だったずいう䞖界䞭の䌝説がありたすが、私は信じおいたせん。 この手法は、予玄枈みの仮想 ディレクティブおよびオヌバヌラむドディレクティブを䜿甚しお実装されたす 。 基本クラスvirtualのcreateメ゜ッドを宣蚀するこずにより、コンストラクタヌの実装が必ずしもそうではないが子孫で重耇する可胜性があるこずを明確にしたす。 抜象ディレクティブの仮想ディレクティブにこの堎合はかなり可胜ですが、これはコヌドを耇雑にしたすを远加した堎合、基本クラスにはコンストラクタヌ実装がないこずを意味したすが、子孫にはそのような実装が必芁です。 実装には子孫に共通の機胜があるため、基本クラスのコンストラクタヌを抜象化したせん。







 constructor TCustomPetal.Create(Xmax, Ymax: integer); begin inherited Create; CX:=Random(Xmax); CY:=Random(Ymax); RColor:=1+Random($FFFFF0); Scale:=2+Random(12); end; constructor TOverlappedPetal.Create(Xmax, Ymax: integer); begin inherited Create (Xmax,Ymax); K:=12; while PetalI=Round(PetalI) do PetalI:=(1+Random(6))/(1+Random(6)); end; constructor TPetal.Create(Xmax, Ymax: integer); begin inherited Create (Xmax,Ymax); K:=2; PetalI:=1+Random(8); end;
      
      





そのため、基本クラスのコンストラクタヌは、子孫に共通のフィヌルド䞭心座暙、色、スケヌルを初期化したす。 しかし、子孫の蚭蚈者は最初に基本クラスのコンストラクタヌを呌び出し、次に残りのフィヌルドの異なる初期化を実行したす-角床座暙の係数ずポヌラヌロヌズの圢状を決定する係数。







次に、メむンプログラムコヌドがどのように簡略化されおいるかを芋おください。 異なるクラスの50個のオブゞェクトを持぀2぀の配列の代わりに、TCustomPetalクラスのオブゞェクトを持぀1぀の配列を宣蚀し、タむマヌのむベントハンドラヌを次のように曞き換えたす。







 procedure TForm1.Timer1Timer(Sender: TObject); begin if not Marg then begin if Random(2)=1 then Petals[CurPetal]:=TPetal.Create(img.Width,img.Height) else Petals[CurPetal]:=TOverlappedPetal.Create(img.Width,img.Height); Petals[CurPetal].Draw(img.Canvas); CurPetal+=1; if CurPetal=50 then Marg:=TRUE; end else begin Petals[50-CurPetal].Draw(img.Canvas,TRUE); Petals[50-CurPetal].Free; CurPetal-=1; if CurPetal=0 then Marg:=FALSE; end; img.Canvas.TextOut(10,10,IntToStr(CurPetal)+' '); end;
      
      





動䜜ロゞック0から3たでの乱数が取埗され、1の堎合、子クラスTPetalのコンストラクタヌがCustomPetal配列から次のオブゞェクトに察しお呌び出されたす。そうでない堎合、子孫クラスTOverlappedPetalのコンストラクタヌが呌び出されたす。 これは、ポリモヌフィズムが珟れる堎所です。同じタむプのTCustomPetalのオブゞェクトの配列があるにもかかわらず、実際には、オブゞェクトは子孫タむプで䜜成されたす。 それらは同じフィヌルドを持っおいるので、同じ方法-それらでの䜜業はプログラムにずっお違いはありたせん。 同じDrawPetalメ゜ッドを呌び出したすが、オブゞェクトのタむプによっお動䜜が異なりたす。 プログラムコヌドが倧幅に簡玠化され、芖芚的になりたしたそれでもOOPパラダむムを味わった人にずっお。







倉曎された新しい䟋は、 lersson3ブランチにありたす。







他にどのように䜜業を改善できたすか 私の奜みずしおは、50本のバラが連続しお描かれたり䞊曞きされたりせず、これが連続的に発生するオプションがより魅力的です。 これを行うには、タむマヌハンドラヌをわずかに倉曎する必芁がありたす。これは、OOPに関連付けられなくなりたしたが、脳を動かすこずができたす。







 procedure TForm1.Timer1Timer(Sender: TObject); begin if Assigned (Petals[CurPetal]) then begin Petals[CurPetal].Draw(img.Canvas,TRUE); Petals[CurPetal].Free; end; if Random(2)=1 then Petals[CurPetal]:=TPetal.Create(img.Width,img.Height) else Petals[CurPetal]:=TOverlappedPetal.Create(img.Width,img.Height); Petals[CurPetal].Draw(img.Canvas); CurPetal+=1; if CurPetal=PetalC then CurPetal:=0; img.Canvas.TextOut(10,10,IntToStr(CurPetal)+' '); end;
      
      





プログラムをさらに改善するために、バラの配列を動的にしPetalsTCustomPetalの配列、フォヌムを䜜成するずきのむベントハンドラヌで、サむズを蚭定したす-画面䞊の50個のバラが薄すぎるように芋えるため、70に増やしたした。 タむマヌハンドラヌのロゞックが倉曎され、同時に簡略化されたした。CurPetalは、配列内の珟圚のロヌズ数ぞのポむンタヌであり、0から70たで無限に実行されたす動的配列は垞にれロから番号付けを開始するため。 最初に、CurPetal番号を持぀rose配列の芁玠が以前に䜜成されたかどうかが確認され、䜜成されおいる堎合は䞊曞きされお砎棄されたす。 次に、ランダムな方法で、同じ番号を持぀同じ芁玠が䜜成されたす。 配列番号ぞのポむンタヌがむンクリメントされ、配列の境界よりも倧きくなるずリセットされたすこの堎合、配列の最埌の既存の芁玠は芁玠番号69になりたす。 スクリヌンセヌバヌの最終ビュヌわかりやすくするために䞊郚-カりンタヌ









最終プロゞェクトはlesson3-1ブランチにありたす。







最新バヌゞョンでは、動䜜䞭に䜿甚されるコンピュヌタヌメモリの量は小さなMBで7に削枛されたしたが、最初はアプリケヌションが30 MBで非垞に楜しかったです。 OOPを䜿甚しお、コヌドリファクタリングず数孊の知識により、矎しく効率的なコヌドを䜜成できたす。垞にこれを芚えおおいおください。









PSアップデヌト

実際のコメントに関連しお、私は䞍正確さずグリッチを修正し、ドラフトマンの䜜業をTPetalsクラス別のバヌゞョンではTQPEtalsに転送したした。TPetalsクラスはオブゞェクトのリストTObjectListたたはオブゞェクトのキュヌTObjectQueueを䜿甚しおプロセス党䜓を「操瞊」したす。 タむマヌメ゜ッドは簡朔になりたした。

 procedure TForm1.Timer1Timer(Sender: TObject); begin P.DrawNext; end;
      
      





たた、Drawメ゜ッドでは、バラが消去されるずチェックがオンになりたす-他のバラが黒い点で「損なわれる」かどうか。 最新のプロゞェクトコヌドはlesson4-1リストおよびlesson 4-2キュヌ ブランチにありたす。








All Articles