11/*******************************************************************************************
22*
3- * raylib [core] example - 2d camera extended
3+ * raylib [core] example - 2d camera platformer
44*
55* This example has been created using raylib 2.5 (www.raylib.com)
66* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
77*
8+ * Example contributed by arvyy (@arvyy) and reviewed by Ramon Santamaria (@raysan5)
9+ *
810* Copyright (c) 2019 arvyy (@arvyy)
911*
1012********************************************************************************************/
1719#define PLAYER_HOR_SPD 200.f
1820
1921typedef struct Player {
20- Vector2 pos ;
21- float vel ;
22- int canJump ;
22+ Vector2 position ;
23+ float speed ;
24+ bool canJump ;
2325} Player ;
2426
2527typedef struct EnvItem {
@@ -28,144 +30,14 @@ typedef struct EnvItem {
2830 Color color ;
2931} EnvItem ;
3032
31- void UpdateCameraCenter (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height )
32- {
33- camera -> offset = (Vector2 ){ width /2 , height /2 };
34- camera -> target = player -> pos ;
35- }
3633
37- void UpdateCameraCenterInsideMap (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height )
38- {
39- camera -> target = player -> pos ;
40- camera -> offset = (Vector2 ){ width /2 , height /2 };
41- float minX = 1000 , minY = 1000 , maxX = -1000 , maxY = -1000 ;
42-
43- for (int i = 0 ; i < envItemsLength ; i ++ )
44- {
45- EnvItem * ei = envItems + i ;
46- minX = fminf (ei -> rect .x , minX );
47- maxX = fmaxf (ei -> rect .x + ei -> rect .width , maxX );
48- minY = fminf (ei -> rect .y , minY );
49- maxY = fmaxf (ei -> rect .y + ei -> rect .height , maxY );
50- }
51-
52- Vector2 max = GetWorldToScreen2D ((Vector2 ){ maxX , maxY }, * camera );
53- Vector2 min = GetWorldToScreen2D ((Vector2 ){ minX , minY }, * camera );
54-
55- if (max .x < width ) camera -> offset .x = width - (max .x - width /2 );
56- if (max .y < height ) camera -> offset .y = height - (max .y - height /2 );
57- if (min .x > 0 ) camera -> offset .x = width /2 - min .x ;
58- if (min .y > 0 ) camera -> offset .y = height /2 - min .y ;
59- }
34+ void UpdatePlayer (Player * player , EnvItem * envItems , int envItemsLength , float delta );
6035
61- void UpdateCameraCenterSmoothFollow (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height )
62- {
63- static float minSpeed = 30 ;
64- static float minEffectLength = 10 ;
65- static float fractionSpeed = 0.8f ;
66-
67- camera -> offset = (Vector2 ){ width /2 , height /2 };
68- Vector2 diff = Vector2Subtract (player -> pos , camera -> target );
69- float length = Vector2Length (diff );
70-
71- if (length > minEffectLength )
72- {
73- float speed = fmaxf (fractionSpeed * length , minSpeed );
74- camera -> target = Vector2Add (camera -> target , Vector2Scale (diff , speed * delta /length ));
75- }
76- }
77-
78- void UpdateCameraEvenOutOnLanding (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height )
79- {
80- static float evenOutSpeed = 700 ;
81- static int eveningOut = false;
82- static float evenOutTarget ;
83-
84- camera -> offset = (Vector2 ){ width /2 , height /2 };
85- camera -> target .x = player -> pos .x ;
86-
87- if (eveningOut )
88- {
89- if (evenOutTarget > camera -> target .y )
90- {
91- camera -> target .y += evenOutSpeed * delta ;
92-
93- if (camera -> target .y > evenOutTarget )
94- {
95- camera -> target .y = evenOutTarget ;
96- eveningOut = 0 ;
97- }
98- }
99- else
100- {
101- camera -> target .y -= evenOutSpeed * delta ;
102-
103- if (camera -> target .y < evenOutTarget )
104- {
105- camera -> target .y = evenOutTarget ;
106- eveningOut = 0 ;
107- }
108- }
109- }
110- else
111- {
112- if (player -> canJump && (player -> vel == 0 ) && (player -> pos .y != camera -> target .y ))
113- {
114- eveningOut = 1 ;
115- evenOutTarget = player -> pos .y ;
116- }
117- }
118- }
119-
120- void UpdateCameraPlayerBoundsPush (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height )
121- {
122- static Vector2 bbox = { 0.2f , 0.2f };
123-
124- Vector2 bboxWorldMin = GetScreenToWorld2D ((Vector2 ){ (1 - bbox .x )* 0.5f * width , (1 - bbox .y )* 0.5f * height }, * camera );
125- Vector2 bboxWorldMax = GetScreenToWorld2D ((Vector2 ){ (1 + bbox .x )* 0.5f * width , (1 + bbox .y )* 0.5f * height }, * camera );
126- camera -> offset = (Vector2 ){ (1 - bbox .x )* 0.5f * width , (1 - bbox .y )* 0.5f * height };
127-
128- if (player -> pos .x < bboxWorldMin .x ) camera -> target .x = player -> pos .x ;
129- if (player -> pos .y < bboxWorldMin .y ) camera -> target .y = player -> pos .y ;
130- if (player -> pos .x > bboxWorldMax .x ) camera -> target .x = bboxWorldMin .x + (player -> pos .x - bboxWorldMax .x );
131- if (player -> pos .y > bboxWorldMax .y ) camera -> target .y = bboxWorldMin .y + (player -> pos .y - bboxWorldMax .y );
132- }
133-
134- void UpdatePlayer (Player * player , EnvItem * envItems , int envItemsLength , float delta )
135- {
136- if (IsKeyDown (KEY_LEFT )) player -> pos .x -= PLAYER_HOR_SPD * delta ;
137- if (IsKeyDown (KEY_RIGHT )) player -> pos .x += PLAYER_HOR_SPD * delta ;
138- if (IsKeyDown (KEY_SPACE ) && player -> canJump )
139- {
140- player -> vel = - PLAYER_JUMP_SPD ;
141- player -> canJump = 0 ;
142- }
143-
144- int hitObstacle = 0 ;
145- for (int i = 0 ; i < envItemsLength ; i ++ )
146- {
147- EnvItem * ei = envItems + i ;
148- Vector2 * p = & (player -> pos );
149- if (ei -> blocking &&
150- ei -> rect .x <= p -> x &&
151- ei -> rect .x + ei -> rect .width >= p -> x &&
152- ei -> rect .y >= p -> y &&
153- ei -> rect .y < p -> y + player -> vel * delta )
154- {
155- hitObstacle = 1 ;
156- player -> vel = 0.0f ;
157- p -> y = ei -> rect .y ;
158- }
159- }
160-
161- if (!hitObstacle )
162- {
163- player -> pos .y += player -> vel * delta ;
164- player -> vel += G * delta ;
165- player -> canJump = 0 ;
166- }
167- else player -> canJump = 1 ;
168- }
36+ void UpdateCameraCenter (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height );
37+ void UpdateCameraCenterInsideMap (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height );
38+ void UpdateCameraCenterSmoothFollow (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height );
39+ void UpdateCameraEvenOutOnLanding (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height );
40+ void UpdateCameraPlayerBoundsPush (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height );
16941
17042
17143int main (void )
@@ -178,9 +50,9 @@ int main(void)
17850 InitWindow (screenWidth , screenHeight , "raylib [core] example - 2d camera" );
17951
18052 Player player = { 0 };
181- player .pos = (Vector2 ){ 400 , 280 };
182- player .vel = 0 ;
183- player .canJump = 0 ;
53+ player .position = (Vector2 ){ 400 , 280 };
54+ player .speed = 0 ;
55+ player .canJump = false ;
18456 EnvItem envItems [] = {
18557 {{ 0 , 0 , 1000 , 400 }, 0 , LIGHTGRAY },
18658 {{ 0 , 400 , 1000 , 200 }, 1 , GRAY },
@@ -192,7 +64,7 @@ int main(void)
19264 int envItemsLength = sizeof (envItems )/sizeof (envItems [0 ]);
19365
19466 Camera2D camera = { 0 };
195- camera .target = player .pos ;
67+ camera .target = player .position ;
19668 camera .offset = (Vector2 ){ screenWidth /2 , screenHeight /2 };
19769 camera .rotation = 0.0f ;
19870 camera .zoom = 1.0f ;
@@ -237,7 +109,7 @@ int main(void)
237109 if (IsKeyPressed (KEY_R ))
238110 {
239111 camera .zoom = 1.0f ;
240- player .pos = (Vector2 ){ 400 , 280 };
112+ player .position = (Vector2 ){ 400 , 280 };
241113 }
242114
243115 if (IsKeyPressed (KEY_C )) cameraOption = (cameraOption + 1 )%cameraUpdatersLength ;
@@ -256,7 +128,7 @@ int main(void)
256128
257129 for (int i = 0 ; i < envItemsLength ; i ++ ) DrawRectangleRec (envItems [i ].rect , envItems [i ].color );
258130
259- Rectangle playerRect = { player .pos .x - 20 , player .pos .y - 40 , 40 , 40 };
131+ Rectangle playerRect = { player .position .x - 20 , player .position .y - 40 , 40 , 40 };
260132 DrawRectangleRec (playerRect , RED );
261133
262134 EndMode2D ();
@@ -280,3 +152,142 @@ int main(void)
280152
281153 return 0 ;
282154}
155+
156+ void UpdatePlayer (Player * player , EnvItem * envItems , int envItemsLength , float delta )
157+ {
158+ if (IsKeyDown (KEY_LEFT )) player -> position .x -= PLAYER_HOR_SPD * delta ;
159+ if (IsKeyDown (KEY_RIGHT )) player -> position .x += PLAYER_HOR_SPD * delta ;
160+ if (IsKeyDown (KEY_SPACE ) && player -> canJump )
161+ {
162+ player -> speed = - PLAYER_JUMP_SPD ;
163+ player -> canJump = false;
164+ }
165+
166+ int hitObstacle = 0 ;
167+ for (int i = 0 ; i < envItemsLength ; i ++ )
168+ {
169+ EnvItem * ei = envItems + i ;
170+ Vector2 * p = & (player -> position );
171+ if (ei -> blocking &&
172+ ei -> rect .x <= p -> x &&
173+ ei -> rect .x + ei -> rect .width >= p -> x &&
174+ ei -> rect .y >= p -> y &&
175+ ei -> rect .y < p -> y + player -> speed * delta )
176+ {
177+ hitObstacle = 1 ;
178+ player -> speed = 0.0f ;
179+ p -> y = ei -> rect .y ;
180+ }
181+ }
182+
183+ if (!hitObstacle )
184+ {
185+ player -> position .y += player -> speed * delta ;
186+ player -> speed += G * delta ;
187+ player -> canJump = false;
188+ }
189+ else player -> canJump = true;
190+ }
191+
192+ void UpdateCameraCenter (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height )
193+ {
194+ camera -> offset = (Vector2 ){ width /2 , height /2 };
195+ camera -> target = player -> position ;
196+ }
197+
198+ void UpdateCameraCenterInsideMap (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height )
199+ {
200+ camera -> target = player -> position ;
201+ camera -> offset = (Vector2 ){ width /2 , height /2 };
202+ float minX = 1000 , minY = 1000 , maxX = -1000 , maxY = -1000 ;
203+
204+ for (int i = 0 ; i < envItemsLength ; i ++ )
205+ {
206+ EnvItem * ei = envItems + i ;
207+ minX = fminf (ei -> rect .x , minX );
208+ maxX = fmaxf (ei -> rect .x + ei -> rect .width , maxX );
209+ minY = fminf (ei -> rect .y , minY );
210+ maxY = fmaxf (ei -> rect .y + ei -> rect .height , maxY );
211+ }
212+
213+ Vector2 max = GetWorldToScreen2D ((Vector2 ){ maxX , maxY }, * camera );
214+ Vector2 min = GetWorldToScreen2D ((Vector2 ){ minX , minY }, * camera );
215+
216+ if (max .x < width ) camera -> offset .x = width - (max .x - width /2 );
217+ if (max .y < height ) camera -> offset .y = height - (max .y - height /2 );
218+ if (min .x > 0 ) camera -> offset .x = width /2 - min .x ;
219+ if (min .y > 0 ) camera -> offset .y = height /2 - min .y ;
220+ }
221+
222+ void UpdateCameraCenterSmoothFollow (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height )
223+ {
224+ static float minSpeed = 30 ;
225+ static float minEffectLength = 10 ;
226+ static float fractionSpeed = 0.8f ;
227+
228+ camera -> offset = (Vector2 ){ width /2 , height /2 };
229+ Vector2 diff = Vector2Subtract (player -> position , camera -> target );
230+ float length = Vector2Length (diff );
231+
232+ if (length > minEffectLength )
233+ {
234+ float speed = fmaxf (fractionSpeed * length , minSpeed );
235+ camera -> target = Vector2Add (camera -> target , Vector2Scale (diff , speed * delta /length ));
236+ }
237+ }
238+
239+ void UpdateCameraEvenOutOnLanding (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height )
240+ {
241+ static float evenOutSpeed = 700 ;
242+ static int eveningOut = false;
243+ static float evenOutTarget ;
244+
245+ camera -> offset = (Vector2 ){ width /2 , height /2 };
246+ camera -> target .x = player -> position .x ;
247+
248+ if (eveningOut )
249+ {
250+ if (evenOutTarget > camera -> target .y )
251+ {
252+ camera -> target .y += evenOutSpeed * delta ;
253+
254+ if (camera -> target .y > evenOutTarget )
255+ {
256+ camera -> target .y = evenOutTarget ;
257+ eveningOut = 0 ;
258+ }
259+ }
260+ else
261+ {
262+ camera -> target .y -= evenOutSpeed * delta ;
263+
264+ if (camera -> target .y < evenOutTarget )
265+ {
266+ camera -> target .y = evenOutTarget ;
267+ eveningOut = 0 ;
268+ }
269+ }
270+ }
271+ else
272+ {
273+ if (player -> canJump && (player -> speed == 0 ) && (player -> position .y != camera -> target .y ))
274+ {
275+ eveningOut = 1 ;
276+ evenOutTarget = player -> position .y ;
277+ }
278+ }
279+ }
280+
281+ void UpdateCameraPlayerBoundsPush (Camera2D * camera , Player * player , EnvItem * envItems , int envItemsLength , float delta , int width , int height )
282+ {
283+ static Vector2 bbox = { 0.2f , 0.2f };
284+
285+ Vector2 bboxWorldMin = GetScreenToWorld2D ((Vector2 ){ (1 - bbox .x )* 0.5f * width , (1 - bbox .y )* 0.5f * height }, * camera );
286+ Vector2 bboxWorldMax = GetScreenToWorld2D ((Vector2 ){ (1 + bbox .x )* 0.5f * width , (1 + bbox .y )* 0.5f * height }, * camera );
287+ camera -> offset = (Vector2 ){ (1 - bbox .x )* 0.5f * width , (1 - bbox .y )* 0.5f * height };
288+
289+ if (player -> position .x < bboxWorldMin .x ) camera -> target .x = player -> position .x ;
290+ if (player -> position .y < bboxWorldMin .y ) camera -> target .y = player -> position .y ;
291+ if (player -> position .x > bboxWorldMax .x ) camera -> target .x = bboxWorldMin .x + (player -> position .x - bboxWorldMax .x );
292+ if (player -> position .y > bboxWorldMax .y ) camera -> target .y = bboxWorldMin .y + (player -> position .y - bboxWorldMax .y );
293+ }
0 commit comments