contrib: move lib/gamnit/examples/asteronits to contrib/
[nit.git] / contrib / asteronits / src / touch_ui.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Touchscreen UI for mobile devices
16 module touch_ui
17
18 import asteronits
19 import controls
20
21 redef class App
22
23 # Controls texture
24 var spritesheet_controls = new ControlsImages
25
26 private var joystick_x = 200.0
27 private var joystick_y = 100.0
28
29 redef fun accept_event(event)
30 do
31 super
32
33 var display = display
34 if display == null then return false
35
36 if event isa PointerEvent and not event.is_move then
37
38 # Convert input coordinates from screen coordinates to UI units.
39 # Effectively reverting the transformation created by `ui_camera.reset_height`.
40 var ui_pos = ui_camera.camera_to_ui(event.x, event.y)
41
42 var ship = world.ship
43
44 if ui_pos.y.to_i > display.height/2 then
45 # Lower half of the screen
46 if ui_pos.x.to_i > display.width/2 then
47 # Bottom right
48 if event.pressed then ship.fire
49 else
50 # Bottom left
51 var dx = ui_pos.x - joystick_x
52 var dy = ui_pos.y - (ui_camera.height - joystick_y)
53
54 # Any touch in the joystick reset all joystick effects.
55 # It prevents leaving a button without releasing by moving
56 # the pointer over another button.
57 ship.applied_rotation = 0.0
58 ship.applied_thrust = 0.0
59
60 if not event.pressed then return true
61
62 if dy > 0.0 then
63 # Bottom part of the joystick, turns left or right
64 if dx < 0.0 then
65 ship.applied_rotation = -1.0
66 else
67 ship.applied_rotation = 1.0
68 end
69 else
70 # Upper part of the joystick, detect action using 45d angles
71 if dx < dy then
72 ship.applied_rotation = -1.0
73 else if dx > -dy then
74 ship.applied_rotation = 1.0
75 else
76 ship.applied_thrust = 1.0
77 end
78 end
79 end
80 end
81 return true
82 end
83
84 return false
85 end
86
87 redef fun on_create
88 do
89 super
90
91 var display = display
92 assert display != null
93
94 # Standardize the UI size to look like a 1600 pixels high screen.
95 # Meaning that the controls have a size proportional to the height of each screen.
96 # In the code, we can use "pixel" precision as if the target screen was 1600 pixels high.
97 ui_camera.reset_height 800.0
98
99 # Add the joystick to the UI
100 ui_sprites.add new Sprite(spritesheet_controls.forward,
101 ui_camera.bottom_left.offset(joystick_x, -200.0, 0.0))
102 ui_sprites.add new Sprite(spritesheet_controls.left,
103 ui_camera.bottom_left.offset(joystick_x-100.0, -joystick_y, 0.0))
104 ui_sprites.add new Sprite(spritesheet_controls.right,
105 ui_camera.bottom_left.offset(joystick_x+100.0, -joystick_y, 0.0))
106
107 # Purely cosmetic joystick background
108 ui_sprites.add new Sprite(spritesheet_controls.joystick_back,
109 ui_camera.bottom_left.offset(joystick_x, -joystick_y, -1.0)) # In the back
110 ui_sprites.add new Sprite(spritesheet_controls.joystick_down,
111 ui_camera.bottom_left.offset(joystick_x, 0.0, 1.0))
112
113 # Add the "open fire" button
114 ui_sprites.add new Sprite(spritesheet_controls.fire,
115 ui_camera.bottom_right.offset(-150.0, -150.0, 0.0))
116 end
117 end