Source

astertris / states / game.lua

Full commit
--- game gamestate
Gamestate.game = Gamestate.new()
local state = Gamestate.game

-- constant

-- state variables
Gamestate.game.inputenabled = false
Gamestate.game.font10 = nil
Gamestate.game.font20 = nil
Gamestate.game.actors = {}
Gamestate.game.objects = {}
Gamestate.game.object = {}
Gamestate.game.next = {}
Gamestate.game.sensors = {}
Gamestate.game.board = {}
Gamestate.game.score = 0
Gamestate.game.pieces = 0
Gamestate.game.level = 0
Gamestate.game.speed = 0
Gamestate.game.world = {}

function state:enter(pre, action, ...)
  -- disable input
  state.inputenabled = false
  
  state.actors = {}
  
  if action == "init" then

    --classes requires
    require("classes/object")
    require("classes/sensor")
    require("classes/board")

    -- fonts
    if not state.font10 then state.font10 = love.graphics.newFont(10) end
    if not state.font20 then state.font20 = love.graphics.newFont(20) end
    
    -- logic
    state.score = 0
    state.pieces = 0
    state.level = 0
    state.speed = 0
  else
  	-- other init action?
  end

  -- graphics
  love.graphics.setBackgroundColor(0, 0, 0)

  state:newLevel(state.level)

  -- enable input
  state.inputenabled = true

end

function state:leave()
end

function state:update(dt)
	
	state.world:update(dt) --this puts the world into motion

  -- actors (explosions, movement, animations...)
  local bremove = false
   
  for i, v in pairs(state.actors) do
    if not v.finished then
      -- if actor pretends no-interactive
      if v.interactive == false then
        state.inputenabled = false
      end
      if v:update(dt) == false then
        bremove = true
      elseif v.modal then
        break
      end
    end
  end
  -- remove 'finished' actors
  if bremove then
    for i = #state.actors, 1, -1 do
      table.remove(state.actors, i)
    end
  end
 
  -- updates
  state.board:update(dt)
  if state.object ~= nil then
    state.object:update(dt)
  end
  if state.next then
  	state.next:update(dt)
  end
  for i, v in pairs(state.objects) do
    if not v.finished then
    	v:update(dt)
    end
  end
  for i, v in pairs(state.sensors) do
    if not v.finished then
    	v:update(dt)
    end
  end
  if state.inputenabled then
	  --here we are going to create some keyboard events
	  if love.keyboard.isDown("right") then
	    if state.object ~= nil then
	      --state.object.body:applyForce(400, 0)
	      state.object.body:applyImpulse(10, 0)
	    end
	  elseif love.keyboard.isDown("left") then
	    if state.object ~= nil then
	      --state.object.body:applyForce(-400, 0)
	      state.object.body:applyImpulse(-10, 0)
	    end
	  elseif love.keyboard.isDown("down") then
	    if state.object ~= nil then
	      --state.object.body:applyForce(0,400)
	      state.object.body:applyImpulse(0,10)
	    end
	  elseif love.keyboard.isDown("Z") then
	    if state.object ~= nil then
	      state.object.r = state.object.r - 0.1
	      state.object.body:setAngle(state.object.r)
	    end
	  elseif love.keyboard.isDown("X") then
	    if state.object ~= nil then
	      state.object.r = state.object.r + 0.1
	      state.object.body:setAngle(state.object.r)
	    end
	  end
  end

end

