interface SimpleCollection[E]
super RemovableCollection[E]
- # Add an item in a collection.
+ # Add `item` to this collection.
#
# var a = [1,2]
# a.add 3
intrude import gamnit::flat
-# Visible entity in the game world, represented by its `model` modified by the other attributes
+# Visible 3D entity in the game world
+#
+# Similar to `gamnit::Sprite` which is in 2D.
+#
+# Each actor associates a `model` to the position `center`.
+# The appearance is modified by `rotation`, `scale` and `alpha`,
+# as well as the attributes of `model` itself.
+#
+# ~~~
+# import gamnit::depth
+#
+# # Load model from the assets folder
+# var model = new Model("path/in/assets.obj")
+#
+# # Create and configure an actor
+# var actor = new Actor(model, new Point3d[Float](0.0, 0.0, 0.0))
+# actor.scale = 2.0
+#
+# # Add to the visible game world
+# app.actors.add actor
+# ~~~
class Actor
- # Model used to dray this actor
+ # Model used to draw this actor
var model: Model
# Position of this sprite in world coordinates
# Rotation on the Z axis
var rotation = 0.0 is writable
- # Scale applied to this sprite
+ # Scale applied to the model
var scale = 1.0 is writable
- # Transparency applied to the texture on draw
+ # Transparency applied to the model on draw
+ #
+ # This value may be ignored by some materials.
+ # Non-opaque values may result in artifacts as there is no specialized
+ # support for transparent models and the depth buffer.
var alpha = 1.0 is writable
end
-# Entire 3D model defined by its `leaves`, an association of `Mesh` to `Material`
+# 3D model composed of `Mesh` and `Material`, loaded from the assets folder by default
+#
+# Instances can be created at any time and must be loaded after or at the end of `on_create`.
+# If loading fails, the model is replaced by `placeholder_model`.
+#
+# ~~~
+# import gamnit::depth
+#
+# var model = new Model("path/in/assets.obj")
+# model.load
+# ~~~
+#
+# The most simple model is `LeafModel`, composed of a single `Mesh` and `Material`.
+# It can be easily created programmatically to display simple geometries.
+# Whereas `CompositeModel` is composed of one or many `LeafModel` and is usually
+# loaded from the assets folder as a `ModelAsset`.
+# Instances of `ModelAsset` must be in the format OBJ and MAT,
+# and their texture in PNG or JPG.
abstract class Model
# Load this model in memory
redef var leaves = new Array[LeafModel]
end
-# Single model with a `mesh` and `material`
+# Basic model with a single `mesh` and `material`
#
# Only leaves are actually drawn by the `material`.
class LeafModel
redef var leaves = [self]
end
-# Material for a model or how to draw the model
+# Material for models, or how to draw the model
+#
+# To create a simple basic blueish material, use `new Material`.
+#
+# Each class of material is associated to a `GLProgram` and its GPU shaders.
+# The simple material `SmoothMaterial` allows to set an ambient, diffuse and specular color.
+# To which `TextureMaterial` adds three textures, for each kind of light.
+# The `NormalsMaterial` may be useful for debugging, it show the orientation of
+# the normal vectors as colors.
+#
+# ~~~
+# import gamnit::depth
+#
+# var blueish_material = new Material
+# var redish_material = new SmoothMaterial([0.3, 0.0, 0.0],
+# [0.6, 0.0, 0.0],
+# [1.0, 1.0, 1.0])
+# var normals_material = new NormalsMaterial
+# ~~~
abstract class Material
- # Draw `actor`
+ # Draw a `model` from `actor`
#
# This method should be refined by subclasses as the default implementation is a no-op.
#
end
# Mesh with all geometry data
+#
+# May be created via `Plane`, `Cube` or `UVSphere`,
+# or loaded from the assets folder indirectly with a `Model`.
+#
+# ~~~
+# import gamnit::depth
+#
+# var plane = new Plane
+# var cube = new Cube
+# var sphere = new UVSphere(1.0, 32, 16)
+# ~~~
class Mesh
# Vertices coordinates
[1.0, 1.0, 1.0, 1.0])
end
-# Simple material with static colors used for debugging or display abstract objects
+# Simple material with static colors
class SmoothMaterial
super Material
end
# Cube, with 6 faces
+#
+# Occupies `[-0.5..0.5]` on all three axes.
class Cube
super Mesh
import gamnit::limit_fps
import gamnit::camera_control
-# Draw a `texture` at `center`
+# Visible 2D entity in the game world or UI
#
-# An instance of `Sprite` can only belong to a single `SpriteSet` at
-# a time. The on screen position depends on the camera associated
+# Similar to `gamnit::Actor` which is in 3D.
+#
+# Each sprite associates a `texture` to the position `center`.
+# The appearance is modified by `rotation`, `invert_x`,
+# `scale`, `red`, `green`, `blue` and `alpha`.
+# These values can be changed at any time and will trigger an update
+# of the data on the GPU side, having a small performance cost.
+#
+# For a sprite to be visible, it must be added to either the world `sprites`
+# or the `ui_sprites`.
+# However, an instance of `Sprite` can only belong to a single `SpriteSet`
+# at a time. The final on-screen position depends on the camera associated
# to the `SpriteSet`.
+#
+# ~~~
+# # Load texture and create sprite
+# var texture = new Texture("path/in/assets.png")
+# var sprite = new Sprite(texture, new Point3d[Float](0.0, 0.0, 0.0))
+#
+# # Add sprite to the visible game world
+# app.sprites.add sprite
+#
+# # Extra configuration of the sprite
+# sprite.rotation = pi/2.0
+# sprite.scale = 2.0
+#
+# # Show only the blue colors
+# sprite.red = 0.0
+# sprite.green = 0.0
+# ~~~
+#
+# To add a sprite to the UI it can be anchored to screen borders
+# with `ui_camera.top_left` and the likes.
+#
+# ~~~nitish
+# # Place it a bit off the top left of the screen
+# var pos = app.ui_camera.top_left.offset(128.0, -128.0, 0)
+#
+# # Load texture and create sprite
+# var texture = new Texture("path/in/assets.png")
+# var sprite = new Sprite(texture, pos)
+#
+# # Add it to the UI (above world sprites)
+# app.ui_sprites.add sprite
+# ~~~
class Sprite
# Texture drawn to screen
center_direct = value
end
- # Rotation on the Z axis, positive values go counterclockwise
+ # Rotation on the Z axis, positive values turn counterclockwise
var rotation = 0.0 is writable(rotation_direct=)
- # Rotation on the Z axis, positive values go counterclockwise
+ # Rotation on the Z axis, positive values turn counterclockwise
fun rotation=(value: Float)
do
if isset _rotation and value != rotation then needs_update
# Scale applied to this sprite
#
- # The default size of `self` depends on the size in pixels of `texture`.
+ # The basic size of `self` depends on the size in pixels of `texture`.
var scale = 1.0 is writable(scale_direct=)
- # Scale applied to this sprite, see `scale`
+ # Scale applied to this sprite
+ #
+ # The basic size of `self` depends on the size in pixels of `texture`.
fun scale=(value: Float)
do
if isset _scale and value != scale then needs_update
# Camera for `ui_sprites` using an orthogonal view
var ui_camera = new UICamera(app.display.as(not null)) is lazy
- # World sprites to draw as seen by `world_camera`
+ # World sprites drawn as seen by `world_camera`
var sprites: Set[Sprite] = new SpriteSet
- # UI sprites to draw as seen by `ui_camera`, drawn over world `sprites`
+ # UI sprites drawn as seen by `ui_camera`, over world `sprites`
var ui_sprites: Set[Sprite] = new SpriteSet
# Main method to refine in clients to update game logic and `sprites`
# The data can be compressed by a call to `defragment`.
#
# ~~~
+# intrude import gamnit::flat
+#
# var array = new GroupedArray[String]
# assert array.to_s == ""
#
# Returns the elements that moved as a list.
#
# ~~~
+ # intrude import gamnit::flat
+ #
# var array = new GroupedArray[String]
# array.add "a"
# array.add "b"
# See the License for the specific language governing permissions and
# limitations under the License.
-# Services to load textures, create subtextures and manage their life-cycle
+# Load textures, create subtextures and manage their life-cycle
module textures
import display
-# Abstract gamnit texture
+# Texture composed of pixels, loaded from the assets folder by default
+#
+# Most textures should be created with `App` (as attributes)
+# for the method `on_create` to load them.
+#
+# ~~~
+# import gamnit::flat
+#
+# redef class App
+# # Create the texture object, it will be loaded automatically
+# var texture = new Texture("path/in/assets.png")
+#
+# redef fun on_create()
+# do
+# # Let `on_create` load the texture
+# super
+#
+# # Use the texture
+# var sprite = new Sprite(texture, new Point3d[Float](0.0, 0.0, 0.0))
+# app.sprites.add sprite
+# end
+# end
+# ~~~
+#
+# Otherwise, they can be loaded and error checked explicitly after `on_create`.
+#
+# ~~~nitish
+# var texture = new Texture("path/in/assets.png")
+# texture.load
+# var error = texture.error
+# if error != null then print_error error
+# ~~~
+#
+# A texture may also be created programmatically, like `CheckerTexture`,
+# or derived from another texture, using `subtexture`.
+# Textures with actual pixel data (not `Subtexture`) are `RootTexture`.
+# Texture loaded from the assets folder may in the PNG or JPG formats.
abstract class Texture
# Prepare a texture located at `path` within the `assets` folder
# See the License for the specific language governing permissions and
# limitations under the License.
-# Provides interfaces and classes to represent basic geometry needs.
+# Interfaces and classes to represent basic geometry needs.
module points_and_lines is serialize
import serialization
-# An abstract 2d point, strongly linked to its implementation `Point`
+# Abstract 2d point, strongly linked to its implementation `Point`
interface IPoint[N: Numeric]
# Horizontal coordinate
redef fun ==(o) do return o isa IPoint[Numeric] and o.x == x and o.y == y
end
-# A 2d point and an implementation of `IPoint`
+# 2D point with `x` and `z`
class Point[N: Numeric]
super IPoint[N]
redef var y: N is writable
end
-# An abstract 3d point, strongly linked to its implementation `Point3d`
+# Abstract 3d point, strongly linked to its implementation `Point3d`
interface IPoint3d[N: Numeric]
super IPoint[N]
- # depth coordinate
+ # Depth coordinate
fun z: N is abstract
redef fun to_s do return "({x}, {y}, {z})"
end
-# A 3d point and an implementation of `IPoint3d`
+# 3D point with `x`, `y` and `z`
class Point3d[N: Numeric]
super IPoint3d[N]
super Point[N]
redef var z: N is writable
end
-# An abstract 2d line segment
+# Abstract 2D line segment between two ordered points
interface ILine[N: Numeric]
# The type of points that ends the segment
type P: IPoint[N]
- # The point that is the left-end of the segment
+ # Point at the left-end of the segment
fun point_left: P is abstract
- # The point that is the right-end of the segment
+ # Point at the right-end of the segment
fun point_right: P is abstract
redef fun to_s do return "{point_left}--{point_right}"
end
-# A 2d line segment
+# 2D line segment between two ordered points
class Line[N: Numeric]
super ILine[N]
end
end
-# An abstract 3d line segment
+# Abstract 3D line segment between two ordered points
interface ILine3d[N: Numeric]
super ILine[N]
redef type P: IPoint3d[N]
end
-# A 3d line segment
+# 3D line segment between two ordered points
class Line3d[N: Numeric]
super Line[N]
super ILine3d[N]