projects: update some short descriptions
[nit.git] / lib / scene2d.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 # Framework for 2D management of game elements
16 #
17 # TODO: collision framework (with quad tree?)
18 module scene2d
19
20 # The root class of the living objects (sprites, group of sprites, etc.)
21 abstract class LiveObject
22 # Compute the position, state and appearance.
23 fun update do end
24
25 # Controls whether `update' and `draw' are automatically called by `LiveGroup'
26 var exists = true is writable
27
28 # Redefine this method to asks how to draw on a view
29 fun draw(view: View) is abstract
30 end
31
32
33 # The basic atomic living and moving object.
34 #
35 # A sprite has a position and a velocity
36 class Sprite
37 super LiveObject
38
39 # x coordinate of the center point
40 var x: Int = 0 is writable
41
42 # y coordinate of the center point
43 var y: Int = 0 is writable
44
45 # width of the sprite
46 var width: Int = 100 is writable
47
48 # height of the sprite
49 var height: Int = 100 is writable
50
51 # X coordinate of left side.
52 fun left: Int do return x - width/2
53
54 # X coordinate of right side.
55 fun right: Int do return x + width/2
56
57 # Y coordinate of top.
58 fun top: Int do return y - height/2
59
60 # Y coordinate of bottom.
61 fun bottom: Int do return y + height/2
62
63 # x velocity (applied by `update')
64 var vx: Int = 0 is writable
65
66 # y velocity (applied by `update')
67 var vy: Int = 0 is writable
68
69 redef fun update
70 do
71 self.x += self.vx
72 self.y += self.vy
73 end
74
75 redef fun draw(view) do view.draw_sprite(self)
76
77 # Is self overlaps (or contains) an other sprite
78 # `x', `y', `width', and `height' of both sprites are considered
79 fun overlaps(other: Sprite): Bool
80 do
81 return self.right > other.left and self.left < other.right and self.bottom > other.top and self.top < other.bottom
82 end
83
84 # Return the current angle of velocity
85 # Often used to rotate the displayed image with the correct angle
86 fun velocity_angle: Float
87 do
88 return atan2(self.vx.to_f, -self.vy.to_f)
89 end
90
91 # Return the angle to target an other sprite
92 fun angle_to(target: Sprite): Float
93 do
94 return atan2((target.x-self.x).to_f, (self.y-target.y).to_f)
95 end
96
97 # Update of vx and vy toward a given angle and magnitude
98 fun set_velocity(angle: Float, maginude: Int)
99 do
100 var magf = maginude.to_f
101 self.vx = (angle.sin * magf).to_i
102 self.vy = (angle.cos * -magf).to_i
103 end
104
105 end
106
107 # Organizational class to manage groups of sprites and other live objects.
108 class LiveGroup[E: LiveObject]
109 super LiveObject
110 super List[E]
111
112 # Recursively update each live objects that `exists'
113 redef fun update
114 do
115 for x in self do if x.exists then x.update
116 end
117
118 # Remove all live Objects that do not exists
119 # Call this to cleanup the live group
120 fun gc
121 do
122 var i = self.iterator
123 while i.is_ok do
124 var e = i.item
125 if not e.exists then
126 i.delete
127 else if e isa LiveGroup[LiveObject] then
128 e.gc
129 end
130 i.next
131 end
132 end
133
134 # Recursively draw each live objects that `exists'
135 redef fun draw(view)
136 do
137 for x in self do if x.exists then x.draw(view)
138 end
139 end
140
141 # A state in the game logic
142 # A scene manage a bunch of live objects
143 class Scene
144 super LiveObject
145 end
146
147 # Abstract view do draw sprites
148 #
149 # Concrete views are specific for each back-end.
150 # View can also be used to implements camera and other fun things.
151 interface View
152 # Draw a specific sprite on the view
153 #
154 # This method must be implemented for each specific view.
155 # A traditional way of implementation is to use a double-dispatch mechanism
156 #
157 # class MyView
158 # super View
159 # redef fun draw_sprite(s) do s.draw_on_myview(self)
160 # end
161 # redef class Sprite
162 # # How to draw a sprite on my specific view
163 # fun draw_on_myview(myview: MyView) is abstract
164 # end
165 fun draw_sprite(s: Sprite) is abstract
166 end