|
| 1 | +# Camera |
| 2 | + |
| 3 | +When the stage is large and the game's display area is small, we cannot show the complete stage content to users. We use Camera to control which areas of content the users can see. |
| 4 | + |
| 5 | +## Basic Concepts |
| 6 | + |
| 7 | +### Stage Space |
| 8 | + |
| 9 | +Stage Space is the original coordinate system of the game world. Sprite positions, stage size, and other elements are all defined based on this coordinate system. |
| 10 | + |
| 11 | +### Viewport Space |
| 12 | + |
| 13 | +Viewport Space is the coordinate system relative to the viewport. Objects that are visible in the viewport but do not belong to the game world (such as [Widget](./widget.md)) have their positions defined based on this coordinate system. |
| 14 | + |
| 15 | +Camera determines the transformation relationship from Stage Space to Viewport Space. |
| 16 | + |
| 17 | +### Camera Position |
| 18 | + |
| 19 | +The Camera's position determines the center point of the viewport, affecting the location of the game area that players see. It is a coordinate in Stage Space. |
| 20 | + |
| 21 | +The initial Camera Position defaults to (0,0); we may allow users to configure this through the editor in the future. |
| 22 | + |
| 23 | +### Camera Zoom |
| 24 | + |
| 25 | +Camera Zoom determines the size of the game area corresponding to the viewport. |
| 26 | + |
| 27 | +When Camera Zoom is 1, a 100x100 area on the stage (Stage Space) will also be 100x100 in size in the viewport (Viewport Space). |
| 28 | + |
| 29 | +The initial Camera Zoom defaults to 1; we may allow users to configure this through the editor in the future. |
| 30 | + |
| 31 | +### Stage Size |
| 32 | + |
| 33 | +Stage Size is the size of the game world, which determines the available space in the game and the areas that players can explore. |
| 34 | + |
| 35 | +In Stage Config, we allow users to configure the stage size. We also allow users to dynamically adjust the stage size at runtime through the `setStageSize` API. |
| 36 | + |
| 37 | +### Viewport Size |
| 38 | + |
| 39 | +Viewport Size determines the size of the game viewport; Viewport Size divided by Camera Zoom is the size of the corresponding area in Stage Space. |
| 40 | + |
| 41 | +Viewport Size currently remains at the default 480x360; we may allow users to configure this through the editor in the future. |
| 42 | + |
| 43 | +Taking Stage Size 1000x1000, Viewport Size 480x360, Camera Zoom of 1, and Camera Position of 0,0 (stage center) as an example, the viewport shows the content corresponding to a 480x360 rectangular area at the center of the stage. |
| 44 | + |
| 45 | +### Follow |
| 46 | + |
| 47 | +We can control the viewport to follow a target sprite's movement to keep that sprite always visible in the viewport. This functionality is called Follow. |
| 48 | + |
| 49 | +### Stage Viewer |
| 50 | + |
| 51 | +Stage Viewer is used to display stage content from the viewport's perspective. |
| 52 | + |
| 53 | +### Map Editor |
| 54 | + |
| 55 | +Map Editor provides comprehensive map editing functionality, including preview of the entire map (with zoom support), adjustment of map size, and the ability to select sprites and edit their basic properties (position, direction, etc.) in place. |
| 56 | + |
| 57 | +Map Editor does not provide preview and editing for Widgets. |
| 58 | + |
| 59 | +## Related APIs |
| 60 | + |
| 61 | +### Camera APIs |
| 62 | + |
| 63 | +```go |
| 64 | +type Game struct { |
| 65 | + Camera Camera |
| 66 | +} |
| 67 | + |
| 68 | +type Camera interface { |
| 69 | + Zoom() float64 |
| 70 | + SetZoom(zoom float64) |
| 71 | + |
| 72 | + Xpos() float64 |
| 73 | + Ypos() float64 |
| 74 | + SetXYpos(x float64, y float64) |
| 75 | + |
| 76 | + Follow__0(target Sprite) |
| 77 | + Follow__1(target SpriteName) |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +### Stage APIs |
| 82 | + |
| 83 | +```go |
| 84 | +type Game interface { |
| 85 | + SetStageSize(width, height float64) |
| 86 | +} |
| 87 | +``` |
| 88 | + |
| 89 | +### Mouse APIs |
| 90 | + |
| 91 | +Mouse-related APIs (such as `MouseX`, `MouseY`) all use Stage Space for positioning. |
| 92 | + |
| 93 | +For example, in Sprite code: |
| 94 | + |
| 95 | +```spx |
| 96 | +setXYpos mouseX, mouseY |
| 97 | +``` |
| 98 | + |
| 99 | +This will move the Sprite to the current mouse position without requiring coordinate system conversion. |
| 100 | + |
| 101 | +### Edge APIs |
| 102 | + |
| 103 | +Edge-related APIs (such as `touching(Edge)`, `bounceOffEdge()`), the "edge" they refer to is always the stage edge, not the viewport edge. |
| 104 | + |
| 105 | +For example, in Sprite code: |
| 106 | + |
| 107 | +```spx |
| 108 | +touching(Edge) |
| 109 | +``` |
| 110 | + |
| 111 | +The expression evaluates to `true` when the Sprite touches the stage edge, regardless of whether the Sprite is at the viewport edge. |
| 112 | + |
| 113 | +## User Story |
| 114 | + |
| 115 | +### Enabling Camera |
| 116 | + |
| 117 | +All projects can be considered to have Camera enabled by default, but in the default state, the viewport exactly displays the complete stage content, so the Camera's presence is not felt. |
| 118 | + |
| 119 | +By setting Stage Size through Stage Editor, or adjusting Camera Zoom/Position through runtime APIs to make the viewport unable to fully display the stage content, this can be considered as "enabling Camera functionality". |
| 120 | + |
| 121 | +Through Stage Viewer, you can intuitively see the Camera's effect and adjust the Camera's position. |
| 122 | + |
| 123 | +### Camera Following the Main Character |
| 124 | + |
| 125 | +In stage code: |
| 126 | + |
| 127 | +```spx |
| 128 | +Camera.follow Hero |
| 129 | +``` |
| 130 | + |
| 131 | +### Click to Move and Coordinate Conversion |
| 132 | + |
| 133 | +Players click the screen, and the main character moves to the position corresponding to the click. In stage code: |
| 134 | + |
| 135 | +```go |
| 136 | +onClick => { |
| 137 | + Hero.setXYpos mouseX, mouseY |
| 138 | +} |
| 139 | +``` |
| 140 | + |
| 141 | +### Dynamic Zoom to Highlight Combat |
| 142 | + |
| 143 | +Zoom in when combat starts, and restore when it ends. In Sprite code: |
| 144 | + |
| 145 | +```go |
| 146 | +onMsg "fight", => { |
| 147 | + zoom := Camera.zoom |
| 148 | + Camera.setZoom zoom*1.4 |
| 149 | + animateAndWait "fight" |
| 150 | + Camera.setZoom zoom |
| 151 | +} |
| 152 | +``` |
0 commit comments