From ba40d8901a146f1404f28a910c9f05050e646922 Mon Sep 17 00:00:00 2001 From: phomm Date: Fri, 12 Jun 2026 15:00:25 +0200 Subject: [PATCH 1/6] reworked images component and weapons images usage --- code/gameentities.pas | 4 +-- code/gameviewformula.pas | 4 +-- code/imagescomponent.pas | 41 +++++++++++---------- code/roomcomponent.pas | 2 +- data/images.castle-component | 63 ++++++++++++++++++++------------- data/room.castle-user-interface | 24 +------------ 6 files changed, 67 insertions(+), 71 deletions(-) diff --git a/code/gameentities.pas b/code/gameentities.pas index e8e5dc5..aacf7b1 100644 --- a/code/gameentities.pas +++ b/code/gameentities.pas @@ -143,8 +143,6 @@ TMap = class(TComponent) const GameSeconds: array[NDifficulty] of Integer = (240, 360, 480, 600); WeaponToOperation: array[NHeroWeapon] of string = ('', '+', '-', '*'); - WeaponFileNames: array[Succ(Low(NHeroWeapon))..High(NHeroWeapon)] of string = - ('weapon-shuriken.png', 'weapon-kunai.png', 'weapon-star.png'); implementation @@ -447,7 +445,7 @@ constructor TWeaponLoot.Create(AOwner: TComponent; AWeapon: NHeroWeapon); begin inherited Create(AOwner); FWeapon := AWeapon; - FAssetId := 'castle-data:/resources/' + WeaponFileNames[AWeapon]; + FAssetId := Images.WeaponUrl(Ord(AWeapon)); end; function TWeaponLoot.GetVisual(): string; diff --git a/code/gameviewformula.pas b/code/gameviewformula.pas index 8c9ae4e..fcf6dcf 100644 --- a/code/gameviewformula.pas +++ b/code/gameviewformula.pas @@ -52,7 +52,7 @@ implementation // Castle castlewindow, castlelog, castleglimages, castlecolors, // Own - gameviewgame, Common; + gameviewgame, Common, imagescomponent; constructor TViewFormula.Create(AOwner: TComponent); begin @@ -86,7 +86,7 @@ procedure TViewFormula.Resume; if AMarked then begin LButton.ImageScale := 0.2; - LButton.Image.Url := 'castle-data:/resources/' + WeaponFileNames[Weapon]; + LButton.Image.Url := Images.WeaponUrl(Ord(Weapon)); end else begin diff --git a/code/imagescomponent.pas b/code/imagescomponent.pas index d26f657..8367dd8 100644 --- a/code/imagescomponent.pas +++ b/code/imagescomponent.pas @@ -8,7 +8,7 @@ interface // System Classes, Generics.Collections, // Castle - CastleTerrain; + Castlefonts; type @@ -20,11 +20,12 @@ TImagesComponent = class(TComponent) private class var FInstance: TImagesComponent; private - FImages: TArray; + FActorImages: TArray; + FWeaponImages: TArray; public constructor Create(AOwner: TComponent); override; - destructor Destroy(); override; function ImageUrl(APicture: NActorPicture): string; + function WeaponUrl(AWeaponIndex: Integer): string; end; function Images(): TImagesComponent; @@ -37,7 +38,7 @@ implementation // Castle CastleComponentSerialize, castlelog, // Own - Common, gameoptions + Common, gameoptions, gameentities ; function Images(): TImagesComponent; @@ -50,17 +51,25 @@ function Images(): TImagesComponent; constructor TImagesComponent.Create(AOwner: TComponent); procedure FetchImages(); var - LIndex: NActorPicture; - LImage: TCastleTerrainImage; + LIndex: Integer; + LImage: TCastleBitmapFont; begin - Setlength(FImages, Ord(High(NActorPicture)) + 1); - for LIndex := Low(NActorPicture) to High(NActorPicture) do + Setlength(FActorImages, Ord(High(NActorPicture)) + 1); + Setlength(FWeaponImages, Ord(High(NHeroWeapon)) + 1); + for LIndex := Ord(Low(NActorPicture)) to Ord(High(NActorPicture)) do begin - LImage := FindComponent(EnumName(TypeInfo(NActorPicture), Ord(LIndex))) as TCastleTerrainImage; + LImage := FindComponent(EnumName(TypeInfo(NActorPicture), Ord(LIndex))) as TCastleBitmapFont; if not Assigned(LImage) then Continue; - FImages[Ord(LIndex)] := LImage; + FActorImages[LIndex] := LImage; end; + for LIndex := Ord(Low(NHeroWeapon)) to Ord(High(NHeroWeapon)) do + begin + LImage := FindComponent('Weapon' + EnumName(TypeInfo(NHeroWeapon), Ord(LIndex))) as TCastleBitmapFont; + if not Assigned(LImage) then + Continue; + FWeaponImages[LIndex] := LImage; + end; end; begin inherited Create(AOwner); @@ -68,18 +77,14 @@ constructor TImagesComponent.Create(AOwner: TComponent); FetchImages(); end; -destructor TImagesComponent.Destroy(); -var - I: Integer; +function TImagesComponent.ImageUrl(APicture: NActorPicture): string; begin - for I := Low(FImages) to High(FImages) do - FreeAndNil(FImages[I]); - inherited Destroy(); + Result := FActorImages[Ord(APicture)].ImageUrl; end; -function TImagesComponent.ImageUrl(APicture: NActorPicture): string; +function TImagesComponent.WeaponUrl(AWeaponIndex: Integer): string; begin - Result := FImages[Ord(APicture)].Url; + Result := FWeaponImages[AWeaponIndex].ImageUrl; end; initialization diff --git a/code/roomcomponent.pas b/code/roomcomponent.pas index 9706d00..e8d25e3 100644 --- a/code/roomcomponent.pas +++ b/code/roomcomponent.pas @@ -17,7 +17,7 @@ TRoomComponent = class(TCastleUserInterface) published ControlRoom: TCastleButton; ImageRight, ImageLeft, ImageHeroWeapon: TCastleImageControl; - {LabelRight,} LabelLeft, LabelRight1, LabelRight2, LabelRight3: TCastleLabel; + LabelLeft, LabelRight1, LabelRight2, LabelRight3: TCastleLabel; public constructor Create(AOwner: TComponent); override; procedure SetEnemy(AEnemy: TActor); diff --git a/data/images.castle-component b/data/images.castle-component index 78f4ca9..d99cc7f 100644 --- a/data/images.castle-component +++ b/data/images.castle-component @@ -3,44 +3,59 @@ "Name" : "Component1", "$NonVisualComponents" : [ { - "$$ClassName" : "TCastleTerrainImage", - "Name" : "Hero", - "Url" : "castle-data:/resources/hero-samurai.png" + "$$ClassName" : "TCastleBitmapFont", + "ImageUrl" : "castle-data:/resources/hero-samurai.png", + "Name" : "Hero" }, { - "$$ClassName" : "TCastleTerrainImage", - "Name" : "Boss", - "Url" : "castle-data:/resources/dragon.png" + "$$ClassName" : "TCastleBitmapFont", + "ImageUrl" : "castle-data:/resources/dragon.png", + "Name" : "Boss" }, { - "$$ClassName" : "TCastleTerrainImage", - "Name" : "Enemy1", - "Url" : "castle-data:/resources/enemy-yokai.png" + "$$ClassName" : "TCastleBitmapFont", + "ImageUrl" : "castle-data:/resources/enemy-yokai.png", + "Name" : "Enemy1" }, { - "$$ClassName" : "TCastleTerrainImage", - "Name" : "Enemy2", - "Url" : "castle-data:/resources/enemy-yurei.png" + "$$ClassName" : "TCastleBitmapFont", + "ImageUrl" : "castle-data:/resources/enemy-yurei.png", + "Name" : "Enemy2" }, { - "$$ClassName" : "TCastleTerrainImage", - "Name" : "Enemy3", - "Url" : "castle-data:/resources/enemy-ninja.png" + "$$ClassName" : "TCastleBitmapFont", + "ImageUrl" : "castle-data:/resources/enemy-ninja.png", + "Name" : "Enemy3" }, { - "$$ClassName" : "TCastleTerrainImage", - "Name" : "Blood", - "Url" : "castle-data:/resources/blood_splat.png" + "$$ClassName" : "TCastleBitmapFont", + "ImageUrl" : "castle-data:/resources/blood_splat.png", + "Name" : "Blood" }, { - "$$ClassName" : "TCastleTerrainImage", - "Name" : "MiniBoss1", - "Url" : "castle-data:/resources/mini-boss-oni.png" + "$$ClassName" : "TCastleBitmapFont", + "ImageUrl" : "castle-data:/resources/mini-boss-oni.png", + "Name" : "MiniBoss1" }, { - "$$ClassName" : "TCastleTerrainImage", - "Name" : "MiniBoss2", - "Url" : "castle-data:/resources/mini-boss-shinigami.png" + "$$ClassName" : "TCastleBitmapFont", + "ImageUrl" : "castle-data:/resources/mini-boss-shinigami.png", + "Name" : "MiniBoss2" + }, + { + "$$ClassName" : "TCastleBitmapFont", + "ImageUrl" : "castle-data:/resources/weapon-shuriken.png", + "Name" : "WeaponPlus" + }, + { + "$$ClassName" : "TCastleBitmapFont", + "ImageUrl" : "castle-data:/resources/weapon-kunai.png", + "Name" : "WeaponMinus" + }, + { + "$$ClassName" : "TCastleBitmapFont", + "ImageUrl" : "castle-data:/resources/weapon-star.png", + "Name" : "WeaponMultiply" } ] } \ No newline at end of file diff --git a/data/room.castle-user-interface b/data/room.castle-user-interface index 8e5ee29..c2a71ca 100644 --- a/data/room.castle-user-interface +++ b/data/room.castle-user-interface @@ -45,28 +45,6 @@ "VerticalAnchorSelf" : "vpTop", "Width" : 6.4000000000000000E+001 }, - { - "$$ClassName" : "TCastleLabel", - "Alignment" : "hpMiddle", - "BorderColorPersistent" : { - "$$ClassName" : "TCastleColorPersistent", - "Alpha" : 1.0000000000000000E+000 - }, - "Exists" : false, - "FontSize" : 3.5000000000000000E+001, - "HorizontalAnchorParent" : "hpMiddle", - "HorizontalAnchorSelf" : "hpMiddle", - "Html" : true, - "Name" : "LabelRight", - "Text" : [ - "R" - ], - "TranslationPersistent" : { - "$$ClassName" : "TCastleVector2Persistent", - "Y" : 5.0000000000000000E+000 - }, - "WidthFraction" : 1.0000000000000000E+000 - }, { "$$ClassName" : "TCastleHorizontalGroup", "HorizontalAnchorParent" : "hpMiddle", @@ -191,7 +169,7 @@ "Stretch" : true, "TranslationPersistent" : { "$$ClassName" : "TCastleVector2Persistent", - "Y" : -2.9999998092651367E+001 + "Y" : -3.0000000000000000E+001 }, "VerticalAnchorParent" : "vpTop", "VerticalAnchorSelf" : "vpTop", From 0e0e8b53be6b792d94c38316a2f4da83aade7e5f Mon Sep 17 00:00:00 2001 From: phomm Date: Thu, 18 Jun 2026 14:15:44 +0200 Subject: [PATCH 2/6] tutorial and all difficulties are picked on start --- code/gameentities.pas | 12 +++---- code/gameoptions.pas | 2 +- code/gameviewdefeat.pas | 4 ++- code/gameviewgame.pas | 6 ++-- code/gameviewleaders.pas | 6 ++-- code/gameviewmain.pas | 40 ++++++++++++---------- code/gameviewwin.pas | 4 ++- code/models.pas | 2 +- data/gameviewcredits.castle-user-interface | 3 +- data/gameviewgame.castle-user-interface | 2 +- data/gameviewmain.castle-user-interface | 19 +++++++++- 11 files changed, 62 insertions(+), 38 deletions(-) diff --git a/code/gameentities.pas b/code/gameentities.pas index aacf7b1..8291776 100644 --- a/code/gameentities.pas +++ b/code/gameentities.pas @@ -107,7 +107,7 @@ TTower = class(TComponent) TMap = class(TComponent) private FTowers: TObjectList; - FDifficulty: NDifficulty; + FDifficulty: Integer; FLastTower, FLastStock, FHeroTowerIndex, FHeroStockIndex, FTargetTower, FTargetStock: Integer; FHero: THero; FHeroRoom: TRoom; @@ -141,7 +141,7 @@ TMap = class(TComponent) end; const - GameSeconds: array[NDifficulty] of Integer = (240, 360, 480, 600); + GameSeconds: array[NDifficulty] of Integer = (0, 240, 360, 480, 600); WeaponToOperation: array[NHeroWeapon] of string = ('', '+', '-', '*'); implementation @@ -265,8 +265,8 @@ constructor TMap.Create(AOwner: TComponent); FMap := Self; FHero := THero.Create(nil); FTowers := TObjectList.Create(True); - FDifficulty := Difficulty(); - FLastTower := IIF(IsSchool(), 2, 3 + Ord(FDifficulty)); + FDifficulty := Ord(Difficulty()) - 1; + FLastTower := IIF(IsSchool(), 2, 3 + FDifficulty); FLastStock := Min(LastTower + 3, 8); FBoss := TBoss.Create(nil, LastTower, FLastStock); for T := 1 to LastTower do @@ -417,7 +417,7 @@ function TMap.Score(ATimeLeft: Integer): Integer; function TMap.BossCap(): Integer; begin - Result := FBoss.Level * 95 div 100 - (Random(5) + 5) * (Ord(Difficulty) + 1) + Result := FBoss.Level * 95 div 100 - (Random(5) + 5) * (FDifficulty + 1) end; constructor TEnemy.Create(AOwner: TComponent; ATower, AStock: Integer); @@ -504,7 +504,7 @@ function TBoss.CalcLevel(ATower, AStock: Integer): Integer; begin if IsSchool() then Exit(SchoolBossLevel); - case Difficulty of + case Difficulty() of gdEasy: Result := 444; gdNormal: Result := 1000 + Random(5) * 100 + 40 + ValueOrZero(4); gdHard: Result := 2400 + Random(5) * 10 + ValueOrZero(4); diff --git a/code/gameoptions.pas b/code/gameoptions.pas index 392d2f6..e3c5e79 100644 --- a/code/gameoptions.pas +++ b/code/gameoptions.pas @@ -7,7 +7,7 @@ interface uses Classes, generics.collections; type - NDifficulty = (gdEasy, gdNormal, gdHard, gdInsane); + NDifficulty = (gdTutorial, gdEasy, gdNormal, gdHard, gdInsane); /// /// Current Difficulty, default is Easy diff --git a/code/gameviewdefeat.pas b/code/gameviewdefeat.pas index c71ec66..a8a204e 100644 --- a/code/gameviewdefeat.pas +++ b/code/gameviewdefeat.pas @@ -53,9 +53,11 @@ procedure TViewDefeat.ButtonMenuClick(Sender: TObject); procedure TViewDefeat.BackToMenu(); begin + { if IsSchool() then Container.View := ViewCredits else + } Container.View := ViewMain; end; @@ -67,7 +69,7 @@ function TViewDefeat.Press(const Event: TInputPressRelease): Boolean; if Event.IsKey(keyEscape) or Event.IsKey(keyEnter) or Event.IsKey(keyBackSpace) then begin BackToMenu(); - Exit(true); // key was handled + Exit(True); // key was handled end; end; diff --git a/code/gameviewgame.pas b/code/gameviewgame.pas index dd44240..f842519 100644 --- a/code/gameviewgame.pas +++ b/code/gameviewgame.pas @@ -155,7 +155,7 @@ procedure TViewGame.Start(); begin LRoomComponent := TRoomComponent.Create(LGroupTower); LRoomUI := FactoryRoom.ComponentLoad(LGroupTower, LRoomComponent) as TCastleUserInterface; - LRoomComponent.InsertFront(LRoomUI); + LRoomComponent.InsertFront(LRoomUI); LRoomComponent.Name := 'Room' + LTowerIndex.ToString + '_' + LStockIndex.ToString; LGroupTower.InsertFront(LRoomComponent); LRoomComponent.ControlRoom.OnClick := ButtonRoomClick; @@ -304,7 +304,7 @@ procedure TViewGame.ButtonDefeatClick(Sender: TObject); procedure TViewGame.DefeatQuestionYes(Sender: TObject); begin if IsSchool() then - Container.View := ViewCredits + Container.View := ViewMain else Container.View := ViewDefeat; end; @@ -551,7 +551,7 @@ procedure TViewGame.TimerBloodTick(ASender: TObject); if Map.Hero.Dead then begin if IsSchool() then - DialogYesNo(Container, 'You lost, you''d better|follow the guide|try shool again ?', SchoolDefeatYes, SchoolDefeatNo) + DialogYesNo(Container, 'You lost, you''d better|follow the guide|try tutorial again ?', SchoolDefeatYes, SchoolDefeatNo) else Container.View := ViewDefeat end diff --git a/code/gameviewleaders.pas b/code/gameviewleaders.pas index dfe32af..5d84e1c 100644 --- a/code/gameviewleaders.pas +++ b/code/gameviewleaders.pas @@ -75,7 +75,7 @@ procedure TViewLeaders.Start; ButtonMenu.OnClick := ButtonMenuClick; ButtonSync.OnClick := ButtonSyncClick; LCurrentDifficultyName := DifficultyName(Difficulty()); - for LDifficulty in NDifficulty do + for LDifficulty := Succ(Low(NDifficulty)) to High(NDifficulty) do begin LButton := FactoryButton.ComponentLoad(GroupDifficulty) as TCastleButton; LButton.Caption := DifficultyName(LDifficulty); @@ -137,7 +137,6 @@ procedure TViewLeaders.ButtonDifficultyClick(Sender: TObject); procedure TViewLeaders.SwitchDifficulty(AButton: TCastleButton); var LButton: TCastleUserInterface; - LDifficulty: NDifficulty; LLeader: TLeader; LLabel: TCastleLabel; begin @@ -148,9 +147,8 @@ procedure TViewLeaders.SwitchDifficulty(AButton: TCastleButton); // populate the list of leaders for the selected difficulty. GroupLeaders.ClearControls(); - LDifficulty := NDifficulty(FCurrentDifficultyButton.Tag); for LLeader in FLeaders do - if LLeader.Difficulty = Ord(LDifficulty) then + if LLeader.Difficulty = Ord(NDifficulty(FCurrentDifficultyButton.Tag)) - 1 then begin LLabel := TCastleLabel.Create(GroupLeaders); LLabel.Caption := Format('%d %d %s', [LLeader.Number, LLeader.Score, LLeader.Name]); diff --git a/code/gameviewmain.pas b/code/gameviewmain.pas index fdcad44..4bb24e8 100644 --- a/code/gameviewmain.pas +++ b/code/gameviewmain.pas @@ -16,11 +16,10 @@ interface CastleVectors, CastleUIControls, CastleControls, CastleKeysMouse, CastleComponentSerialize; type - { Main view, where most of the application logic takes place. } TViewMain = class(TCastleView) published ButtonStart, ButtonLeaders, ButtonExit, ButtonOptions, ButtonCredits: TCastleButton; - GroupOptions: TCastleUserInterface; + GroupOptions, GroupDifficulty: TCastleUserInterface; SliderMusic, SliderFullscreen, SliderUseTimer: TCastleIntegerSlider; FactoryButton: TCastleComponentFactory; ImageRoomRoof2, ImageRoomRoof3: TCastleImageControl; @@ -81,7 +80,6 @@ procedure TViewMain.Start(); var LDifficulty: NDifficulty; LButton: TCastleButton; - LCurrentDifficultyName: string; begin inherited; SetLength(Buttons, 5); @@ -112,15 +110,14 @@ procedure TViewMain.Start(); SliderUseTimer.Value := Ord(UseTimer()); SliderUseTimer.OnChange := SliderUseTimerChange; - LCurrentDifficultyName := DifficultyName(Difficulty()); for LDifficulty in NDifficulty do begin LButton := FactoryButton.ComponentLoad(GroupOptions) as TCastleButton; LButton.Caption := DifficultyName(LDifficulty); - LButton.Pressed := LButton.Caption = LCurrentDifficultyName; + LButton.Pressed := LButton.Caption = DifficultyName(Difficulty()); LButton.Tag := Ord(LDifficulty); LButton.OnClick := ButtonDifficultyClick; - GroupOptions.InsertFront(LButton); + GroupDifficulty.InsertFront(LButton); end; end; @@ -140,12 +137,19 @@ procedure TViewMain.ButtonDifficultyClick(Sender: TObject); var LButton: TCastleUserInterface; begin - for LButton in GroupOptions do + for LButton in GroupDifficulty do if LButton is TCastleButton then begin TCastleButton(LButton).Pressed := LButton = Sender; if TCastleButton(LButton).Pressed then - SetDifficulty(NDifficulty(TCastleButton(LButton).Tag)); + begin + if LButton.Tag = Ord(gdTutorial) then + SetIsSchool(True) + else + SetDifficulty(NDifficulty(TCastleButton(LButton).Tag)); + GroupOptions.Exists := not GroupOptions.Exists; + Container.View := ViewGame; + end; end; end; @@ -159,19 +163,13 @@ procedure TViewMain.SliderMusicChange(Sender: TObject); end; procedure TViewMain.SliderFullscreenChange(Sender: TObject); -var - LFullscreenValue: Integer; begin - LFullscreenValue := (Sender as TCastleIntegerSlider).Value; - SetFullscreen(LFullscreenValue = 1); + SetFullscreen((Sender as TCastleIntegerSlider).Value = 1); end; procedure TViewMain.SliderUseTimerChange(Sender: TObject); -var - LUseTimerValue: Integer; begin - LUseTimerValue := (Sender as TCastleIntegerSlider).Value; - SetUseTimer(LUseTimerValue = 1); + SetUseTimer((Sender as TCastleIntegerSlider).Value = 1); end; procedure TViewMain.ButtonMotion(const Sender: TCastleUserInterface; const Event: TInputMotion; var Handled: Boolean); @@ -183,6 +181,8 @@ procedure TViewMain.ButtonMotion(const Sender: TCastleUserInterface; const Event (Sender as TCastleButton).ImageScale := 0.08; if Sender <> ButtonOptions then GroupOptions.Exists := False; + if Sender <> ButtonStart then + GroupDifficulty.Exists := False; end; procedure TViewMain.ButtonExitClick(Sender: TObject); @@ -192,7 +192,9 @@ procedure TViewMain.ButtonExitClick(Sender: TObject); procedure TViewMain.ButtonStartClick(Sender: TObject); begin - Container.View := ViewGame; + GroupDifficulty.Exists := not GroupDifficulty.Exists; + if not GroupDifficulty.Exists then + Container.View := ViewGame; end; procedure TViewMain.ButtonLeadersClick(Sender: TObject); @@ -207,12 +209,14 @@ procedure TViewMain.ButtonOptionsClick(Sender: TObject); procedure TViewMain.ButtonCreditsClick(Sender: TObject); begin + { if not IsSchoolDone() then begin SetIsSchool(True); Container.View := ViewGame; end - else + else + } Container.View := ViewCredits; end; diff --git a/code/gameviewwin.pas b/code/gameviewwin.pas index 51fdd23..22c9a55 100644 --- a/code/gameviewwin.pas +++ b/code/gameviewwin.pas @@ -77,9 +77,11 @@ procedure TViewWin.ButtonMenuClick(Sender: TObject); procedure TViewWin.BackToMenu(); begin + { if IsSchool() then Container.View := ViewCredits else + } Container.View := ViewMain; end; @@ -106,7 +108,7 @@ function TViewWin.Press(const Event: TInputPressRelease): Boolean; if Event.IsKey(keyEscape) then begin BackToMenu(); - Exit(true); // key was handled + Exit(True); // key was handled end; end; diff --git a/code/models.pas b/code/models.pas index 1170dae..555b64f 100644 --- a/code/models.pas +++ b/code/models.pas @@ -79,7 +79,7 @@ constructor TSubmitLeader.Create(const AName: string; AScore: Integer; ADifficul Name := AName; Guid := UserGuid; Score := AScore; - Difficulty := Ord(ADifficulty); + Difficulty := Ord(ADifficulty) - 1; CalcHash(); end; diff --git a/data/gameviewcredits.castle-user-interface b/data/gameviewcredits.castle-user-interface index e9ba05d..292f38b 100644 --- a/data/gameviewcredits.castle-user-interface +++ b/data/gameviewcredits.castle-user-interface @@ -73,6 +73,7 @@ "CustomBackgroundPressed" : { "$$ClassName" : "TCastleImagePersistent" }, + "Exists" : false, "FontSize" : 7.0000000000000000E+001, "Image" : { "$$ClassName" : "TCastleImagePersistent" @@ -423,7 +424,7 @@ "Spacing" : 7.0000000000000000E+001, "TranslationPersistent" : { "$$ClassName" : "TCastleVector2Persistent", - "X" : 1.0090648193359375E+003 + "X" : 1.1242473144531250E+003 }, "VerticalAnchorParent" : "vpMiddle", "VerticalAnchorSelf" : "vpMiddle", diff --git a/data/gameviewgame.castle-user-interface b/data/gameviewgame.castle-user-interface index bfaf69e..06f2866 100644 --- a/data/gameviewgame.castle-user-interface +++ b/data/gameviewgame.castle-user-interface @@ -1075,7 +1075,7 @@ "try weapon to make him weaker", "click kunai on the weapon panel!", "It works as minus in formula view", - "Replace multiply sign with it!" + "Replace plus sign with it!" ] }, { diff --git a/data/gameviewmain.castle-user-interface b/data/gameviewmain.castle-user-interface index 9be9f77..b78bd43 100644 --- a/data/gameviewmain.castle-user-interface +++ b/data/gameviewmain.castle-user-interface @@ -391,7 +391,23 @@ "VerticalAnchorParent" : "vpTop", "VerticalAnchorSelf" : "vpTop", "Width" : 3.0000000000000000E+002 - }, + } + ] + }, + { + "$$ClassName" : "TCastleVerticalGroup", + "Exists" : false, + "HorizontalAnchorParent" : "hpMiddle", + "HorizontalAnchorSelf" : "hpMiddle", + "Name" : "GroupDifficulty", + "Spacing" : 4.0000000000000000E+000, + "TranslationPersistent" : { + "$$ClassName" : "TCastleVector2Persistent", + "X" : 1.0000000000000000E+002 + }, + "VerticalAnchorParent" : "vpMiddle", + "VerticalAnchorSelf" : "vpMiddle", + "$Children" : [ { "$$ClassName" : "TCastleButton", "AutoSize" : false, @@ -410,6 +426,7 @@ "CustomBackgroundPressed" : { "$$ClassName" : "TCastleImagePersistent" }, + "Exists" : false, "FontSize" : 5.0000000000000000E+001, "Height" : 8.0000000000000000E+001, "Image" : { From 2b52df3fc4eeaa0408f522d8678bcdbd799c0ef3 Mon Sep 17 00:00:00 2001 From: phomm Date: Thu, 18 Jun 2026 17:00:49 +0200 Subject: [PATCH 3/6] redesigned difficulty buttons --- code/difficultybutton.pas | 60 +++++ code/gameviewleaders.pas | 15 +- code/gameviewmain.pas | 24 +- data/buttonDifficulty.castle-user-interface | 100 +++++++- data/gameviewmain.castle-user-interface | 240 ++++++++++---------- data/resources/marker.png | Bin 0 -> 16518 bytes 6 files changed, 292 insertions(+), 147 deletions(-) create mode 100644 code/difficultybutton.pas create mode 100644 data/resources/marker.png diff --git a/code/difficultybutton.pas b/code/difficultybutton.pas new file mode 100644 index 0000000..dda9ee6 --- /dev/null +++ b/code/difficultybutton.pas @@ -0,0 +1,60 @@ +unit difficultybutton; + +{$mode delphi} + +interface + +uses +// System + Classes, +// Castle + CastleUIControls, CastleControls, CastleKeysMouse, castlescene, +// Own + gameoptions; + +type + TDifficultyButton = class(TCastleUserInterface) + published + ImageMarkerRight, ImageMarkerLeft: TCastleImageControl; + Tutorial, Easy, Normal, Hard, Insane: TCastleFog; + public + procedure Init(ADifficulty: NDifficulty; AButton: TCastleButton; AOnClick: TNotifyEvent); + procedure ButtonDifficultyMotion(const Sender: TCastleUserInterface; const Event: TInputMotion; var Handled: Boolean); + end; + +implementation + +uses +// System + SysUtils, +// Castle + CastleVectors, castleColors, +// Own + gameviewmain, Common; + +procedure TDifficultyButton.Init(ADifficulty: NDifficulty; AButton: TCastleButton; AOnClick: TNotifyEvent); +begin + AButton.Caption := DifficultyName(ADifficulty); + AButton.Tag := Ord(ADifficulty); + AButton.Pressed := AButton.Caption = DifficultyName(Difficulty()); + ImageMarkerLeft.Color := Vector4((AButton.Parent.FindComponent(AButton.Caption) as TCastleFog).Color, 1); + ImageMarkerRight.Color := ImageMarkerLeft.Color; + ImageMarkerRight.Exists := False; + ImageMarkerLeft.Exists := False; + AButton.OnMotion := ButtonDifficultyMotion; + AButton.OnClick := AOnClick; +end; + +procedure TDifficultyButton.ButtonDifficultyMotion(const Sender: TCastleUserInterface; const Event: TInputMotion; var Handled: Boolean); +var + LButton: TCastleUserInterface; +begin + for LButton in Sender.Parent do + if LButton is TCastleButton and (LButton.ControlsCount > 0) then + begin + LButton.Controls[0].Exists := Sender = LButton; + LButton.Controls[1].Exists := Sender = LButton; + end; +end; + +end. diff --git a/code/gameviewleaders.pas b/code/gameviewleaders.pas index 5d84e1c..11a07fc 100644 --- a/code/gameviewleaders.pas +++ b/code/gameviewleaders.pas @@ -48,7 +48,7 @@ implementation // Castle castlewindow, castlelog, // Own - gameoptions, castlerest, gameviewmain + gameoptions, castlerest, gameviewmain, difficultybutton ; constructor TViewLeaders.Create(AOwner: TComponent); @@ -69,22 +69,19 @@ procedure TViewLeaders.Start; var LDifficulty: NDifficulty; LButton: TCastleButton; - LCurrentDifficultyName: string; + LDifficultyButton: TDifficultyButton; begin inherited; ButtonMenu.OnClick := ButtonMenuClick; ButtonSync.OnClick := ButtonSyncClick; - LCurrentDifficultyName := DifficultyName(Difficulty()); for LDifficulty := Succ(Low(NDifficulty)) to High(NDifficulty) do begin - LButton := FactoryButton.ComponentLoad(GroupDifficulty) as TCastleButton; - LButton.Caption := DifficultyName(LDifficulty); - LButton.Pressed := LButton.Caption = LCurrentDifficultyName; + LDifficultyButton := TDifficultyButton.Create(GroupDifficulty); + LButton := FactoryButton.ComponentLoad(GroupDifficulty, LDifficultyButton) as TCastleButton; + GroupDifficulty.InsertFront(LButton); + LDIfficultyButton.Init(LDifficulty, LButton, ButtonDifficultyClick); if LButton.Pressed then FCurrentDifficultyButton := LButton; - LButton.Tag := Ord(LDifficulty); - LButton.OnClick := ButtonDifficultyClick; - GroupDifficulty.InsertFront(LButton); end; GroupLeaders.ClearControls(); end; diff --git a/code/gameviewmain.pas b/code/gameviewmain.pas index 4bb24e8..a5faf1a 100644 --- a/code/gameviewmain.pas +++ b/code/gameviewmain.pas @@ -22,7 +22,7 @@ TViewMain = class(TCastleView) GroupOptions, GroupDifficulty: TCastleUserInterface; SliderMusic, SliderFullscreen, SliderUseTimer: TCastleIntegerSlider; FactoryButton: TCastleComponentFactory; - ImageRoomRoof2, ImageRoomRoof3: TCastleImageControl; + ImageRoomRoof2, ImageRoomRoof3, ImageOptions, ImageDifficulty: TCastleImageControl; public constructor Create(AOwner: TComponent); override; procedure Start(); override; @@ -56,7 +56,7 @@ implementation castlewindow, castlemessages, castlesoundengine, CastleApplicationProperties, castlelog, // Own Common, gameviewgame, gameviewleaders, gameviewcredits, gameentities, gameoptions, - audiocomponent, gameviewdialog + audiocomponent, gameviewdialog, difficultybutton ; constructor TViewMain.Create(AOwner: TComponent); @@ -80,6 +80,7 @@ procedure TViewMain.Start(); var LDifficulty: NDifficulty; LButton: TCastleButton; + LDifficultyButton: TDifficultyButton; begin inherited; SetLength(Buttons, 5); @@ -94,6 +95,8 @@ procedure TViewMain.Start(); for LButton in Buttons do LButton.OnMotion := ButtonMotion; + ImageOptions.OnMotion := ButtonMotion; + ImageDifficulty.OnMotion := ButtonMotion; ButtonExit.OnClick := ButtonExitClick; ButtonStart.OnClick := ButtonStartClick; @@ -112,12 +115,11 @@ procedure TViewMain.Start(); for LDifficulty in NDifficulty do begin - LButton := FactoryButton.ComponentLoad(GroupOptions) as TCastleButton; - LButton.Caption := DifficultyName(LDifficulty); - LButton.Pressed := LButton.Caption = DifficultyName(Difficulty()); - LButton.Tag := Ord(LDifficulty); - LButton.OnClick := ButtonDifficultyClick; + LDifficultyButton := TDifficultyButton.Create(GroupDifficulty); + LButton := FactoryButton.ComponentLoad(GroupDifficulty, LDifficultyButton) as TCastleButton; + WriteLnLog(LButton.ComponentCount.toString); GroupDifficulty.InsertFront(LButton); + LDifficultyButton.Init(LDifficulty, LButton, ButtonDifficultyClick); end; end; @@ -147,7 +149,6 @@ procedure TViewMain.ButtonDifficultyClick(Sender: TObject); SetIsSchool(True) else SetDifficulty(NDifficulty(TCastleButton(LButton).Tag)); - GroupOptions.Exists := not GroupOptions.Exists; Container.View := ViewGame; end; end; @@ -178,6 +179,13 @@ procedure TViewMain.ButtonMotion(const Sender: TCastleUserInterface; const Event begin for LButton in Buttons do LButton.ImageScale := 0; + if not (Sender is TCastleButton) then + begin + Handled := True; + Exit; + end; + + (Sender as TCastleButton).ImageScale := 0.08; (Sender as TCastleButton).ImageScale := 0.08; if Sender <> ButtonOptions then GroupOptions.Exists := False; diff --git a/data/buttonDifficulty.castle-user-interface b/data/buttonDifficulty.castle-user-interface index f0f5f33..1a18ecf 100644 --- a/data/buttonDifficulty.castle-user-interface +++ b/data/buttonDifficulty.castle-user-interface @@ -30,11 +30,97 @@ }, "Name" : "ButtonDifficultyTemplate", "Toggle" : true, - "TranslationPersistent" : { - "$$ClassName" : "TCastleVector2Persistent", - "Y" : -1.5800000000000000E+002 - }, - "VerticalAnchorParent" : "vpTop", - "VerticalAnchorSelf" : "vpTop", - "Width" : 3.0000000000000000E+002 + "Width" : 3.0000000000000000E+002, + "$NonVisualComponents" : [ + { + "$$ClassName" : "TCastleFog", + "ColorPersistent" : { + "$$ClassName" : "TCastleColorRGBPersistent", + "Blue" : 0.0000000000000000E+000, + "Green" : 1.0000000000000000E+000, + "Red" : 0.0000000000000000E+000 + }, + "Name" : "Tutorial" + }, + { + "$$ClassName" : "TCastleFog", + "ColorPersistent" : { + "$$ClassName" : "TCastleColorRGBPersistent", + "Blue" : 1.0000000000000000E+000, + "Green" : 1.0000000000000000E+000, + "Red" : 0.0000000000000000E+000 + }, + "Name" : "Easy" + }, + { + "$$ClassName" : "TCastleFog", + "ColorPersistent" : { + "$$ClassName" : "TCastleColorRGBPersistent", + "Blue" : 1.0000000000000000E+000, + "Green" : 0.0000000000000000E+000, + "Red" : 0.0000000000000000E+000 + }, + "Name" : "Normal" + }, + { + "$$ClassName" : "TCastleFog", + "ColorPersistent" : { + "$$ClassName" : "TCastleColorRGBPersistent", + "Blue" : 1.0000000000000000E+000, + "Green" : 0.0000000000000000E+000, + "Red" : 1.0000000000000000E+000 + }, + "Name" : "Hard" + }, + { + "$$ClassName" : "TCastleFog", + "ColorPersistent" : { + "$$ClassName" : "TCastleColorRGBPersistent", + "Blue" : 0.0000000000000000E+000, + "Green" : 0.0000000000000000E+000, + "Red" : 1.0000000000000000E+000 + }, + "Name" : "Insane" + } + ], + "$Children" : [ + { + "$$ClassName" : "TCastleImageControl", + "Content" : { + "$$ClassName" : "TCastleImagePersistent", + "Url" : "castle-data:/resources/marker.png" + }, + "Height" : 2.0000000000000000E+001, + "Name" : "ImageMarkerLeft", + "Stretch" : true, + "TranslationPersistent" : { + "$$ClassName" : "TCastleVector2Persistent", + "X" : 8.0000000000000000E+000, + "Y" : 2.0000000000000000E+000 + }, + "VerticalAnchorParent" : "vpMiddle", + "VerticalAnchorSelf" : "vpMiddle", + "Width" : 2.0000000000000000E+001 + }, + { + "$$ClassName" : "TCastleImageControl", + "Content" : { + "$$ClassName" : "TCastleImagePersistent", + "Url" : "castle-data:/resources/marker.png" + }, + "Height" : 2.0000000000000000E+001, + "HorizontalAnchorParent" : "hpRight", + "HorizontalAnchorSelf" : "hpRight", + "Name" : "ImageMarkerRight", + "Stretch" : true, + "TranslationPersistent" : { + "$$ClassName" : "TCastleVector2Persistent", + "X" : -1.0000000000000000E+001, + "Y" : 2.0000000000000000E+000 + }, + "VerticalAnchorParent" : "vpMiddle", + "VerticalAnchorSelf" : "vpMiddle", + "Width" : 2.0000000000000000E+001 + } + ] } \ No newline at end of file diff --git a/data/gameviewmain.castle-user-interface b/data/gameviewmain.castle-user-interface index b78bd43..8519fee 100644 --- a/data/gameviewmain.castle-user-interface +++ b/data/gameviewmain.castle-user-interface @@ -321,129 +321,6 @@ } ] }, - { - "$$ClassName" : "TCastleVerticalGroup", - "Exists" : false, - "HorizontalAnchorParent" : "hpMiddle", - "HorizontalAnchorSelf" : "hpMiddle", - "Name" : "GroupOptions", - "Spacing" : 4.0000000000000000E+000, - "TranslationPersistent" : { - "$$ClassName" : "TCastleVector2Persistent", - "X" : 3.5000000000000000E+002, - "Y" : -1.6000000000000000E+002 - }, - "VerticalAnchorParent" : "vpMiddle", - "VerticalAnchorSelf" : "vpMiddle", - "$Children" : [ - { - "$$ClassName" : "TCastleIntegerSlider", - "Background" : { - "$$ClassName" : "TCastleImagePersistent" - }, - "Caption" : "FullScreen", - "Height" : 5.0000000000000000E+001, - "Max" : 1, - "Name" : "SliderFullScreen", - "Thumb" : { - "$$ClassName" : "TCastleImagePersistent" - }, - "VerticalAnchorParent" : "vpTop", - "VerticalAnchorSelf" : "vpTop", - "Width" : 3.0000000000000000E+002 - }, - { - "$$ClassName" : "TCastleIntegerSlider", - "Background" : { - "$$ClassName" : "TCastleImagePersistent" - }, - "Caption" : "GameTimer", - "Height" : 5.0000000000000000E+001, - "Max" : 1, - "Name" : "SliderUseTimer", - "Thumb" : { - "$$ClassName" : "TCastleImagePersistent" - }, - "TranslationPersistent" : { - "$$ClassName" : "TCastleVector2Persistent", - "Y" : -5.4000000000000000E+001 - }, - "VerticalAnchorParent" : "vpTop", - "VerticalAnchorSelf" : "vpTop", - "Width" : 3.0000000000000000E+002 - }, - { - "$$ClassName" : "TCastleIntegerSlider", - "Background" : { - "$$ClassName" : "TCastleImagePersistent" - }, - "Caption" : "Music", - "Height" : 5.0000000000000000E+001, - "Max" : 100, - "Name" : "SliderMusic", - "Thumb" : { - "$$ClassName" : "TCastleImagePersistent" - }, - "TranslationPersistent" : { - "$$ClassName" : "TCastleVector2Persistent", - "Y" : -1.0800000000000000E+002 - }, - "VerticalAnchorParent" : "vpTop", - "VerticalAnchorSelf" : "vpTop", - "Width" : 3.0000000000000000E+002 - } - ] - }, - { - "$$ClassName" : "TCastleVerticalGroup", - "Exists" : false, - "HorizontalAnchorParent" : "hpMiddle", - "HorizontalAnchorSelf" : "hpMiddle", - "Name" : "GroupDifficulty", - "Spacing" : 4.0000000000000000E+000, - "TranslationPersistent" : { - "$$ClassName" : "TCastleVector2Persistent", - "X" : 1.0000000000000000E+002 - }, - "VerticalAnchorParent" : "vpMiddle", - "VerticalAnchorSelf" : "vpMiddle", - "$Children" : [ - { - "$$ClassName" : "TCastleButton", - "AutoSize" : false, - "Caption" : "Difficulty", - "CustomBackground" : true, - "CustomBackgroundDisabled" : { - "$$ClassName" : "TCastleImagePersistent" - }, - "CustomBackgroundFocused" : { - "$$ClassName" : "TCastleImagePersistent" - }, - "CustomBackgroundNormal" : { - "$$ClassName" : "TCastleImagePersistent", - "Url" : "castle-data:/resources/cell-old.png" - }, - "CustomBackgroundPressed" : { - "$$ClassName" : "TCastleImagePersistent" - }, - "Exists" : false, - "FontSize" : 5.0000000000000000E+001, - "Height" : 8.0000000000000000E+001, - "Image" : { - "$$ClassName" : "TCastleImagePersistent" - }, - "Name" : "ButtonDifficulty", - "TextAlignment" : "hpRight", - "TranslationPersistent" : { - "$$ClassName" : "TCastleVector2Persistent", - "Y" : -1.6200000000000000E+002 - }, - "VerticalAnchorParent" : "vpTop", - "VerticalAnchorSelf" : "vpTop", - "Width" : 3.0000000000000000E+002 - } - ] - }, { "$$ClassName" : "TCastleImageControl", "Content" : { @@ -470,6 +347,123 @@ "Name" : "ImageSamuraiRight", "Stretch" : true, "WidthFraction" : 3.0000001192092896E-001 + }, + { + "$$ClassName" : "TCastleImageControl", + "AutoSizeToChildren" : true, + "Content" : { + "$$ClassName" : "TCastleImagePersistent", + "Url" : "castle-data:/resources/formulaback.png" + }, + "HorizontalAnchorParent" : "hpMiddle", + "HorizontalAnchorSelf" : "hpMiddle", + "Name" : "ImageOptions", + "VerticalAnchorParent" : "vpMiddle", + "VerticalAnchorSelf" : "vpMiddle", + "$Children" : [ + { + "$$ClassName" : "TCastleVerticalGroup", + "Exists" : false, + "HorizontalAnchorParent" : "hpMiddle", + "HorizontalAnchorSelf" : "hpMiddle", + "Name" : "GroupOptions", + "Padding" : 5.0000000000000000E+001, + "Spacing" : 4.0000000000000000E+000, + "VerticalAnchorParent" : "vpMiddle", + "VerticalAnchorSelf" : "vpMiddle", + "$Children" : [ + { + "$$ClassName" : "TCastleIntegerSlider", + "Background" : { + "$$ClassName" : "TCastleImagePersistent" + }, + "Caption" : "FullScreen", + "Height" : 5.0000000000000000E+001, + "Max" : 1, + "Name" : "SliderFullScreen", + "Thumb" : { + "$$ClassName" : "TCastleImagePersistent" + }, + "TranslationPersistent" : { + "$$ClassName" : "TCastleVector2Persistent", + "X" : 5.0000000000000000E+001, + "Y" : -5.0000000000000000E+001 + }, + "VerticalAnchorParent" : "vpTop", + "VerticalAnchorSelf" : "vpTop", + "Width" : 3.0000000000000000E+002 + }, + { + "$$ClassName" : "TCastleIntegerSlider", + "Background" : { + "$$ClassName" : "TCastleImagePersistent" + }, + "Caption" : "GameTimer", + "Height" : 5.0000000000000000E+001, + "Max" : 1, + "Name" : "SliderUseTimer", + "Thumb" : { + "$$ClassName" : "TCastleImagePersistent" + }, + "TranslationPersistent" : { + "$$ClassName" : "TCastleVector2Persistent", + "X" : 5.0000000000000000E+001, + "Y" : -1.0400000000000000E+002 + }, + "VerticalAnchorParent" : "vpTop", + "VerticalAnchorSelf" : "vpTop", + "Width" : 3.0000000000000000E+002 + }, + { + "$$ClassName" : "TCastleIntegerSlider", + "Background" : { + "$$ClassName" : "TCastleImagePersistent" + }, + "Caption" : "Music", + "Height" : 5.0000000000000000E+001, + "Max" : 100, + "Name" : "SliderMusic", + "Thumb" : { + "$$ClassName" : "TCastleImagePersistent" + }, + "TranslationPersistent" : { + "$$ClassName" : "TCastleVector2Persistent", + "X" : 5.0000000000000000E+001, + "Y" : -1.5800000000000000E+002 + }, + "VerticalAnchorParent" : "vpTop", + "VerticalAnchorSelf" : "vpTop", + "Width" : 3.0000000000000000E+002 + } + ] + } + ] + }, + { + "$$ClassName" : "TCastleImageControl", + "AutoSizeToChildren" : true, + "Content" : { + "$$ClassName" : "TCastleImagePersistent", + "Url" : "castle-data:/resources/formulaback.png" + }, + "HorizontalAnchorParent" : "hpMiddle", + "HorizontalAnchorSelf" : "hpMiddle", + "Name" : "ImageDifficulty", + "VerticalAnchorParent" : "vpMiddle", + "VerticalAnchorSelf" : "vpMiddle", + "$Children" : [ + { + "$$ClassName" : "TCastleVerticalGroup", + "Exists" : false, + "HorizontalAnchorParent" : "hpMiddle", + "HorizontalAnchorSelf" : "hpMiddle", + "Name" : "GroupDifficulty", + "Padding" : 5.0000000000000000E+001, + "Spacing" : 4.0000000000000000E+000, + "VerticalAnchorParent" : "vpMiddle", + "VerticalAnchorSelf" : "vpMiddle" + } + ] } ] } \ No newline at end of file diff --git a/data/resources/marker.png b/data/resources/marker.png new file mode 100644 index 0000000000000000000000000000000000000000..0f69b3457937e996848602dacccfee794d24908e GIT binary patch literal 16518 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 Date: Thu, 18 Jun 2026 17:02:25 +0200 Subject: [PATCH 4/6] improved design of option sliders --- code/gameviewmain.pas | 5 ++ data/gameviewmain.castle-user-interface | 80 +++++++++++++++++++++++-- 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/code/gameviewmain.pas b/code/gameviewmain.pas index a5faf1a..b74ac7c 100644 --- a/code/gameviewmain.pas +++ b/code/gameviewmain.pas @@ -23,6 +23,7 @@ TViewMain = class(TCastleView) SliderMusic, SliderFullscreen, SliderUseTimer: TCastleIntegerSlider; FactoryButton: TCastleComponentFactory; ImageRoomRoof2, ImageRoomRoof3, ImageOptions, ImageDifficulty: TCastleImageControl; + LabelFullscreen, LabelUseTimer: TCastleLabel; public constructor Create(AOwner: TComponent); override; procedure Start(); override; @@ -109,9 +110,11 @@ procedure TViewMain.Start(); SliderFullscreen.Value := Ord(Fullscreen()); SliderFullscreen.OnChange := SliderFullscreenChange; + SliderFullscreenChange(SliderFullscreen); SliderUseTimer.Value := Ord(UseTimer()); SliderUseTimer.OnChange := SliderUseTimerChange; + SliderUseTimerChange(SliderUseTimer); for LDifficulty in NDifficulty do begin @@ -166,11 +169,13 @@ procedure TViewMain.SliderMusicChange(Sender: TObject); procedure TViewMain.SliderFullscreenChange(Sender: TObject); begin SetFullscreen((Sender as TCastleIntegerSlider).Value = 1); + LabelFullScreen.Caption := 'FullScreen: ' + IIF(FullScreen(), 'On', 'Off'); end; procedure TViewMain.SliderUseTimerChange(Sender: TObject); begin SetUseTimer((Sender as TCastleIntegerSlider).Value = 1); + LabelUseTimer.Caption := 'Timer: ' + IIF(UseTimer(), 'On', 'Off'); end; procedure TViewMain.ButtonMotion(const Sender: TCastleUserInterface; const Event: TInputMotion; var Handled: Boolean); diff --git a/data/gameviewmain.castle-user-interface b/data/gameviewmain.castle-user-interface index 8519fee..eaf9e90 100644 --- a/data/gameviewmain.castle-user-interface +++ b/data/gameviewmain.castle-user-interface @@ -375,9 +375,11 @@ { "$$ClassName" : "TCastleIntegerSlider", "Background" : { - "$$ClassName" : "TCastleImagePersistent" + "$$ClassName" : "TCastleImagePersistent", + "Url" : "castle-data:/resources/cell-old.png" }, "Caption" : "FullScreen", + "DisplayValue" : false, "Height" : 5.0000000000000000E+001, "Max" : 1, "Name" : "SliderFullScreen", @@ -391,14 +393,29 @@ }, "VerticalAnchorParent" : "vpTop", "VerticalAnchorSelf" : "vpTop", - "Width" : 3.0000000000000000E+002 + "Width" : 3.0000000000000000E+002, + "$Children" : [ + { + "$$ClassName" : "TCastleLabel", + "HorizontalAnchorParent" : "hpMiddle", + "HorizontalAnchorSelf" : "hpMiddle", + "Name" : "LabelFullScreen", + "Text" : [ + "FullScreen" + ], + "VerticalAnchorParent" : "vpMiddle", + "VerticalAnchorSelf" : "vpMiddle" + } + ] }, { "$$ClassName" : "TCastleIntegerSlider", "Background" : { - "$$ClassName" : "TCastleImagePersistent" + "$$ClassName" : "TCastleImagePersistent", + "Url" : "castle-data:/resources/cell-old.png" }, "Caption" : "GameTimer", + "DisplayValue" : false, "Height" : 5.0000000000000000E+001, "Max" : 1, "Name" : "SliderUseTimer", @@ -412,12 +429,26 @@ }, "VerticalAnchorParent" : "vpTop", "VerticalAnchorSelf" : "vpTop", - "Width" : 3.0000000000000000E+002 + "Width" : 3.0000000000000000E+002, + "$Children" : [ + { + "$$ClassName" : "TCastleLabel", + "HorizontalAnchorParent" : "hpMiddle", + "HorizontalAnchorSelf" : "hpMiddle", + "Name" : "LabelUseTimer", + "Text" : [ + "Timer" + ], + "VerticalAnchorParent" : "vpMiddle", + "VerticalAnchorSelf" : "vpMiddle" + } + ] }, { "$$ClassName" : "TCastleIntegerSlider", "Background" : { - "$$ClassName" : "TCastleImagePersistent" + "$$ClassName" : "TCastleImagePersistent", + "Url" : "castle-data:/resources/cell-old.png" }, "Caption" : "Music", "Height" : 5.0000000000000000E+001, @@ -461,7 +492,44 @@ "Padding" : 5.0000000000000000E+001, "Spacing" : 4.0000000000000000E+000, "VerticalAnchorParent" : "vpMiddle", - "VerticalAnchorSelf" : "vpMiddle" + "VerticalAnchorSelf" : "vpMiddle", + "$Children" : [ + { + "$$ClassName" : "TCastleButton", + "AutoSize" : false, + "Caption" : "Difficulty", + "CustomBackground" : true, + "CustomBackgroundDisabled" : { + "$$ClassName" : "TCastleImagePersistent" + }, + "CustomBackgroundFocused" : { + "$$ClassName" : "TCastleImagePersistent" + }, + "CustomBackgroundNormal" : { + "$$ClassName" : "TCastleImagePersistent", + "Url" : "castle-data:/resources/cell-old.png" + }, + "CustomBackgroundPressed" : { + "$$ClassName" : "TCastleImagePersistent" + }, + "Exists" : false, + "FontSize" : 5.0000000000000000E+001, + "Height" : 8.0000000000000000E+001, + "Image" : { + "$$ClassName" : "TCastleImagePersistent" + }, + "Name" : "ButtonDifficulty", + "TextAlignment" : "hpRight", + "TranslationPersistent" : { + "$$ClassName" : "TCastleVector2Persistent", + "X" : 5.0000000000000000E+001, + "Y" : -5.0000000000000000E+001 + }, + "VerticalAnchorParent" : "vpTop", + "VerticalAnchorSelf" : "vpTop", + "Width" : 3.0000000000000000E+002 + } + ] } ] } From 621cba1d8dbfe0fdda1b2b432b77da06538fdcc0 Mon Sep 17 00:00:00 2001 From: phomm Date: Thu, 18 Jun 2026 17:38:11 +0200 Subject: [PATCH 5/6] marker image resized --- data/resources/marker.png | Bin 16518 -> 3395 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/data/resources/marker.png b/data/resources/marker.png index 0f69b3457937e996848602dacccfee794d24908e..29a41fdae87a39f46ae8894cccd2c6deacfa7472 100644 GIT binary patch delta 3077 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 Date: Sat, 20 Jun 2026 16:21:41 +0200 Subject: [PATCH 6/6] some more minor improvements --- code/difficultybutton.pas | 2 +- code/gameviewmain.pas | 14 +++-------- data/gameviewcredits.castle-user-interface | 4 ++-- data/gameviewmain.castle-user-interface | 27 +++++++++++++++++++--- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/code/difficultybutton.pas b/code/difficultybutton.pas index dda9ee6..cb6ce50 100644 --- a/code/difficultybutton.pas +++ b/code/difficultybutton.pas @@ -50,7 +50,7 @@ procedure TDifficultyButton.ButtonDifficultyMotion(const Sender: TCastleUserInte LButton: TCastleUserInterface; begin for LButton in Sender.Parent do - if LButton is TCastleButton and (LButton.ControlsCount > 0) then + if (LButton is TCastleButton) and (LButton.ControlsCount > 0) then begin LButton.Controls[0].Exists := Sender = LButton; LButton.Controls[1].Exists := Sender = LButton; diff --git a/code/gameviewmain.pas b/code/gameviewmain.pas index b74ac7c..24a63b9 100644 --- a/code/gameviewmain.pas +++ b/code/gameviewmain.pas @@ -222,15 +222,7 @@ procedure TViewMain.ButtonOptionsClick(Sender: TObject); procedure TViewMain.ButtonCreditsClick(Sender: TObject); begin - { - if not IsSchoolDone() then - begin - SetIsSchool(True); - Container.View := ViewGame; - end - else - } - Container.View := ViewCredits; + Container.View := ViewCredits; end; function TViewMain.Press(const Event: TInputPressRelease): Boolean; @@ -241,12 +233,12 @@ function TViewMain.Press(const Event: TInputPressRelease): Boolean; if Event.IsKey(keyEscape) then begin ButtonExit.DoClick(); - Exit(true); // key was handled + Exit(True); // key was handled end; if Event.IsKey(keyEnter) then begin ButtonStart.DoClick(); - Exit(true); // key was handled + Exit(True); // key was handled end; end; diff --git a/data/gameviewcredits.castle-user-interface b/data/gameviewcredits.castle-user-interface index 292f38b..cc40b67 100644 --- a/data/gameviewcredits.castle-user-interface +++ b/data/gameviewcredits.castle-user-interface @@ -660,8 +660,8 @@ "Enter or Esc/Backspace - answer dialog", "Arrow keys or WASD - move in game", "1-4 or E (before fight) - select weapon", - "E (in Formula dialog) - pick weapon slot", - "Press Enter 4 times - fast battle restart" + "E (Formula dialog) - pick weapon target", + "Press Enter 5 times - fast battle restart" ], "VerticalAnchorParent" : "vpMiddle", "VerticalAnchorSelf" : "vpMiddle" diff --git a/data/gameviewmain.castle-user-interface b/data/gameviewmain.castle-user-interface index eaf9e90..9ff8184 100644 --- a/data/gameviewmain.castle-user-interface +++ b/data/gameviewmain.castle-user-interface @@ -384,7 +384,14 @@ "Max" : 1, "Name" : "SliderFullScreen", "Thumb" : { - "$$ClassName" : "TCastleImagePersistent" + "$$ClassName" : "TCastleImagePersistent", + "ColorPersistent" : { + "$$ClassName" : "TCastleColorPersistent", + "Blue" : 4.8627451062202454E-001, + "Green" : 6.9019609689712524E-001, + "Red" : 8.3529412746429443E-001 + }, + "Url" : "castle-data:/resources/marker.png" }, "TranslationPersistent" : { "$$ClassName" : "TCastleVector2Persistent", @@ -420,7 +427,14 @@ "Max" : 1, "Name" : "SliderUseTimer", "Thumb" : { - "$$ClassName" : "TCastleImagePersistent" + "$$ClassName" : "TCastleImagePersistent", + "ColorPersistent" : { + "$$ClassName" : "TCastleColorPersistent", + "Blue" : 4.8627451062202454E-001, + "Green" : 6.9019609689712524E-001, + "Red" : 8.3529412746429443E-001 + }, + "Url" : "castle-data:/resources/marker.png" }, "TranslationPersistent" : { "$$ClassName" : "TCastleVector2Persistent", @@ -455,7 +469,14 @@ "Max" : 100, "Name" : "SliderMusic", "Thumb" : { - "$$ClassName" : "TCastleImagePersistent" + "$$ClassName" : "TCastleImagePersistent", + "ColorPersistent" : { + "$$ClassName" : "TCastleColorPersistent", + "Blue" : 4.8627451062202454E-001, + "Green" : 6.9019609689712524E-001, + "Red" : 8.3529412746429443E-001 + }, + "Url" : "castle-data:/resources/marker.png" }, "TranslationPersistent" : { "$$ClassName" : "TCastleVector2Persistent",