efl

Форк
0
/
ephysics_logo.c 
280 строк · 9.1 Кб
1
#ifdef HAVE_CONFIG_H
2
# include <config.h>
3
#endif
4

5
#include <Elementary.h>
6
#include <EPhysics.h>
7
#include <Evas.h>
8

9
#define WIDTH (512)
10
#define HEIGHT (384)
11
#define DEPTH (100)
12
#define FLOOR_Y (HEIGHT - 80)
13
#define SH_THRESHOLD (250)
14
#define SH_OFFSET_X (- 16)
15
#define OFFSET_X (90)
16
#define PADDING_X_1 (16)
17
#define PADDING_X_2 (12)
18
#define PADDING_X_3 (22)
19
#define E_THRESHOLD (WIDTH + 560)
20
#define LAYER_SHADOW (10)
21
#define LAYER_LETTER (20)
22

23
#define CENTER(total, item)  (((total) - (item)) / 2)
24
#define LIMIT(val, op, ref) (((val) op (ref)) ? (val) : (ref));
25
#define PROP_GET(pos, min, max) (((min) + ((max) - (min)) * (pos)) / (max))
26

27
static void
28
_update_box_cb(void *data __UNUSED__, EPhysics_Body *body, void *event_info)
29
{
30
   Evas_Object *image = event_info;
31
   Evas_Object *shadow = evas_object_data_get(image, "shadow");
32
   Evas_Object *light = evas_object_data_get(image, "light");
33
   int x, y, w, h, floor_distance, alpha = 0;
34

35
   /* modify the evas object according to the body */
36
   ephysics_body_evas_object_update(body);
37
   evas_object_geometry_get(image, &x, &y, &w, &h);
38

39
   floor_distance = FLOOR_Y - h;
40

41
   /* Bodies penetrates the ground slightly before bouncing. */
42
   /* This is to be expected in realtime physics engines. */
43
   // TODO BUG: should we move the object up by the difference????
44
   //y = LIMIT(y, <=, floor_distance);
45

46
   /* We should show the shadow when we're close enough to ground */
47
   if (y > SH_THRESHOLD)
48
     {
49
        int sh_w, sh_h;
50
        double pos_x;
51

52
        evas_object_image_size_get(shadow, &sh_w, &sh_h);
53
        /* shadow is darker with bigger y */
54
        alpha = 255 * (y - SH_THRESHOLD) / (floor_distance - SH_THRESHOLD);
55
        /* and with bigger x -- it's proportional to x / WIDTH, but varies
56
         * from 100 to 255.
57
         */
58
        pos_x = (double) x / (WIDTH - w);
59
        alpha = alpha * PROP_GET(pos_x, 100, 255);
60
        /* box shadow is not resized, just moved */
61
        evas_object_move(shadow, x + CENTER(w, sh_w) + SH_OFFSET_X,
62
                         FLOOR_Y - sh_h + 2);
63
     }
64
   evas_object_color_set(shadow, alpha, alpha, alpha, alpha);
65

66
   evas_object_move(light, x, y);
67
   /* it's lighter with bigger y */
68
   alpha = (y <= 0) ? 0 : y * 255 / floor_distance;
69
   /* and with bigger x */
70
   alpha = alpha * (x - OFFSET_X + 80) / (WIDTH - OFFSET_X);
71
   evas_object_color_set(light, alpha, alpha, alpha, alpha);
72
}
73

74
static void
75
_update_circle_cb(void *data __UNUSED__, EPhysics_Body *body, void *event_info)
76
{
77
   Evas_Object *image = event_info;
78
   Evas_Object *shadow = evas_object_data_get(image, "shadow");
79
   Evas_Object *light = evas_object_data_get(image, "light");
80
   int x, y, w, h, sh_w, sh_h, alpha = 0;
81
   const Evas_Map *map;
82

83
   /* modify the evas object according to the body */
84
   ephysics_body_evas_object_update(body);
85
   evas_object_geometry_get(image, &x, &y, &w, &h);
86

87
   evas_object_move(light, x, y);
88
   alpha = x * 255 / (WIDTH - w);
89
   evas_object_color_set(light, alpha, alpha, alpha, alpha);
90

91
   /* use the same map from image to the light (rotate it) */
92
   map = evas_object_map_get(image);
93
   evas_object_map_set(light, map);
94
   evas_object_map_enable_set(light, EINA_TRUE);
95

96
   evas_object_image_size_get(shadow, &sh_w, &sh_h);
97
   evas_object_move(shadow, x + CENTER(w, sh_w) + SH_OFFSET_X,
98
                    FLOOR_Y - sh_h + 2);
99
   alpha = 127 + alpha / 2;
100
   evas_object_color_set(shadow, alpha, alpha, alpha, alpha);
101

102
   if (x > E_THRESHOLD)
103
     ephysics_body_move(body, -w - 1, y, -15);
104
}
105

