Skip to content

Commit bce33a2

Browse files
committed
(ForNeVeR#287) Refactor camera control, fix scaling
1 parent 5bfadf7 commit bce33a2

File tree

12 files changed

+55
-96
lines changed

12 files changed

+55
-96
lines changed

O21.Game/DrawSceneHelper.fs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,34 @@
1-
// SPDX-FileCopyrightText: 2024 O21 contributors <https://github.com/ForNeVeR/O21>
1+
// SPDX-FileCopyrightText: 2024-2025 O21 contributors <https://github.com/ForNeVeR/O21>
22
//
33
// SPDX-License-Identifier: MIT
44

55
namespace O21.Game
66

77
open System.Numerics
8-
open Raylib_CSharp
98
open Raylib_CSharp.Camera.Cam2D
109

1110
module DrawSceneHelper =
12-
let configureCameraTarget (camera:byref<Camera2D>) (window:WindowParameters) =
11+
let private configureCameraTarget (window: WindowParameters) (camera: Camera2D) =
1312
let struct (windowWidth, windowHeight) = window.WindowSizePx
1413
let struct (renderTargetWidth, renderTargetHeight) = window.RenderTargetSize
1514

1615
let cameraTargetX = ((windowWidth |> float32) - (renderTargetWidth |> float32) * camera.Zoom) / -2f / camera.Zoom
1716
let cameraTargetY = ((windowHeight |> float32) - (renderTargetHeight |> float32) * camera.Zoom) / -2f / camera.Zoom
18-
17+
18+
let mutable camera = camera
1919
camera.Target <- Vector2(cameraTargetX, cameraTargetY)
20-
window
21-
22-
let configureCameraZoom (camera:byref<Camera2D>) (window:WindowParameters) =
20+
camera
21+
22+
let private configureCameraZoom (window: WindowParameters) (camera: Camera2D) =
2323
let struct (windowWidth, windowHeight) = window.WindowSizePx
2424
let struct (renderTargetWidth, renderTargetHeight) = window.RenderTargetSize
25-
25+
26+
let mutable camera = camera
2627
camera.Zoom <- min ((windowHeight |> float32) / (renderTargetHeight |> float32))
2728
((windowWidth |> float32) / (renderTargetWidth |> float32))
28-
window
29-
30-
let configureCamera (window:WindowParameters) (camera:byref<Camera2D>) =
31-
configureCameraTarget &camera window |> ignore
32-
configureCameraZoom &camera window |> ignore
33-
()
29+
camera
30+
31+
let ConfigureCamera (window: WindowParameters): Camera2D =
32+
Camera2D(Vector2(0f, 0f), Vector2(0f, 0f), 0f, zoom = 1f)
33+
|> configureCameraZoom window
34+
|> configureCameraTarget window

O21.Game/Game.fs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2024 O21 contributors <https://github.com/ForNeVeR/O21>
1+
// SPDX-FileCopyrightText: 2023-2025 O21 contributors <https://github.com/ForNeVeR/O21>
22
//
33
// SPDX-License-Identifier: MIT
44

@@ -11,6 +11,7 @@ open System.Threading
1111
open System.Threading.Tasks
1212
open JetBrains.Lifetimes
1313
open O21.Game.Engine
14+
open Raylib_CSharp.Camera.Cam2D
1415
open Raylib_CSharp.Colors
1516
open type Raylib_CSharp.Raylib
1617
open type Raylib_CSharp.Rendering.Graphics
@@ -37,6 +38,7 @@ type Game(window: WindowParameters, content: LocalContent, data: U95Data) =
3738
Language = DefaultLanguage
3839
Engine = TickEngine.Create(Instant.Now(), newRandom(), data.Levels[GameRules.StartingLevel])
3940
MusicPlayer = None
41+
Camera = Unchecked.defaultof<_>
4042
}
4143

4244
let mutable state = initialState
@@ -64,15 +66,18 @@ type Game(window: WindowParameters, content: LocalContent, data: U95Data) =
6466
Language = state.Language }
6567

6668
member this.Update() =
67-
let input = Input.Handle(state.Scene.Camera)
69+
let input = Input.Handle(state.Camera)
6870
let time = Instant.Now()
6971

7072
pumpQueue()
7173

