You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
radium/radium/scene.coffee

132 lines
3.2 KiB
CoffeeScript

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
10 years ago
@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()
10 years ago
@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