function state:draw()
  love.graphics.setColor(255, 255, 255, 255)

  -- actors beforemap
  for i, v in pairs(state.actors) do
    if not v.finished then
      if v:draw() then
        v.timing = "beforemap"
      end
      if v.modal then
        break
      end
    end
  end

  -- draws
  state.board:draw()
  if state.object ~= nil then
    state.object:draw()
  end
  if state.next then
  	state.next:draw()
  end
  for i, v in pairs(state.sensors) do
    if not v.finished then
    	v:draw()
    end
  end

  -- actors beforeobjects
  for i, v in pairs(state.actors) do
    if not v.finished then
      if v:draw() then
        v.timing = "aftermap"
      end
      if v.modal then
        break
      end
    end
  end
  
  for i, v in pairs(state.objects) do
    if not v.finished then
    	v:draw()
    end
  end
  
  -- actors afterobjects
  for i, v in pairs(state.actors) do
    if not v.finished then
      if v:draw() then
        v.timing = "afterunits"
      end
      if v.modal then
        break
      end
    end
  end

  -- gui
  --
  --
  love.graphics.setColor(255, 255, 255, 255)
  love.graphics.setFont(state.font20)
  love.graphics.print("Astertris", 20, 60, -0.3)
  --love.graphics.printf("GAME PLACEHOLDER", 100,300,600,'center')
  --love.graphics.printf("esc to exit and return to menu", 100,320,600,'center')
  fps = love.timer.getFPS( )
  love.graphics.setColor(255, 255, 255, 255)
  love.graphics.print("fps:"..fps, 2, 20)
  -- actors aftergui
  for i, v in pairs(state.actors) do
    if not v.finished then
      if v:draw() then
        v.timing = "aftergui"
      end
      if v.modal then
        break
      end
    end
  end
end

function state:keypressed(key, unicode)
  if key == "rctrl" then
    debug.debug()
  elseif key == "escape" then
    Gamestate.switch(Gamestate.menu)
  end
end

function state:mousepressed(x, y, button)
end

function state:mousereleased(x, y, button)
end

function addCollision(a, b, coll)
	--print("add:a")
	--print(to_string(a))
  --print("add:b")
  --print(to_string(b))
  if a.tipo=="object" or b.tipo=="object" then
 		local _obj=b
 		local _oth=a
  	if b.tipo=="object" then
  		_obj=b
  		_oth=a
  	else
  		_obj=a
  		_oth=b
    end
    if _oth.tipo=="objects" or _oth.tipo=="board_bottom" then
    	if _obj.value.body:getY()<state.board.y+5 then
    	  Gamestate.switch(Gamestate.gameover,state.score)
    	end
    	_obj.value:stopInteractive()
    	table.insert(state.objects,_obj.value)
		  state.object=_G.object:new(pLevel,state.board,state.world,true,true,false)
		  state.next=_G.object:new(pLevel,state.board,state.world,false,false,true)
    end
  end
  if a.tipo=='sensor' or b.tipo=='sensor' then
 		local _sen=b
 		local _oth=a
  	if b.tipo=="sensor" then
  		_sen=b
  		_oth=a
  	else
  		_sen=a
  		_oth=b
    end
    _sen.value.activate = _sen.value.activate + 1
  end
end

function persistCollision(a, b, coll)
  if a.tipo=='sensor' or b.tipo=='sensor' then
 		local _sen=b
 		local _oth=a
  	if b.tipo=="sensor" then
  		_sen=b
  		_oth=a
  	else
  		_sen=a
  		_oth=b
    end
    _sen.value.activate = _sen.value.activate + 1
  end
end

function remCollision(a, b, coll)
  if a.tipo=='sensor' or b.tipo=='sensor' then
 		local _sen=b
 		local _oth=a
  	if b.tipo=="sensor" then
  		_sen=b
  		_oth=a
  	else
  		_sen=a
  		_oth=b
    end
    _sen.value.activate = 0
  end
end

function resultCollision(a, b, coll)
	--print("result:a")
	--print(to_string(a))
  --print("result:b")
  --print(to_string(b))
end

function state:newLevel(pLevel)
	math.randomseed(os.time() )
  -- physics
  state.world = love.physics.newWorld(0,0,love.graphics.getWidth( ),love.graphics.getHeight(),0, pLevel*100+200,true)
  state.world:setMeter(30)
  state.world:setCallbacks(addCollision, persistCollision, remCollision, resultCollision)
  -- classes
  state.objects={}
  state.board=_G.board:new(pLevel,state.world)
  for i = 0, 9, 1 do
  	for j = 0, 9, 1 do
  		table.insert(state.sensors,_G.sensor:new(pLevel,state.board,state.world,state.board.x+state.board.w/10*(i+0.5),state.board.y+state.board.h/10*(j+0.5)))
  	end
  end
  state.object=_G.object:new(pLevel,state.board,state.world,true,true,false)
  state.next=_G.object:new(pLevel,state.board,state.world,false,false,true)
  state.speed = pLevel
end