Commits

benbeltran committed 6f8605f

Refactor initializers on actors

  • Participants
  • Parent commits 3a3f8ba

Comments (0)

Files changed (13)

actor_factory.lua

 function ActorFactory.create_actor(actor_type, x, y, properties)
   local actor_check = loadstring("return "..actor_type)()
   if actor_check and ActorFactory.should_load(actor_type, x, y) then
-    local generated_actor = actor_check:new(x, y)
-    for k, v in pairs(properties) do
-      if k ~= "spawn" then
-        generated_actor:set_attribute(k,v)
-      end
-    end
+    -- Add everything to properties, and convert the image string to an image object.
+    properties.x = x
+    properties.y = y
+
+    local generated_actor = actor_check:new(properties)
   end
 end
 
 local Actor = class('Actor')
 Actor:include(CustomEventSupport)
 
-function Actor:initialize(x, y, image)
 
-  --set properties with the constructor, with defaults
-  self.x = x or 0
-  self.y = y or 0
-  self.image = love.graphics.newImage(image or "assets/images/sprites/static/cow_64x64.png")
-
-  if not self.name then
-    self.name = "Generic Actor"
-  end
-
-  self.collide = true
-  self.ai = nil
-  self.friendly = true
-  self.fps = 12
-  self.immortal = false
-  self.life = 10
-
-  --bounding box
-  local box_width = self.image:getWidth()
-  local box_height = self.image:getHeight()
-  self.box = {}
-  self.box.top = math.floor(box_height/2)
-  self.box.bottom = math.floor(box_height/2)
-  self.box.left = math.floor(box_width/2)
-  self.box.right = math.floor(box_width/2)
-
-  -- colliders
-  self.collider = {
-    top = false,
+-- Default properties
+-- TODO: Screw middleclass, do this properly
+table.extend(Actor.__instanceDict, {
+  name          = "Generic Actor",
+  x             = 0,
+  y             = 0,
+  image         = "assets/images/sprites/static/cow_64x64.png",
+  collide       = true,
+  friendly      = true,
+  max_x_vel     = 2.5,             -- Maximum Velocity
+  x_acc         = 48.0,            -- Acceleration
+  x_decc        = 48.0,            -- Decceleration
+  x_vel         = 0.0,             -- Current Velocity
+  walk_time     = 0.0,             -- Total Walk time
+  stop_time     = 0.0,             -- Total Stop time
+  dir           = 'right',         -- Current direction.
+  accelerating  = false,           -- accelerating/deccelerating flags.
+  deccelerating = false,
+  max_y_vel     = 12.0,            -- Maximum Air Velocity
+  gravity       = 24.0,            -- Gravity
+  y_acc         = 24.0,            -- Y Acceleration
+  y_vel         = 0.0,             -- Current Air Velocity
+  fall_time     = 0.0,             -- Time falling
+  is_actor      = true,            -- simplify some stuff.
+  box           = {},
+  collider      = {
+    top    = false,
     bottom = false,
-    left = false,
-    right = false
+    left   = false,
+    right  = false
   }
+})
 
-  --horizontal physics variables
-  self.max_x_vel = 2.5      -- Maximum Velocity
-  self.x_acc = 48.0         -- Acceleration
-  self.x_decc = 48.0        -- Decceleration
-  self.x_vel = 0.0          -- Current Velocity
-  self.walk_time = 0.0      -- Total Walk time
-  self.stop_time = 0.0      -- Total Stop time
-  self.dir = 'right'        -- Current direction.
-  self.accelerating = false -- accelerating/deccelerating flags.
-  self.deccelerating = false
-
-  --vertical physics variables
-  self.max_y_vel = 12.0       -- Maximum Air Velocity
-  self.gravity = 24.0         -- Gravity
-  self.y_acc = self.gravity   -- Y Acceleration
-  self.y_vel = 0.0            -- Current Air Velocity
-  self.fall_time = 0.0        -- Time falling
-
-  self.is_actor = true        -- simplify some stuff.
+function Actor:initialize(opts)
+  table.extend(self, opts)
+  self:_resolve_image_string()
+
+  -- Calculate Bounding Box.
+  self:_set_bounding_box()
 
   game.actor_manager:move_in(self)
+  self:_bind_events()
+end
 
-  self:bind_events()
+-- Bind events
+function Actor:_bind_events()
 end
 
-function Actor:bind_events()
+-- If we have a string image, load the resource.
+function Actor:_resolve_image_string()
+  if (type(self.image) == "string") then
+    self.image = love.graphics.newImage(self.image)
+  end
+end
+
+-- If the box is not set, uses the default, which is size of the image.
+function Actor:_set_bounding_box()
+  local box_width = self.image:getWidth()
+  local box_height = self.image:getHeight()
+
+  if not self.box.top then
+    self.box.top = math.floor(box_height/2)
+  end
+  if not self.box.bottom then
+    self.box.bottom = math.floor(box_height/2)
+  end
+  if not self.box.left then
+    self.box.left = math.floor(box_width/2)
+  end
+  if not self.box.right then
+    self.box.right = math.floor(box_width/2)
+  end
 end
 
 function Actor:do_collide(ev)

actors/bovine_head.lua

 local BovineHeadActor = class('BovineHeadActor', Actor)
 
-function BovineHeadActor:initialize(x, y, image)
-  Actor.initialize(self, x, y, image)
-
-  self.name = "Bovine Head"
-  self.immutable = true
-  self.passable = true
-  self.skip_same_collision = true
-
-  self.box.top = 0
-  self.box.bottom = 16
-  self.box.left = 4
-  self.box.right = 4
-
-  self.survives_map = true
-
-  self.key_times = {
-    down = 0,
-    z = 0
+table.extend(BovineHeadActor.__instanceDict, {
+  name                = "Bovine Head",
+  immutable           = true,
+  passable            = true,
+  skip_same_collision = true,
+  survives_map        = true,
+  ended_collision     = 0,
+  box                 = {
+    top    = 0,
+    bottom = 16,
+    left   = 4,
+    right  = 4
+  },
+  key_times           = {
+      down = 0,
+      z    = 0
+  },
+  interaction_helpers = {
+      down = love.graphics.newImage("assets/images/sprites/static/down_key_16x16.png"),
+      z    = love.graphics.newImage("assets/images/sprites/static/z_key_16x16.png")
   }
+})
 
-  self.interaction_helpers = {
-    down = love.graphics.newImage("assets/images/sprites/static/down_key_16x16.png"),
-    z = love.graphics.newImage("assets/images/sprites/static/z_key_16x16.png")
-  }
-  self.ended_collision = 0
+function BovineHeadActor:initialize(opts)
+  Actor.initialize(self, opts)
 end
 
 function BovineHeadActor:draw()
     self.interaction_helper = "down"
     if self.key_times["down"] > 0 and not self.eat_lock then
       self.eat_lock = true
+      self.ended_collision = love.timer.getMicroTime()
       self:dispatch('ate_grass', {grass = ev.other})
       ev.other:dispatch('eaten')
     end
---NOTE: this cat is hella buggy. No clue why and I haven't checked
---but first: y is not centered (I think, maybe it's just a giant gap)
---second: the whole acceleration is weird.
---I haven't touched this since the 90s, but it's crazy.
-
 local CatActor = class('CatActor', Actor)
 
-function CatActor:initialize(x,y,image)
-
-  -- Override default
-  local sent_image = sent_image or "assets/images/sprites/anim/cat_64x64.png"
-
-  self.name = "Cat"
-
-  Actor.initialize(self, x, y, sent_image)
-
-  --define the individual sprite width and height
-  self.sprite_width = 64
-  self.sprite_height = 64
-
+table.extend(CatActor.__instanceDict, {
+  name          = "Cat",
+  sprite_width  = 64,
+  sprite_height = 64,
+  box = {
+    top    = -22,
+    bottom = 32,
+    left   = 8,
+    right  = 8
+  },
+  max_x_vel     = 3,
+  accelerating  = true,
+  friendly      = false,
+  image         = "assets/images/sprites/anim/cat_64x64.png",
+})
+
+function CatActor:initialize(opts)
+  Actor.initialize(self, opts)
   self:create_animation()
-
-  --Redefine bounding box.
-  self.box.top = -22
-  self.box.bottom = 32
-  self.box.left = 8
-  self.box.right = 8
-
-  --horizontal_physics
-  self.max_x_vel = 3
-  self.accelerating = true
-
-  self.friendly = false
 end
 
 function CatActor:create_animation()
 local GrassActor = class('GrassActor', Actor)
 
-function GrassActor:initialize(x, y, color)
-  self.color = color
-  local image = "assets/images/sprites/static/grass_grn_16x16.png"
-
-  if color == "red" then
-    image = "assets/images/sprites/static/grass_red_16x16.png"
-  elseif color == "blue" then
-    image = "assets/images/sprites/static/grass_blu_16x16.png"
+table.extend(GrassActor.__instanceDict, {
+  name                = "Grass",
+  skip_same_collision = true,
+  immutable           = true,
+  passable            = true
+})
+
+function GrassActor:initialize(opts)
+  self:_get_image_for_color()
+  Actor.initialize(self, opts)
+
+  if opts.color then
+    self:_get_image_for_color()
   end
-
-  self.name = "Grass"
-
-  Actor.initialize(self, x, y, image)
-
-  self.skip_same_collision = true
-  self.immutable = true
-  self.passable = true
 end
 
 function GrassActor:set_attribute(key, value)
       image = "assets/images/sprites/static/grass_grn_16x16.png"
     end
     self.image = love.graphics.newImage(image)
+
+    self.box = {}
+    self:_set_bounding_box()
+  end
+end
+
+function GrassActor:_get_image_for_color()
+  local image = "assets/images/sprites/static/grass_grn_16x16.png"
+  if self.color == "red" then
+    image = "assets/images/sprites/static/grass_red_16x16.png"
+  elseif self.color == "blue" then
+    image = "assets/images/sprites/static/grass_blu_16x16.png"
   end
+  self.image = love.graphics.newImage(image)
 
+  self.box = {}
+  self:_set_bounding_box()
 end
 
-function GrassActor:bind_events()
+function GrassActor:_bind_events()
   self:bind('eaten', function (self, ev)
     self:die()
   end)

actors/moving_platform.lua

 local MovingPlatformActor = class('MovingPlatformActor', Actor)
 
-function MovingPlatformActor:initialize(x,y,image)
-
-  -- Override default
-  local sent_image = sent_image or "assets/images/sprites/static/platform_32x16.png"
-
-
-  self.name = "Moving Platform"
-
-  Actor.initialize(self, x, y, sent_image)
-
-  --platform stuff
-  self.x_origin = x
-  self.range = 64
-  self.immutable = true
-  self.gravity = 0.0
-  self.y_acc = 0.0
-
-  --define the individual sprite width and height
-  self.sprite_width = 64
-  self.sprite_height = 64
-
-  self.x_acc = 6
-  self.x_decc = 6
-
-  --horizontal_physics
-  self.max_x_vel = 2
-  self.accelerating = true
+table.extend(MovingPlatformActor.__instanceDict, {
+  image         = "assets/images/sprites/static/platform_32x16.png",
+  name          = "Moving Platform",
+  range         = 64,
+  immutable     = true,
+  gravity       = 0.0,
+  y_acc         = 0.0,
+  sprite_width  = 64,
+  sprite_height = 64,
+  x_acc         = 6,
+  x_decc        = 6,
+  max_x_vel     = 2,
+  accelerating  = true,
+})
+
+function MovingPlatformActor:initialize(opts)
+  Actor.initialize(self, opts)
+
+  self.x_origin = self.x
 end
 
 function MovingPlatformActor:update(dt)

actors/player.lua

 local Player = class('Player', Actor)
 
-function Player:initialize(x, y, image)
-  -- bovine head
-  self.head = BovineHeadActor:new(self.x, self.y, 'assets/images/sprites/static/dot_1x1.png')
-  self.x_head_offset = 16
-  self.y_head_offset = 16
-
-  self.name = "Player"
-
-  Actor.initialize(self, x, y, image)
-
-  self.jumplock = true
-
-  self.box.top = -12
-  self.box.left = 12
-  self.box.right = 12
-
-  self.camera_speed = 2
-
-  self.x_acc = 16.0
-  self.x_decc = 16.0
-
-  self.max_x_vel = 5      -- Maximum Velocity
-  self.max_jump_time = 0.05
-  self.jump_strength = 8.8
-  self.jump_time = 0
-
-  self.key_times = {
-    up = 0,
-    down = 0,
-    left = 0,
+table.extend(Player.__instanceDict, {
+  x_head_offset = 16,          -- Config for the head,
+  y_head_offset = 16,
+  image         = "assets/images/sprites/static/cow_64x64.png",
+  name          = "Player",
+  camera_speed  = 2,
+  x_acc         = 16.0,
+  x_decc        = 16.0,
+  max_x_vel     = 5,      -- Maximum Velocity
+  max_jump_time = 0.05,
+  jumplock      = true,        -- Jump config
+  jump_strength = 8.8,
+  jump_time     = 0,
+  survives_map  = true,
+  stomach       = {"", "", ""},
+  box           = {
+    top   = -12,
+    left  = 12,
+    right = 12,
+  },
+  key_times     = {
+    up    = 0,
+    down  = 0,
+    left  = 0,
     right = 0,
-    z = 0,
-    x = 0
+    z     = 0,
+    x     = 0
   }
+})
 
-  self.survives_map = true
+function Player:initialize(opts)
+  Actor.initialize(self, opts)
+end
 
-  -- stomach
-  self.stomach = {"", "", ""}
+function Player:_create_head()
+  self.head = BovineHeadActor:new({
+    x = self.x,
+    y = self.y,
+    image = 'assets/images/sprites/static/dot_1x1.png'
+  })
 end
 
-function Player:bind_events()
-  Actor.bind_events(self)
+function Player:_bind_events()
+  Actor._bind_events(self)
 
   local player = self
 
+  if not self.head then
+    self:_create_head()
+  end
+
   self.head:bind('ate_grass', function(self, ev)
     player:eat_grass(ev.grass.color)
   end)
   --TODO: Move these "right, left, etc." to a config file. Much laters though.
   --NOTE: Joystick buttons mapped to xbox controller
 
-  self:update_head()
   self:_update_keys()
 
   if self.key_times["x"] > 0 then
   end
 
   self:physics(dt)
+  self:update_head()
   self:centermap()
 
   -- DEBUG

actors/trigger.lua

 local TriggerActor = class('TriggerActor', Actor)
 
-function TriggerActor:initialize(x, y)
-  local image = "assets/images/sprites/static/sign_32x32.png"
-  self.name = "Trigger"
-  Actor.initialize(self, x, y, image)
+table.extend(TriggerActor.__instanceDict, {
+  image               = "assets/images/sprites/static/sign_32x32.png",
+  name                = "Trigger",
+  skip_same_collision = true,
+  immutable           = true,
+  passable            = true,
+  triggerable         = true,
+  box                 = {}
+})
 
-  self.skip_same_collision = true
-  self.immutable           = true
-  self.passable            = true
-  self.triggerable         = true
+function TriggerActor:initialize(opts)
+  Actor.initialize(self, opts)
 end
 
 function TriggerActor:set_attribute(key, value)

lib/extra_table.lua

+local extend = function(self, t)
+  if t then
+    for key, value in pairs(t) do
+      self[key] = value
+    end
+  end
+end
+
+return extend

lib/vendor/middleclass.lua

 
 Object = _createClass("Object", nil)
 
-Object.static.__metamethods = { '__add', '__call', '__concat', '__div', '__le', '__lt', 
+Object.static.__metamethods = { '__add', '__call', '__concat', '__div', '__le', '__lt',
                                 '__mod', '__mul', '__pow', '__sub', '__tostring', '__unm' }
 
 function Object.static:allocate()
   if not _classes[aClass] then return false end
   if aClass.__mixins[mixin] then return true end
   return includes(mixin, aClass.super)
-end
+end
 CustomEvent = require('lib/vendor/custom_event')
 CustomEventSupport = require('lib/vendor/custom_event_support')
 
--- Lib
+-- lib
 require('lib/extra_math')
-
--- Shaders
+table.extend = require('lib/extra_table')
 
 -- Game Components
 
   self.tx = 0
   self.ty = 0
   self.padding = 4
+  self.has_fg = true
   game:move_in(self)
 end
 
 
 function GameScreen:draw()
 
+  local fg_stack = {}
+
   for pos, component in ipairs(self.components) do
     if not component.overlay then
       camera:draw(function(l,t,w,h)
     else
       component:draw()
     end
+
+    if component.has_fg then
+      table.insert(fg_stack, component)
+    end
+  end
+
+  for pos, component in ipairs(fg_stack) do
+    if not component.overlay then
+      camera:draw(function(l,t,w,h)
+        component:draw_fg()
+      end)
+    else
+      component:draw_fg()
+    end
   end
 end