7274
let updatedState, event = state.Scene.Update(input, time, state)
73-
75+
7476
state <- updatedState
75-
77+
78+
let camera = DrawSceneHelper.ConfigureCamera { window with RenderTargetSize = state.Scene.RenderTargetSize }
79+
state <- { state with Camera = camera }
80+
7681
let scene: IScene =
7782
match event with
7883
| Some (NavigateTo Scene.MainMenu) -> MainMenuScene.Init(window, content, data)
@@ -98,19 +103,20 @@ type Game(window: WindowParameters, content: LocalContent, data: U95Data) =
98103
state <- { state with SoundsToStartPlaying = Set.empty }
99104

100105
member private _.WithScissorMode(action: unit -> unit) =
101-
let cam = state.Scene.Camera
102-
let W = float32 GameRules.GameScreenWidth * cam.Zoom |> int
103-
let H = float32 GameRules.GameScreenHeight * cam.Zoom |> int
106+
let cam = state.Camera
107+
let struct(x, y) = state.Scene.RenderTargetSize
108+
let W = float32 x * cam.Zoom |> int
109+
let H = float32 y * cam.Zoom |> int
104110
let offsetX = cam.Target.X * cam.Zoom |> int |> Math.Abs
105111
let offsetY = cam.Target.Y * cam.Zoom |> int |> Math.Abs
106112
BeginScissorMode(offsetX, offsetY, W, H)
107113
action()
108114
EndScissorMode()
109-
115+
110116
member this.Draw() =
111117
BeginDrawing()
112118
ClearBackground(Color.White)
113-
BeginMode2D(state.Scene.Camera)
119+
BeginMode2D state.Camera
114120
this.WithScissorMode(fun () ->
115121
state.Scene.Draw state)
116122
EndMode2D()

O21.Game/Loader.fs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
// SPDX-FileCopyrightText: 2024 O21 contributors <https://github.com/ForNeVeR/O21>
1+
// SPDX-FileCopyrightText: 2024-2025 O21 contributors <https://github.com/ForNeVeR/O21>
22
//
33
// SPDX-License-Identifier: MIT
44

55
namespace O21.Game
66

77
open System.Threading.Tasks
8-
open Raylib_CSharp.Camera.Cam2D
9-
108
open JetBrains.Lifetimes
119

1210
type ProgressReport = string * float
@@ -33,4 +31,3 @@ type ILoadingScene<'TInput, 'Output> =
3331
abstract Load: Lifetime * LoadController -> Task<'Output> // TODO[#103]: Support cancellation
3432
abstract Update: O21.Game.Input * LoadController -> unit
3533
abstract Draw: unit -> unit
36-
abstract Camera: Camera2D with get

O21.Game/Loading/DisclaimerScene.fs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2024 O21 contributors <https://github.com/ForNeVeR/O21>
1+
// SPDX-FileCopyrightText: 2024-2025 O21 contributors <https://github.com/ForNeVeR/O21>
22
//
33
// SPDX-License-Identifier: MIT
44

@@ -8,7 +8,6 @@ open System.Numerics
88
open System.Threading.Tasks
99

1010
open Microsoft.FSharp.Core
11-
open Raylib_CSharp.Camera.Cam2D
1211
open Raylib_CSharp.Colors
1312
open type Raylib_CSharp.Fonts.TextManager
1413
open type Raylib_CSharp.Raylib
@@ -17,7 +16,6 @@ open type Raylib_CSharp.Rendering.Graphics
1716
open O21.Game
1817
open O21.Game.Localization
1918
open O21.Game.Scenes
20-
open Raylib_CSharp
2119

2220
type DisclaimerScene(window: WindowParameters, u95DataDirectory: string) =
2321
let onDiskChecker = task {
@@ -48,8 +46,6 @@ type DisclaimerScene(window: WindowParameters, u95DataDirectory: string) =
4846
0f,
4947
Color.White
5048
)
51-
let mutable camera : Camera2D = Camera2D(Vector2(0f, 0f), Vector2(0f, 0f), 0f, zoom = 1f)
52-
5349
let doLayout() =
5450
let struct (windowWidth, windowHeight) = window.RenderTargetSize
5551
let screenWidth = float32 windowWidth
@@ -106,18 +102,13 @@ type DisclaimerScene(window: WindowParameters, u95DataDirectory: string) =
106102

107103
interface ILoadingScene<LocalContent, unit> with
108104

109-
member this.Camera: Camera2D = camera
110-
111105
member _.Init newContent =
112106
content <- newContent
113-
camera <- Camera2D(Vector2(0f, 0f), Vector2(0f, 0f), 0f, zoom = 1f)
114107