106
static void
107
_letter_add(Evas *evas, const char *letter, Evas_Object **image, Evas_Object **light, Evas_Object **shadow)
108
{
109
   int w, h, sh_w, sh_h;
110
   char buf[1024];
111

112
   snprintf(buf, sizeof(buf), PACKAGE_DATA_DIR "/logo_shadow-%s.png", letter);
113
   *shadow = evas_object_image_filled_add(evas);
114
   evas_object_image_file_set(*shadow, buf, NULL);
115
   evas_object_image_size_get(*shadow, &sh_w, &sh_h);
116
   evas_object_resize(*shadow, sh_w, sh_h);
117
   evas_object_color_set(*shadow, 0, 0, 0, 0);
118
   evas_object_layer_set(*shadow, LAYER_SHADOW);
119
   evas_object_show(*shadow);
120

121
   snprintf(buf, sizeof(buf), PACKAGE_DATA_DIR "/logo_letter-%s.png", letter);
122
   *image = evas_object_image_filled_add(evas);
123
   evas_object_image_file_set(*image, buf, NULL);
124
   evas_object_image_size_get(*image, &w, &h);
125
   evas_object_resize(*image, w, h);
126
   evas_object_layer_set(*image, LAYER_LETTER);
127
   evas_object_show(*image);
128

129
   snprintf(buf, sizeof(buf), PACKAGE_DATA_DIR "/logo_light-%s.png", letter);
130
   *light = evas_object_image_filled_add(evas);
131
   evas_object_image_file_set(*light, buf, NULL);
132
   evas_object_resize(*light, w, h);
133
   evas_object_layer_set(*light, LAYER_LETTER);
134
   evas_object_show(*light);
135

136
   /* allow easy access to shadow and light from the letter image */
137
   evas_object_data_set(*image, "shadow", *shadow);
138
   evas_object_data_set(*image, "light", *light);
139
}
140

141
static void
142
_letter_body_setup_common(EPhysics_Body *body, Evas_Object *view)
143
{
144
   ephysics_body_evas_object_set(body, view, EINA_TRUE);
145
   ephysics_body_mass_set(body, 1.2);
146
   ephysics_body_restitution_set(body, 0.6);
147
   ephysics_body_angular_movement_enable_set(body, EINA_FALSE, EINA_FALSE,
148
                                             EINA_FALSE);
149
}
150

151
static EPhysics_Body *
152
_letter_body_box_add(EPhysics_World *world, Evas_Object *image)
153
{
154
   EPhysics_Body *body = ephysics_body_box_add(world);
155

156
   _letter_body_setup_common(body, image);
157

158
   ephysics_body_event_callback_add
159
     (body, EPHYSICS_CALLBACK_BODY_UPDATE, _update_box_cb, NULL);
160

161
   return body;
162
}
163

164
static EPhysics_Body *
165
_letter_body_circle_add(EPhysics_World *world, Evas_Object *image)
166
{
167
   EPhysics_Body *body = ephysics_body_cylinder_add(world);
168

169
   _letter_body_setup_common(body, image);
170

171
   ephysics_body_event_callback_add
172
     (body, EPHYSICS_CALLBACK_BODY_UPDATE, _update_circle_cb, NULL);
173

174
   return body;
175
}
176

