|
|
|
class Scene
|
|
|
|
constructor: (@engine, @name) ->
|
|
|
|
@reset()
|
|
|
|
|
|
|
|
reset: =>
|
|
|
|
@instances = {}
|
|
|
|
@surfaces = []
|
|
|
|
@dirty = true # Triggers first draw
|
|
|
|
@last_instance_id = 100
|
|
|
|
@active = false
|
|
|
|
@width = 800
|
|
|
|
@height = 600
|
|
|
|
@last_width = 800
|
|
|
|
@last_height = 600
|
|
|
|
|
|
|
|
callEvent: (name, data = {}) ->
|
|
|
|
event_map =
|
|
|
|
load: @onLoad
|
|
|
|
|
|
|
|
switch name
|
|
|
|
when "destroy"
|
|
|
|
@destroySelf()
|
|
|
|
@onDestroy?(data)
|
|
|
|
else event_map[name]?.bind(this)(data)
|
|
|
|
|
|
|
|
addTargetSurface: (surface) =>
|
|
|
|
@surfaces.push(surface)
|
|
|
|
@engine.updateCanvasSize(surface, @width, @height)
|
|
|
|
|
|
|
|
$(surface).on("mousemove.radium", (event) =>
|
|
|
|
canvas_pos = surface.getBoundingClientRect()
|
|
|
|
@mouse_x = (event.clientX - canvas_pos.left) | 0
|
|
|
|
@mouse_y = (event.clientY - canvas_pos.top) | 0
|
|
|
|
@checkMouseCollisions()
|
|
|
|
)
|
|
|
|
|
|
|
|
$(surface).on("click.radium", (event) =>
|
|
|
|
@handleClick("click", event)
|
|
|
|
)
|
|
|
|
|
|
|
|
$(surface).on("mouseup.radium", (event) =>
|
|
|
|
@handleClick("mouse_up", event)
|
|
|
|
)
|
|
|
|
|
|
|
|
$(surface).on("mousedown.radium", (event) =>
|
|
|
|
@handleClick("mouse_down", event)
|
|
|
|
)
|
|
|
|
|
|
|
|
@checkActive()
|
|
|
|
|
|
|
|
handleClick: (event_name, event) =>
|
|
|
|
for id, instance of @instances
|
|
|
|
instance.callEvent("#{event_name}_global", {x: @mouse_x, y: @mouse_y, button: event.which})
|
|
|
|
|
|
|
|
if instance.checkPointCollision(@mouse_x, @mouse_y)
|
|
|
|
instance.callEvent(event_name, {x: @mouse_x, y: @mouse_y, button: event.which})
|
|
|
|
|
|
|
|
# Prevent default browser events from occurring on eg. right or middle click
|
|
|
|
event.preventDefault()
|
|
|
|
event.stopPropagation()
|
|
|
|
return false
|
|
|
|
|
|
|
|
removeTargetSurface: (surface) =>
|
|
|
|
@surfaces = @surfaces.filter (obj) -> obj isnt surface
|
|
|
|
$(surface).off("mousemove.radium")
|
|
|
|
@checkActive()
|
|
|
|
|
|
|
|
checkActive: =>
|
|
|
|
active_now = (@surfaces.length > 0)
|
|
|
|
|
|
|
|
if @active and not active_now
|
|
|
|
# Deactivated
|
|
|
|
@callEvent("destroy")
|
|
|
|
else if not @active and active_now
|
|
|
|
# Activated
|
|
|
|
@callEvent("load")
|
|
|
|
|
|
|
|
@active = active_now
|
|
|
|
|
|
|
|
iteration: =>
|
|
|
|
if @width != @last_width or @height != @last_height
|
|
|
|
@engine.updateCanvasSize(surface, @width, @height) for surface in @surfaces
|
|
|
|
[@last_width, @last_height] = [@width, @height]
|
|
|
|
|
|
|
|
for id, instance of @instances
|
|
|
|
if instance.callEvent("step")
|
|
|
|
@dirty = true
|
|
|
|
|
|
|
|
if @dirty
|
|
|
|
@redraw()
|
|
|
|
@dirty = false
|
|
|
|
|
|
|
|
redraw: =>
|
|
|
|
for surface in @surfaces
|
|
|
|
ctx = @engine.getSurface(surface)
|
|
|
|
ctx.clearRect(0, 0, surface.width, surface.height);
|
|
|
|
instance.callEvent("draw", {surface: surface}) for id, instance of @instances
|
|
|
|
|
|
|
|
checkMouseCollisions: =>
|
|
|
|
for id, instance of @instances
|
|
|
|
collision = instance.checkPointCollision(@mouse_x, @mouse_y)
|
|
|
|
|
|
|
|
if collision and not instance._moused_over
|
|
|
|
instance.callEvent("mouseover")
|
|
|
|
instance._moused_over = true
|
|
|
|
else if not collision and instance._moused_over
|
|
|
|
instance.callEvent("mouseout")
|
|
|
|
instance._moused_over = false
|
|
|
|
|
|
|
|
createInstance: (object, x = 0, y = 0) =>
|
|
|
|
id = @last_instance_id += 1
|
|
|
|
real_object = @engine.getObject(object)
|
|
|
|
|
|
|
|
instance = window.Object.create(real_object)
|
|
|
|
instance.x = x
|
|
|
|
instance.y = y
|
|
|
|
instance.id = id
|
|
|
|
instance.scene = this
|
|
|
|
@instances[id] = instance
|
|
|
|
real_object.instances.push(instance)
|
|
|
|
|
|
|
|
instance.callEvent("create")
|
|
|
|
|
|
|
|
return instance
|
|
|
|
|
|
|
|
changeScene: (scene) =>
|
|
|
|
# This will change to a different scene, but inherit the target surfaces
|
|
|
|
pass
|
|
|
|
|
|
|
|
destroySelf: =>
|
|
|
|
@reset
|