115108
// TODO[#98]: Update this layout on language change
116109
doLayout()
117110

118111
member this.Draw() =
119-
DrawSceneHelper.configureCamera window &camera
120-
121112
ClearBackground(Color.Black)
122113

123114
match areFilesOnDisk with

O21.Game/Loading/LoadingLoop.fs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2024 O21 contributors <https://github.com/ForNeVeR/O21>
1+
// SPDX-FileCopyrightText: 2024-2025 O21 contributors <https://github.com/ForNeVeR/O21>
22
//
33
// SPDX-License-Identifier: MIT
44

@@ -58,10 +58,11 @@ let private processWithPumping(lt, window: WindowParameters, scene: ILoadingScen
5858
| true, action -> action()
5959
| false, _ -> ()
6060

61-
scene.Update(Input.Handle(scene.Camera), controller)
61+
let camera = DrawSceneHelper.ConfigureCamera window
62+
scene.Update(Input.Handle(camera), controller)
6263

6364
BeginDrawing()
64-
BeginMode2D(scene.Camera)
65+
BeginMode2D camera
6566
try
6667
window.Update()
6768
scene.Draw()

O21.Game/Loading/LoadingSceneBase.fs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2024 O21 contributors <https://github.com/ForNeVeR/O21>
1+
// SPDX-FileCopyrightText: 2024-2025 O21 contributors <https://github.com/ForNeVeR/O21>
22
//
33
// SPDX-License-Identifier: MIT
44

@@ -10,7 +10,6 @@ open System.Threading.Tasks
1010

1111
open JetBrains.Lifetimes
1212
open O21.Game.RaylibUtils
13-
open Raylib_CSharp.Camera.Cam2D
1413
open Raylib_CSharp.Colors
1514
open type Raylib_CSharp.Raylib
1615
open type Raylib_CSharp.Fonts.TextManager
@@ -25,7 +24,6 @@ type LoadingSceneBase<'Output>(window: WindowParameters) =
2524

2625
let mutable loadingProgress = 0.0
2726
let mutable loadingStatus = ""
28-
let mutable camera = Camera2D(Vector2(0f, 0f), Vector2(0f, 0f), 0f, zoom = 1f)
2927

3028
let renderImage content =
3129
let texture = content.LoadingTexture
@@ -66,14 +64,10 @@ type LoadingSceneBase<'Output>(window: WindowParameters) =
6664
abstract Load: Lifetime * LoadController -> Task<'Output>
6765

6866
interface ILoadingScene<LocalContent, 'Output> with
69-
member this.Camera: Camera2D = camera
70-
7167
member _.Init loadedContent = content <- loadedContent
7268
member this.Load(lt, controller) = this.Load(lt, controller)
7369

7470
member _.Draw() =
75-
DrawSceneHelper.configureCamera window &camera
76-
7771
ClearBackground(Color.Black)
7872
renderImage content
7973
renderText content

O21.Game/Loading/PreloadingScene.fs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
// SPDX-FileCopyrightText: 2024 O21 contributors <https://github.com/ForNeVeR/O21>
1+
// SPDX-FileCopyrightText: 2024-2025 O21 contributors <https://github.com/ForNeVeR/O21>
22
//
33
// SPDX-License-Identifier: MIT
44

55
namespace O21.Game.Loading
66

7-
open System.Numerics
8-
open Raylib_CSharp.Camera.Cam2D
97
open Raylib_CSharp.Colors
108
open type Raylib_CSharp.Raylib
119
open type Raylib_CSharp.Rendering.Graphics
@@ -15,8 +13,6 @@ open O21.Game
1513
type PreloadingScene(window: WindowParameters) =
1614

1715
interface ILoadingScene<unit, LocalContent> with
18-
member this.Camera: Camera2D = Camera2D(Vector2(0f, 0f), Vector2(0f, 0f), 0f, zoom = 1f)
19-
2016
member this.Init _ = ()
2117
member this.Load(lt, _) = LocalContent.Load(lt, window)
2218

O21.Game/Scenes/GameOverScene.fs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
// SPDX-FileCopyrightText: 2024 O21 contributors <https://github.com/ForNeVeR/O21>
1+
// SPDX-FileCopyrightText: 2024-2025 O21 contributors <https://github.com/ForNeVeR/O21>
22
//
33
// SPDX-License-Identifier: MIT
44

55
namespace O21.Game.Scenes
66

77
open System.Numerics
88

9-
open Raylib_CSharp.Camera.Cam2D
109
open type Raylib_CSharp.Raylib
1110

1211
open O21.Game
@@ -23,7 +22,6 @@ type GameOverScene =
2322
Content: LocalContent
2423
MinimizeButton: MinimizeButton
2524
Window: WindowParameters
26-
mutable Camera: Camera2D
2725
}
2826

