WIP TEntity.bmx
SuperStrict
Module engine.core
Import max2d.max2d
Import engine.Script
'Import brl.maxlua
Import BRL.Stream
Import BRL.PNGLoader
Import BRL.JPGLoader
Import BRL.TGALoader
Import BRL.BMPLoader
Import BRL.TextStream
Import DATA.THash
Import DATA.TData
Import BAH.ChipMunk
'Import BAH.BOX2D
Include "include/TAspect.bmx"
Include "include/TListData.bmx"
Include "include/etc.bmx"
Private
Global cpWorld:CPSpace = New CPSpace
Global world:TList = New TList, add@ = True
Global oldPick:TEntity, newPick:TEntity
Global post:TList = New TList
Function Linear#(a#, b#, m#)
Return a + (b - a) * m
End Function
Public
Type TEntity Extends TLuaObject Final
'id
Field name$
'active state
Field _hide@
'transform
Field _pos:Vec2 = New Vec2
Field _scl:Vec2 = Vec2.Create(1.0, 1.0)
Field _ang#
'tween
'Field _tween# Ptr = MemAlloc(20)
Field _oldx# {no_save}
Field _oldy# {no_save}
Field _oldsx# = 1.0 {no_save}
Field _oldsy# = 1.0 {no_save}
Field _oldang# = _ang {no_save}
'script
Field _path$
'hierarhy
Field _parent:TEntity { no_save no_copy hide }
Field _link:TLink = New TLink { no_save no_copy }
Field _childs:TList = New TList { no_copy }
'aspects
Field _aspects:THash = New THash
Method SendMessage:Object(message:Object, context:Object)
Local m$ = String(message)
Select m.ToLower()
Case "angle", "rotate"
Case "turns"
If context = "set"
DebugLog "TURN?"
Turn(Float(String(lua_result)))
End If
Return FloatTypeId
Case "hide"
If context = "get"
lua_result = String(GetHide())
Else
DebugLog "SetHide = "+String(lua_result)
_hide = String(lua_result).ToInt()
DebugLog "Hide field: " + String(_hide)
End If
Return BoolTypeId
Case "name"
If context = "get"
Else
End If
Case "path"
If context = "get"
lua_result = _path
Else
'DebugLog "setter!"
_path = String(lua_result)
End If
Return StringTypeId
End Select
If context = "get"
Local obj:Object = _aspects.ValueForKey(m)
If obj
lua_result = obj
Return ObjectTypeId
End If
Else
End If
End Method
Method New()
name = "Entity_" + Super.ToString()
If add = True Then _link = world.AddLast(Self)
End Method
Method Free()
Invoke("Free")
For Local a:TAspect = EachIn _aspects.Values()
a.Free(Self)
Next
For Local child:TEntity = EachIn _childs
child.Free()
Next
_link.Remove()
_link = Null
_parent = Null
'MemFree(_tween)
'If _parent
' _parent._childs.Remove(Self)
'Else
' world.Remove(Self)
'End If
End Method
Method SetHide(hide@)
_hide = hide
End Method
Method GetHide@()
If _hide Then Return True
Local e:TEntity = _parent
While e
If e._hide Then Return True
e = e._parent
Wend
Return False
End Method
Method Copy:TEntity(parent:TEntity = Null)
End Method
Method SetParent(parent:TEntity = Null, isGlobal@ = True)
If _parent = parent Then Return
Local gp:Vec2 = GetPosition(True)
Local gr:Float = GetRotation(True)
Local gs:Vec2 = GetScale(True)
_link.Remove()
_link = Null
_parent = parent
If _parent = Null
_pos.Set(gp.x, gp.y)
_ang = gr
_scl.Set(gs.x, gs.y)
_link = world.AddLast(Self)
Return
End If
_link = _parent._childs.AddLast(Self)
If isGlobal = True
SetPosition(gp, True)
SetRotation(gr, True)
SetScale(gs, True)
Else
SetPosition(_pos, False)
SetRotation(_ang, False)
SetScale(_scl, False)
End If
End Method
Method GetParent:TEntity()
Return _parent
End Method
Method FindChild:TEntity(name$, isGlobal@ = False)
For Local child:TEntity = EachIn _childs
If child.name = name Then Return child
If Not isGlobal Then Continue
child = child.FindChild(name, True)
If child Then Return child
Next
End Method
Method CountChildren%()
Return _childs.Count()
End Method
Method GetChild:TEntity(index%)
Return TEntity(_childs.ValueAtIndex(index))
End Method
Method SetPosition(pos:Vec2, isGlobal@ = False)
If isGlobal And _parent
_pos.Sub(_parent.GetPosition(True))
_pos.Div(_parent.GetScale(True))
_pos.Rotate(Vec2.ForAngle(_parent.GetRotation(True)))
Else
_pos.Set(pos.x, pos.y)
End If
_oldx = _pos.x
_oldy = _pos.y
End Method
Method GetPosition:Vec2(isGlobal@ = False)
If isGlobal And _parent
Local pos:Vec2 = New Vec2
Local ent:TEntity = Self
While ent
pos.Add(ent._pos)
If ent._parent
pos.Mul(ent._parent._scl)
pos.Rotate(Vec2.ForAngle(ent._parent._ang))
End If
ent = ent._parent
Wend
Return pos
End If
Return _pos.Copy()
End Method
Method SetRotation(angle#, isGlobal@ = False)
If isGlobal And _parent
_ang = (angle - _parent.GetRotation(True))' Mod 360
Else
_ang = angle' Mod 360
End If
_oldang = _ang
End Method
Method GetRotation#(isGlobal@ = False)
If isGlobal And _parent
Local ent:TEntity = _parent
Local ang# = _ang
While ent
ang:+ent._ang
ent = ent._parent
Wend
Return ang' Mod 360
End If
Return _ang' Mod 360
End Method
Method SetScale(scl:Vec2, isGlobal@ = False)
If isGlobal And _parent
_scl = _parent.GetScale(True) '.Div(scl)
_scl.Div(scl)
Else
_scl.Set(scl.x, scl.y)
End If
_oldsx = _scl.x
_oldsy = _scl.y
End Method
Method GetScale:Vec2(isGlobal@ = False)
If isGlobal And _parent
Local ent:TEntity = _parent
Local scl:Vec2 = _scl.Copy()
While ent
scl.Mul(ent._scl)
ent = ent._parent
Wend
Return scl
End If
Return _scl.Copy()
End Method
Method Distance#(target:TEntity)
Local v:Vec2 = GetPosition(True)
v.Sub(target.GetPosition(True))
Return Abs(v.Length())
End Method
Method DeltaAngle#(target:TEntity)
End Method
Method Align(v:Vec2, m# = 1.0)
End Method
Method Compare%(with:Object)
Local ent:TEntity = TEntity(with)
End Method
Method Move(v:Vec2)
_oldx = _pos.x
_oldy = _pos.y
_pos.x:+v.x
_pos.y:+v.y
End Method
Method Turn(angle#)
_oldang = _ang
_ang:+angle
End Method
Method Translate(v:Vec2)
End Method
Method Point(target:TEntity)
End Method
Method ObjectEnumerator:TListEnum()
Return _childs.ObjectEnumerator()
End Method
End Type
Function CreateEntity:TEntity(parent:TEntity = Null)
Local entity:TEntity = New TEntity
If parent Then entity.SetParent(parent)
Return entity
End Function
Function LoadEntity:TEntity(url:Object, parent:TEntity = Null)
add = False
Local obj:Object = LoadObject(url)
add = True
'manager.Load(Null)
Local entity:TEntity = TEntity(obj)
If entity
Load(entity)
entity.SetParent(parent)
Else
Local list:TList = TList(obj)
For entity:TEntity = EachIn list
Load(entity)
entity.SetParent(parent)
Next
entity = Null
End If
Return entity
Function Load(entity:TEntity)
If entity._path <> ""
entity.SetClass(TLuaClass(Manager.Get(entity._path)))
End If
For Local a:TAspect = EachIn entity._aspects.Values()
a.Load(entity)
Next
For Local child:TEntity = EachIn entity._childs
Load(child)
Next
entity.Invoke("Load")
End Function
End Function
Function SaveEntity(url:Object, entity:TEntity = Null)
If entity
SaveObject(entity, url)
Else
SaveObject(world, url)
End If
End Function
Function ClearWorld()
For Local entity:TEntity = EachIn world
entity.Free()
Next
world = New TList
End Function
Function UpdateWorld(capture@ = True)
mouse.x = MouseX()
mouse.y = MouseY()
mouse.z = MouseZ()
mouse.xspeed = MouseXSpeed()
mouse.yspeed = MouseYSpeed()
mouse.zspeed = MouseZSpeed()
If newPick
If newPick <> oldPick
If oldPick Then oldPick.Invoke("Pick", ["-1"])
newPick.Invoke("Pick", ["1"])
Else
newPick.Invoke("Pick", ["0"])
End If
End If
oldPick = newPick
cpWorld.DoStep(1.0 / 60.0)
Local entity:TEntity
post = New TList
For entity = EachIn world
UpdateEntity(entity, capture)
Next
For entity = EachIn post
entity.Invoke("PostLoop", [String(capture)])
Next
Function UpdateEntity(entity:TEntity, capture@)
If entity._hide Then Return
If capture
entity._oldx = entity._pos.x
entity._oldy = entity._pos.y
entity._oldsx = entity._scl.x
entity._oldsy = entity._scl.y
entity._oldang = entity._ang
End If
For Local aspect:TAspect = EachIn entity._aspects.Values()
aspect.Loop(entity, capture)
Next
entity.Invoke("Loop", [String(capture)])
For Local child:TEntity = EachIn entity._childs
UpdateEntity(child, capture)
Next
End Function
End Function
Function RenderWorld(tween# = 1.0)
Cls(black)
TImage.picked = Null
newPick = Null
post = New TList
Local entity:TEntity
Matrix.Push()
For entity = EachIn world
Matrix.Load()
RenderEntity(entity, tween)
Next
For entity = EachIn post
For Local aspect:TPostDraw = EachIn entity._aspects.Values()
Matrix.Load(aspect.Matrix)
Exit
Next
entity.Invoke("PostDraw", [String(tween)])
Next
Matrix.Pop()
Function RenderEntity(entity:TEntity, tween#)
If entity._hide Then Return
Matrix.Translate(Linear(entity._oldx, entity._pos.x, tween), ..
Linear(entity._oldy, entity._pos.y, tween))
Matrix.Scale(Linear(entity._oldsx, entity._scl.x, tween), ..
Linear(entity._oldsy, entity._scl.y, tween))
Matrix.Rotate(Linear(entity._oldang, entity._ang, tween))
entity.Invoke("Draw", [String(tween)])
For Local aspect:TAspect = EachIn entity._aspects.Values()
aspect.Draw(entity, tween)
Next
For Local child:TEntity = EachIn entity._childs
Matrix.Push()
RenderEntity(child, tween)
Matrix.Pop()
Next
End Function
End Function
Function CountChildren%(entity:TEntity = Null)
If entity
Return entity._childs.Count()
Else
Return world.Count()
End If
End Function
Function GetChild:TEntity(index%, entity:TEntity = Null)
If entity
Return TEntity(entity._childs.ValueAtIndex(index))
Else
Return TEntity(world.ValueAtIndex(index))
End If
End Function
Function FindChild:TEntity(name$, entity:TEntity = Null, isGlobal@ = False)
If entity
Return entity.FindChild(name, isGlobal)
Else
For entity = EachIn world
Next
End If
End Function
WIP Aspects.bmx:
Public
Type TAspect Abstract
Method Load(entity:TEntity)
End Method
Method Free(entity:TEntity)
End Method
Method Loop(entity:TEntity, capture@)
End Method
Method Draw(entity:TEntity, tween#)
End Method
End Type
Type TBody Extends TAspect
'Field body:CPBody
'Field shape:CPShape[]
'Field shape:tlBox
Method Loop(entity:TEntity, capture@)
End Method
End Type
Type TMouseAspect Extends TAspect
Method Loop(entity:TEntity, capture@)
entity.SetPosition(Vec2.Create(MouseX(), MouseY()), True)
End Method
End Type
Type TPostLoop Extends TAspect { single }
Method Loop(entity:TEntity, capture@)
post.AddLast(entity)
End Method
End Type
Type TPostDraw Extends TAspect { single }
Field Matrix#[6] { no_edit }
Method Draw(entity:TEntity, tween#)
MemCopy(Matrix, Varptr .Matrix.ix, 24)
post.AddLast(entity)
End Method
End Type
Type TLineCompare Extends TAspect
Field xy#[]
End Type
Type TChildSorter Extends TAspect
Method Loop(entity:TEntity, capture@)
Local array:Object[] = entity._childs.ToArray()
qsort(array)
entity._childs = TList.FromArray(array)
End Method
Function qsort(array:Object[])
End Function
End Type
Type TAnimator Extends TAspect
Field keys#[]
Field AnimSpeed#
Field AnimTime#
Field AnimMode@
Field AnimFunc@
Method Loop(entity:TEntity, c@)
End Method
End Type
Type TSoundStreamed Extends TAspect
Field path$
End Type
Type TSoundAspect Extends TAspect
'Field sound:TSound { no_save }
Field path$ { manager }
Field flags%
Method Play()
' PlaySound(sound)
End Method
Method Load(entity:TEntity)
End Method
End Type
Type TImageAspect Extends TAspect
Field image:TImage { no_save }
Field path$ { manager }
Field flags% = -1
Field blend@ = ALPHABLEND
Field Color#[] = white[..]
Field pick@ = False
Method Load(entity:TEntity)
image = TImage.Load(path, flags)
'image = TImage.Load(Manager.Get(path), flags)
End Method
Method Draw(entity:TEntity, tween#)
SetBlend(blend)
SetColor(Color)
If pick Then image.pick = entity
image.Draw()
'newPick = TImage.picked
If TImage.picked = entity
'entity.Invoke("Pick")
newPick = entity
End If
image.pick = Null
End Method
End Type
Type TParticleAspect Extends TImageAspect
End Type
Type TTextAspect Extends TImageAspect
Field Text$
Field charKerning# = 0
Field lineKerning# = 0
Method Draw(entity:TEntity, tween#)
SetBlend(blend)
SetColor(Color)
SetFont(image, charKerning, lineKerning)
If pick Then image.pick = entity
DrawText(Text)
If TImage.picked = entity
'entity.Invoke("Pick")
newPick = entity
End If
image.pick = Null
End Method
End Type
|