X-Git-Url: http://nitlanguage.org diff --git a/lib/scene2d.nit b/lib/scene2d.nit new file mode 100644 index 0000000..18a5d13 --- /dev/null +++ b/lib/scene2d.nit @@ -0,0 +1,163 @@ +# This file is part of NIT ( http://www.nitlanguage.org ). +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# 2D management of game elements +# +# TODO: collision framework (with quad tree?) +module scene2d + +# The root class of the living objects (sprites, group of sprites, etc.) +abstract class LiveObject + # Compute the position, state and appearance. + fun update do end + + # Controls whether `update' and `draw' are automatically called by `LiveGroup' + var exists writable = true + + # Redefine this method to asks how to draw on a view + fun draw(view: View) is abstract +end + + +# The basic atomic living and moving object. +# +# A sprite has a position and a velocity +class Sprite + super LiveObject + + # x coordinate of the center point + var x: Int writable = 0 + + # y coordinate of the center point + var y: Int writable = 0 + + # width of the sprite + var width: Int writable = 100 + + # height of the sprite + var height: Int writable = 100 + + fun left: Int do return x - width/2 + fun right: Int do return x + width/2 + fun top: Int do return y - height/2 + fun bottom: Int do return y + height/2 + + # x velocity (applied by `update') + var vx: Int writable = 0 + + # y velocity (applied by `update') + var vy: Int writable = 0 + + redef fun update + do + self.x += self.vx + self.y += self.vy + end + + redef fun draw(view) do view.draw_sprite(self) + + # Is self overlaps (or contains) an other sprite + # `x', `y', `width', and `height' of both sprites are considered + fun overlaps(other: Sprite): Bool + do + return self.right > other.left and self.left < other.right and self.bottom > other.top and self.top < other.bottom + end + + # Return the current angle of velocity + # Often used to rotate the displayed image with the correct angle + fun velocity_angle: Float + do + return atan2(self.vx.to_f, -self.vy.to_f) + end + + # Return the angle to target an other sprite + fun angle_to(target: Sprite): Float + do + return atan2((target.x-self.x).to_f, (self.y-target.y).to_f) + end + + # Update of vx and vy toward a given angle and magnitude + fun set_velocity(angle: Float, maginude: Int) + do + var magf = maginude.to_f + self.vx = (angle.sin * magf).to_i + self.vy = (angle.cos * -magf).to_i + end + +end + +# Organizational class to manage groups of sprites and other live objects. +class LiveGroup[E: LiveObject] + super LiveObject + super List[E] + + init + do + end + + # Recursively update each live objects that `exists' + redef fun update + do + for x in self do if x.exists then x.update + end + + # Remove all live Objects that do not exists + # Call this to cleanup the live group + fun gc + do + var i = self.iterator + while i.is_ok do + var e = i.item + if not e.exists then + i.delete + else if e isa LiveGroup[LiveObject] then + e.gc + end + i.next + end + end + + # Recursively draw each live objects that `exists' + redef fun draw(view) + do + for x in self do if x.exists then x.draw(view) + end +end + +# A state in the game logic +# A scene manage a bunch of live objects +class Scene + super LiveObject +end + +# Abstract view do draw sprites +# +# Concrete views are specific for each back-end. +# View can also be used to implements camera and other fun things. +interface View + # Draw a specific sprite on the view + # + # This method must be implemented for each specific view. + # A traditional way of implementation is to use a double-dispatch mechanism + # + # Exemple: + # class MyView + # redef fun draw_sprite(s) do s.draw_on_myview(self) + # end + # redef class Sprite + # # How to draw a sprite on my specific view + # fun draw_on_myview(myview: MyView) is abstract + # end + fun draw_sprite(s: Sprite) is abstract +end