177
EAPI_MAIN int
178
elm_main(int argc __UNUSED__, char **argv __UNUSED__)
179
{
180
   Evas_Object *win, *bg, *image, *light, *shadow;
181
   EPhysics_Body *ground_body, *letter_body;
182
   EPhysics_World *world;
183
   unsigned int i = 0;
184
   int x, w, h, sh_w;
185
   Evas *evas;
186

187
   struct letter_desc {
188
      const char *letter;
189
      int padding;
190
   } falling_letters[] = {
191
     {"P", PADDING_X_1},
192
     {"H", PADDING_X_1},
193
     {"Y", PADDING_X_3},
194
     {"S1", PADDING_X_2},
195
     {"I", PADDING_X_2},
196
     {"C", PADDING_X_3},
197
     {"S2", 0}
198
   };
199

200
   if (!ephysics_init())
201
     return - 1;
202

203
   elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
204

205
   win = elm_win_add(NULL, "main", ELM_WIN_SPLASH);
206
   elm_win_title_set(win, "EPhysics Logo");
207
   elm_win_autodel_set(win, EINA_TRUE);
208
   evas_object_show(win);
209

210
   bg = elm_bg_add(win);
211
   elm_bg_file_set(bg, PACKAGE_DATA_DIR "/logo_background.png", NULL);
212
   elm_win_resize_object_add(win, bg);
213
   evas_object_size_hint_min_set(bg, WIDTH, HEIGHT);
214
   evas_object_size_hint_max_set(bg, WIDTH, HEIGHT);
215
   evas_object_show(bg);
216

217
   world = ephysics_world_new();
218
   ephysics_world_render_geometry_set(world, 0, 0, -50, WIDTH, HEIGHT, DEPTH);
219

220
   ground_body = ephysics_body_box_add(world);
221
   ephysics_body_mass_set(ground_body, EPHYSICS_BODY_MASS_STATIC);
222
   ephysics_body_geometry_set(ground_body, -100, FLOOR_Y, -15, WIDTH + 800, 10,
223
                              30);
224
   ephysics_body_restitution_set(ground_body, 0.65);
225
   ephysics_body_friction_set(ground_body, 0.8);
226

227
   evas = evas_object_evas_get(win);
228
   x = OFFSET_X;
229

230
   for (i = 0; i < EINA_C_ARRAY_LENGTH(falling_letters); i++)
231
     {
232
        _letter_add(evas, falling_letters[i].letter, &image, &light, &shadow);
233

234
        evas_object_image_size_get(shadow, &sh_w, NULL);
235
        evas_object_image_size_get(image, &w, &h);
236

237
        /* place image and light on top, above what the viewport can show */
238
        evas_object_move(image, x, -h * (i + 1) - 50);
239
        evas_object_move(light, x, -h * (i + 1) - 50);
240
        /* place shadow below the hit-line: FLOOR_Y, centered at image */
241
        evas_object_move(shadow, x + CENTER(w, sh_w), FLOOR_Y);
242

243
        x += falling_letters[i].padding + w;
244

245
        letter_body = _letter_body_box_add(world, image);
246
        ephysics_body_friction_set(letter_body, 0.4);
247
     }
248

249
   /* E is a circle that comes rolling on the floor */
250
   _letter_add(evas, "E", &image, &light, &shadow);
251
   evas_object_color_set(shadow, 255, 255, 255, 255);
252

253
   evas_object_image_size_get(shadow, &sh_w, NULL);
254
   evas_object_image_size_get(image, &w, &h);
255
   /* place image and light so they are above the floor,
256
    * and to the left of viewport
257
    */
258
   evas_object_move(image, -w - 1, FLOOR_Y - h + 1);
259
   evas_object_move(light, -w - 1, FLOOR_Y - h + 1);
260
   /* place the shadow below the hit-line: FLOOR_Y, centered at image */
261
   evas_object_move(shadow, -w - 1 + CENTER(w, sh_w), FLOOR_Y);
262

263
   letter_body = _letter_body_circle_add(world, image);
264
   ephysics_body_friction_set(letter_body, 1);
265
   ephysics_body_mass_set(letter_body, 1);
266
   ephysics_body_angular_movement_enable_set(letter_body, EINA_FALSE,
267
                                             EINA_FALSE, EINA_TRUE);
268

269
   /* make the "E" logo get into the viewport by applying an horizontal force */
270
   ephysics_body_central_impulse_apply(letter_body, 390, 0, 0);
271

272
   elm_run();
273

274
   ephysics_world_del(world);
275
   ephysics_shutdown();
276
   elm_shutdown();
277

278
   return 0;
279
}
280
ELM_MAIN()
281

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.