2927
with
@@ -33,19 +31,14 @@ type GameOverScene =
3331
Content = content
3432
MinimizeButton = MinimizeButton.Create(Vector2(193f, 134f), language)
3533
Window = window
36-
Camera = Camera2D(Vector2(0f, 0f), Vector2(0f, 0f), 0f, zoom = 1f)
3734
}
3835

3936
interface IScene with
40-
member this.Camera = this.Camera
37+
member this.RenderTargetSize = 640, 480
4138

4239
member this.Draw(state) =
4340
let x,y = 188, 129
44-
45-
DrawSceneHelper.configureCamera
46-
{ this.Window with RenderTargetSize = (600, 480) }
47-
&this.Camera
48-
41+
4942
WindowRenderer.render(x, y)
5043
this.MinimizeButton.Render()
5144
DrawTexture(state.U95Data.Sprites.Bonuses.LifeBonus, x+23, y+45, Color.White)
@@ -57,15 +50,16 @@ type GameOverScene =
5750
float32 (this.Content.UiFontRegular.BaseSize-5),
5851
0f,
5952
Color.Black)
60-
53+
6154
member this.Update(input, _, state) =
6255
let scene =
6356
{ this with
6457
OkButton = this.OkButton.Update(input, state.Language)
65-
MinimizeButton = this.MinimizeButton.Update input
58+
MinimizeButton = this.MinimizeButton.Update input
6659
}
6760
let navigationEvent =
6861
if this.OkButton.IsClicked then Some (NavigateTo Scene.MainMenu)
6962
elif this.MinimizeButton.IsClicked then Some (NavigateTo Scene.Play)
7063
else None
7164
{ state with Scene = scene }, navigationEvent
65+

O21.Game/Scenes/HelpScene.fs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
// SPDX-FileCopyrightText: 2024 O21 contributors <https://github.com/ForNeVeR/O21>
1+
// SPDX-FileCopyrightText: 2024-2025 O21 contributors <https://github.com/ForNeVeR/O21>
22
//
33
// SPDX-License-Identifier: MIT
44

55
namespace O21.Game.Scenes
66

77
open System.Numerics
88

9-
open Raylib_CSharp.Camera.Cam2D
109
open Raylib_CSharp.Colors
1110
open Raylib_CSharp.Interact
1211
open type Raylib_CSharp.Raylib
@@ -27,9 +26,7 @@ type HelpScene = {
2726
TotalHeight: float32
2827
HelpDocument: DocumentFragment[]
2928
Window: WindowParameters
30-
mutable Camera: Camera2D
31-
32-
} with
29+
} with
3330

3431
static member Init(
3532
window: WindowParameters,
@@ -43,7 +40,6 @@ type HelpScene = {
4340
TotalHeight = HelpScene.GetFragmentsHeight content helpDocument
4441
HelpDocument = helpDocument
4542
Window = window
46-
Camera = Camera2D(Vector2(0f, 0f), Vector2(0f, 0f), 0f, zoom = 1f)
4743
}
4844

4945
static member private GetScrollMomentum(input: Input) =
@@ -87,9 +83,8 @@ type HelpScene = {
8783

8884
fragmentsHeight
8985

90-
interface IScene with
91-
member this.Camera= this.Camera
92-
86+
interface IScene with
87+
member this.RenderTargetSize = this.Window.RenderTargetSize
9388
member this.Update(input, _, state) =
9489
let mutable fragmentsHeight = this.TotalHeight
9590
let renderHeight = GetRenderHeight() / 2 |> float32
@@ -116,8 +111,6 @@ type HelpScene = {
116111
let mutable x = 0f
117112
let mutable currentLineHeight = 0f
118113

119-
DrawSceneHelper.configureCamera this.Window &this.Camera
120-
121114
for fragment in this.HelpDocument do
122115
match fragment with
123116
| DocumentFragment.Text(style, text) ->

0 commit comments

Comments
 (0)