Merge branch 'split-controller-2' of Kazhnuz/imperium-porcorum into master

This commit is contained in:
Kazhnuz 2019-03-03 16:23:38 +01:00 committed by Gitea
commit 2e02c15757
35 changed files with 917 additions and 958 deletions

View File

@ -1,4 +0,0 @@
return {
["coin"] = {w = 16, h = 16},
["block"] = {w = 16, h = 16},
}

View File

@ -1,8 +1,5 @@
Datas = {}
Datas.levels = require "datas.levels"
Datas.layers = require "datas.layers"
Datas.entities = require "datas.entities"
Datas.vpad = require "datas.vpad"
return Datas

View File

@ -1,3 +0,0 @@
return {
"wall", "platform", "water"
}

View File

@ -1,12 +0,0 @@
return {
{
["left"] = "left",
["right"] = "right",
["up"] = "up",
["down"] = "down",
["A"] = "a",
["B"] = "z",
["C"] = "e",
["start"] = "return",
}
}

View File

@ -25,7 +25,6 @@ datas = require "datas"
utils = require "libs.loveutils"
menus = require "modules.menus"
assets = require "modules.assets"
vpad = require "modules.vpad"
scenes = require "scenes"
@ -42,7 +41,6 @@ function love.load() -- On charge la scene de départ (pour l'instant le menu, b
game.pigmanager:addPig("cochon")
assets:init()
virtualpad = vpad()
scenes.MainMenu()
end

View File

@ -1,37 +0,0 @@
local VPad = Object:extend()
local defaultVPad = require "datas.vpad"
function VPad:new()
self.keyboard = defaultVPad
end
function VPad:getData(playerID)
return self.keyboard[playerID]
end
function VPad:translateAction(playerID, key)
local padkey = ""
for k,v in pairs(self.keyboard[playerID]) do
if v == key then padkey = k end
end
return padkey
end
function VPad:getKey(playerID, padkey)
local padkey = padkey
for k,v in pairs(self.keyboard[playerID]) do
if (k == padkey) then key = v end
end
return key
end
function VPad:isDown(playerID, padkey)
local isdown = false
local key = self:getKey(playerID, padkey)
isdown = love.keyboard.isDown(key)
return isdown
end
return VPad

View File

@ -1,41 +1,112 @@
function Level:initCamera(x, y)
self.camera = Camera(x, y, 1, 0, true)
--local width, height = love.graphics.getDimensions()
local CameraSystem = Object:extend()
-- INIT FUNCTIONS
-- Initialize the camera system
function CameraSystem:new(scene, x, y)
self.scene = scene
self.world = scene.world
self.view = Camera(x, y, 1, 0, true)
local width, height, flags = love.window.getMode( )
self.screenWidth = width
self.screenHeight = height
self.cameraWidth = 480
self.cameraHeight = 272
self.viewWidth = 424
self.viewHeight = 240
self.resolution = self.screenWidth / self.cameraWidth
self:limitCamera()
self.resolution = self.screenWidth / self.viewWidth
self:limit()
end
function Level:floorCameraCoord()
self.camera.x, self.camera.y = utils.math.floorCoord(self.camera.x, self.camera.y)
print(self.camera.x .. ";" .. self.camera.y)
-- WRAPPER and UTILS
-- Access data from the camera
function CameraSystem:floorCoord()
self.view.x, self.view.y = utils.math.floorCoord(self.view.x, self.view.y)
end
function Level:updateCamera(dt)
self:cameraFollowPlayer(self.activePlayer)
self:limitCamera()
self:floorCameraCoord()
function CameraSystem:getCoord()
local camx, camy, camh, camw
camx = self.view.x - (self.viewWidth/2)
camy = self.view.y - (self.viewHeight/2)
camw = self.viewWidth
camh = self.viewHeight
return camx, camy, camw, camh
end
function Level:cameraFollowPlayer(id)
local player = self:getPlayerByID(id)
function CameraSystem:getScale()
return self.view.scale
end
function CameraSystem:getScreenCoord()
local camx, camy, camh, camw
camx = self.view.x - (self.screenWidth/2)
camy = self.view.y - (self.screenHeight/2)
camw = self.screenWidth
camh = self.screenHeight
return camx, camy, camw, camh
end
function CameraSystem:worldCoord(x, y, ox, oy, w, h)
ox, oy = ox or 0, oy or 0
w,h = w or love.graphics.getWidth(), h or love.graphics.getHeight()
return self.view:worldCoords(x, y, ox, oy, w, h)
end
function CameraSystem:cameraCoords(x, y)
return self.view:cameraCoords(x, y, ox, oy, w, h)
end
function CameraSystem:getVisibleEntities()
local camx, camy, camw, camh = self:getScreenCoord()
local visibleThings, len = self.world:queryRect(camx-64, camy-64, camw+128, camh+128)
return visibleThings, len
end
function CameraSystem:isInsideView(x, y, w, h, border)
local camx, camy, camw, camh = self:getCoord()
local border = border or 0
if (x + w + border >= camx) and (x < camx + camw + border)
and (y + h + border >= camy) and (y < camy + camh + border) then
return true
else
return false
end
end
function CameraSystem:attach()
self.view:attach()
end
function CameraSystem:detach()
self.view:detach()
end
-- UPDATE and MOVE functions
-- Move and update the camera system
function CameraSystem:update(dt)
self:followPlayer(self.scene.playermanager.activePlayer)
self:limit()
self:floorCoord()
end
function CameraSystem:followPlayer(id)
local player = self.scene.playermanager:getPlayerByID(id)
if (player ~= nil) then
local playx, playy = utils.math.floorCoord(player.center.x,
player.center.y)
local camx, camy = self.camera.x + (self.cameraWidth/2),
self.camera.y + (self.cameraHeight/2)
local camx, camy = self.view.x + (self.viewWidth/2),
self.view.y + (self.viewHeight/2)
playx, playy = self:cameraCoords(playx, playy)
playx = playx - (self.cameraWidth/2)
playy = playy - (self.cameraHeight/2)
playx = playx - (self.viewWidth/2)
playy = playy - (self.viewHeight/2)
if (math.abs(playx) > 8) then
camx = camx + (playx - (8*utils.math.sign(playx)))
@ -47,28 +118,23 @@ function Level:cameraFollowPlayer(id)
camy = camy + (playy + 64)
end
self.camera.x, self.camera.y = camx - (self.cameraWidth/2),
camy - (self.cameraHeight/2)
self.view.x, self.view.y = camx - (self.viewWidth/2),
camy - (self.viewHeight/2)
end
end
function Level:debugDrawCameraPlayerZone()
--
function CameraSystem:move(x, y)
self.view.x = x
self.view.y = y
self:limit()
end
function Level:moveCamera(x, y)
self.camera.x = x
self.camera.y = y
self:limitCamera()
end
function Level:limitCamera()
local camx, camy = self.camera.x, self.camera.y
function CameraSystem:limit()
local camx, camy = self.view.x, self.view.y
local camMinX, camMinY = (self.screenWidth/2), (self.screenHeight/2)
local camMaxX, camMaxY = self.map.width * self.map.tilewidth,
self.map.height * self.map.tileheight
local camMaxX, camMaxY = self.world:getDimensions()
if (self.resolution == 1) then
camMaxX, camMaxY = camMaxX - camMinX, camMaxY - camMinY
@ -81,42 +147,7 @@ function Level:limitCamera()
camy = math.max(camy, camMinY)
camy = math.min(camy, camMaxY)
self.camera.x, self.camera.y = camx, camy
self.view.x, self.view.y = camx, camy
end
function Level:getCameraCoord()
local camx, camy, camh, camw
camx = self.camera.x - (self.cameraWidth/2)
camy = self.camera.y - (self.cameraHeight/2)
camw = self.cameraWidth
camh = self.cameraHeight
return camx, camy, camw, camh
end
function Level:getScreenCoord()
local camx, camy, camh, camw
camx = self.camera.x - (self.screenWidth/2)
camy = self.camera.y - (self.screenHeight/2)
camw = self.screenWidth
camh = self.screenHeight
return camx, camy, camw, camh
end
function Level:cameraWorldCoord(x, y, ox, oy, w, h)
ox, oy = ox or 0, oy or 0
w,h = w or love.graphics.getWidth(), h or love.graphics.getHeight()
return self.camera:worldCoords(x, y, ox, oy, w, h)
end
function Level:cameraCoords(x, y)
return self.camera:cameraCoords(x, y, ox, oy, w, h)
end
function Level:getVisibleEntities()
local camx, camy, camw, camh = self:getScreenCoord()
local visibleThings, len = self.world:queryRect(camx-64, camy-64, camw+128, camh+128)
return visibleThings, len
end
return CameraSystem

View File

@ -1,166 +1,94 @@
Level = Object:extend() -- On créer la classe des entitées, c'est la classe de base
local Level = Object:extend() -- On créer la classe des entitées, c'est la classe de base
require "scenes.levels.controller.virtualpad"
local World = require "scenes.levels.controller.world"
local Camera = require "scenes.levels.controller.camera"
local PlayerManager = require "scenes.levels.controller.players"
require "scenes.levels.controller.world"
require "scenes.levels.controller.camera"
require "scenes.levels.controller.players"
require "scenes.levels.controller.debug"
local leveldatas = require "datas.levels"
-- INIT FUNCTIONS
-- Initialize and launch the level
function Level:new()
self:reset()
end
function Level:reset()
self.levelRealm = ""
self.levelName = ""
self.missionName = ""
self.missionDesc = ""
self.mapfile = "level1"
self.gravity = 0
self.autorun = 1
self.objectiveID = 0
self.startx = 32
self.starty = 420/2
self.datas = {}
self.pause = false
self.map = nil
self.backcolor = {0, 0, 0}
self.itemList = {}
self.score = 0
self.gold = 0
self:resetPlayers()
self:resetPads()
self:setDebugMode(true)
end
function Level:loadMission(levelID, missionID)
local leveldatas, missiondatas
leveldatas = datas.levels[levelID]
missiondatas = leveldatas.missions[missionID]
self.levelRealm = leveldatas.realm
self.levelName = leveldatas.name
self.missionName = missiondatas.missionName
self.missionDesc = missiondatas.description
self.mapfile = missiondatas.mapfile
self.gravity = missiondatas.gravity
self.autorun = missiondatas.autorun
self.objectiveID = missiondatas.objectiveID
self.startx = missiondatas.startx
self.starty = missiondatas.starty
local datas, missiondatas
self.datas = {}
datas = leveldatas[levelID]
self.datas.realm = datas.realm
self.datas.level = datas.name
self:initWorld()
assets:setMusic(missiondatas.music)
missiondatas = datas.missions[missionID]
self.datas.missions = {}
self.datas.missions.name = missiondatas.missionName
self.datas.missions.desc = missiondatas.description
self.datas.missions.map = missiondatas.mapfile
self.datas.missions.gravity = missiondatas.gravity
self.datas.missions.autorun = missiondatas.autorun
self.datas.missions.objectiveID = missiondatas.objectiveID
self.datas.missions.startx = missiondatas.startx
self.datas.missions.starty = missiondatas.starty
self.datas.missions.music = missiondatas.music
self.world = World(self, self.datas.missions.map)
self.world:load()
assets:setMusic(self.datas.missions.music)
self:launchMission()
end
function Level:launchMission()
self:resetPlayers()
self:resetPads()
self.playermanager = PlayerManager(self)
--self:resetSpawnAndEntities()
assets:silence()
assets:playMusic()
self:initCamera(0, 0)
self.playermanager:addPlayer(1)
self.playermanager:spawnPlayer(1)
self:addPlayer(1)
self:spawnPlayer(1)
local padid = self:addPad(Pad(1))
self.virtualpads[padid]:addKey("up","up")
self.virtualpads[padid]:addKey("down","down")
self.virtualpads[padid]:addKey("left","left")
self.virtualpads[padid]:addKey("right","right")
self.virtualpads[padid]:addKey("a","A")
self.virtualpads[padid]:addKey("z","B")
self.virtualpads[padid]:addKey("e","C")
self.camera = Camera(self, self.playermanager.startx, self.playermanager.starty)
self.score = 0
self.gold = 0
end
-- UPDATE FUNCTIONS
-- Update the level
function Level:update(dt)
self:updateMap(dt)
self.keys = core.input.keys
if (self.pause == false) then
self:updatePlayerSystem(dt)
self:worldUpdate(dt)
self.playermanager:update(dt)
self.world:update(dt)
assets:update(dt)
self:updateCamera(dt)
self.camera:update(dt)
end
end
-- DRAW FUNCTIONS
-- draw level elements
function Level:draw(dt)
love.graphics.setColor(1, 1, 1, 1) -- On reset la couleur.
utils.graphics.resetColor()
-- Ona attache puis détache la caméra pour dessiner le monde, afin que celui
-- reste "fixe" tandis que le jouer bouge.
self:floorCameraCoord()
self:drawBackgroundColor()
self.camera:attach()
self.camera:floorCoord()
self.world:draw()
self:drawMap()
self:drawCollisions()
self:worldDraw()
self.camera:detach()
if (self.pause == false) then
self:drawHUD()
self.playermanager:drawHUD()
end
self:drawDebugHUD()
end
function Level:drawMap()
local tx = self.camera.x - 424 / 2
local ty = self.camera.y - 240 / 2
tx = math.floor(tx)
ty = math.floor(ty)
self.map:draw(-tx, -ty, self.camera.scale, self.camera.scale)
end
function Level:drawBackgroundColor()
local r, g, b = self.backcolor[1], self.backcolor[2], self.backcolor[3]
love.graphics.setColor(r/256, g/256, b/256)
love.graphics.rectangle("fill", 0, 0, 480, 272)
utils.graphics.resetColor()
end
function Level:drawHUD(dt)
utils.graphics.resetColor()
local hp = 0
local mp = 0
local weapon = 0
assets.textbox["yellowbox"]:draw(16,16,24,24)
if self:playerHaveObject(1) then
local player = self:getPlayerByID(1)
hp = player.hp / player.stats.maxHP
mp = player.mp / player.stats.maxMP
weapon = player.weapon
end
if (weapon ~= 0) and (weapon ~= nil) then
assets.sprites["weapon"]:drawIcon(weapon,28,28,0,1,1,8,8)
end
assets.progressbar["greenbar"]:draw("HP", 68, 14, 96, hp, "")
assets.progressbar["bluebar"]:draw("MP", 68, 30, 96, mp, "")
assets.fonts["medium"]:set()
love.graphics.printf( utils.math.numberToString(self.score, 6), 373, 10, 96, "right")
love.graphics.printf( utils.math.numberToString(self.gold, 4), 373, 25, 96-18, "right")
love.graphics.setColor(1, 1, 85/256)
love.graphics.printf( "G", 373, 25, 96, "right")
utils.graphics.resetColor()
end
return Level

View File

@ -1,10 +1,24 @@
function Level:resetPlayers(player)
self.players = {}
self.deathTimer = -100
local PlayerManager = Object:extend()
local Obj = require "scenes.levels.entities"
function PlayerManager:new(scene)
self.scene = scene
self.players = {}
self.deathTimer = -100
self.activePlayer = -1
self.startx, self.starty = self.scene.world:getStartPosition()
self.itemList = {}
self.score = 0
self.gold = 0
end
function Level:addPlayer(pigID)
-- PLAYER FUNCTIONS
-- Handle virtual players
-- TODO: Gérer la manière dont le joueur va avoir une équipe de cochons
function PlayerManager:addPlayer(pigID)
-- Enregistrer le joueur n'est pas le rajouter à une liste des objets qui existe,
-- mais juste insérer ses informations les plus importantes afin d'aider le jeu
-- à pouvoir le reconstruire.
@ -15,14 +29,14 @@ function Level:addPlayer(pigID)
table.insert(self.players, play)
end
function Level:spawnPlayer(playerID)
function PlayerManager:spawnPlayer(playerID)
local play = self.players[playerID]
Player(self, playerID, self.startx, self.starty)
Obj.Player(self.scene, self.startx, self.starty, playerID)
self.activePlayer = playerID
end
function Level:getPlayers()
local itemList = self:getEntities()
function PlayerManager:getPlayers()
local itemList = self.scene.world:getEntities()
local playerList = {}
for i,v in ipairs(itemList) do
@ -34,10 +48,14 @@ function Level:getPlayers()
return playerList
end
function Level:getPlayerByID(id)
local itemList = self:getEntities()
function PlayerManager:getPlayerByID(id)
local itemList = self.scene.world:getEntities()
local player
if (id == nil) then
error("You must have an ID to search")
end
for i,v in ipairs(itemList) do
if (v.playerID == id) then
player = v
@ -47,15 +65,15 @@ function Level:getPlayerByID(id)
return player
end
function Level:playerExist(id)
function PlayerManager:playerExist(id)
return (self.players[id] ~= nil)
end
function Level:setDeathTimer(timer)
function PlayerManager:setDeathTimer(timer)
self.deathTimer = timer
end
function Level:playerHaveObject(id)
function PlayerManager:playerHaveObject(id)
player = self:getPlayerByID(id)
if (player == nil) then
@ -65,9 +83,10 @@ function Level:playerHaveObject(id)
end
end
function Level:updatePlayerSystem(dt)
self:updatePads(dt)
-- UPDATE FUNCTIONS
-- Update the death timer and respawn the player when it's done
function PlayerManager:update(dt)
if (self.deathTimer > 0) then
self.deathTimer = self.deathTimer - dt
elseif (self.deathTimer > -100) then
@ -75,3 +94,37 @@ function Level:updatePlayerSystem(dt)
self.deathTimer = -100
end
end
-- DRAW FUNCTIONS
-- Functions made to draw the HUD
function PlayerManager:drawHUD(dt)
utils.graphics.resetColor()
local hp = 0
local mp = 0
local weapon = 0
assets.textbox["yellowbox"]:draw(16,16,24,24)
if self:playerHaveObject(1) then
local player = self:getPlayerByID(1)
hp = player.hp / player.stats.maxHP
mp = player.mp / player.stats.maxMP
weapon = player.weapon
end
if (weapon ~= 0) and (weapon ~= nil) then
assets.sprites["weapon"]:drawIcon(weapon,28,28,0,1,1,8,8)
end
assets.progressbar["greenbar"]:draw("HP", 68, 14, 96, hp, "")
assets.progressbar["bluebar"]:draw("MP", 68, 30, 96, mp, "")
assets.fonts["medium"]:set()
love.graphics.printf( utils.math.numberToString(self.score, 6), 373, 10, 96, "right")
love.graphics.printf( utils.math.numberToString(self.gold, 4), 373, 25, 96-18, "right")
love.graphics.setColor(1, 1, 85/256)
love.graphics.printf( "G", 373, 25, 96, "right")
utils.graphics.resetColor()
end
return PlayerManager

View File

@ -1,53 +0,0 @@
--[[ scenes.levels.controller.virtualpad
Ce fichier va contenir le système de détection des touches, indispensables
pour pouvoir envoyer les actions au joueur. Il détecte les touches sur lesquels
le joueur appue, et les retranscrit en tant que touche megadrive, afin de
permettre au joueur de pouvoir agir sur le joueur.
Chaque "manette virtuelle" est enregistrée séparément, et les moyens de l'activer
peuvent être différentes, suivant les touches]
--]]
Pad = Object:extend()
function Level:resetPads()
self.virtualpads = {}
end
function Level:addPad(pad)
table.insert(self.virtualpads, pad)
return #self.virtualpads
end
function Level:updatePads()
for i,v in ipairs(self.virtualpads) do
local player = self:getPlayerByID(self.activePlayer)
if (player ~= nil) then
for k, u in pairs(v.keys) do
if virtualpad:isDown(1, u.padTouch) then
player:padPush(u.padTouch, true)
else
player:padPush(u.padTouch, false)
end
end
end
end
end
function Pad:new(playerid)
self.keys = {}
self.playerID = playerid
end
function Pad:addKey(key, padTouch)
local id = #self.keys + 1
self.keys[id] = {}
self.keys[id].key = key
self.keys[id].padTouch = padTouch
end
function Pad:update(dt)
end

View File

@ -1,17 +1,26 @@
function Level:initWorld()
self.map = Sti("assets/maps/" .. self.mapfile .. ".lua")
self.world = Bump.newWorld(50)
local World = Object:extend()
local Obj = require "scenes.levels.entities"
-- INIT FUNCTIONS
-- All functions to init the world and the map
function World:new(scene, mapfile)
self.scene = scene
self.map = Sti("assets/maps/" .. mapfile .. ".lua")
self.obj = Obj
self.entities = Bump.newWorld(50)
self.backcolor = self.map.backgroundcolor or {0, 0, 0}
self.blocks = {} -- On vide la liste des blocks
self.activeObjects = 0
self:loadCollisions()-- On charge les collisions
self:loadEntities()
self:getStartPosition()
end
function Level:loadEntities()
function World:load()
self:loadCollisions()
self:loadEntities()
end
function World:loadEntities()
for k, objectlayer in pairs(self.map.layers) do
if (self:isEntityLayer(objectlayer.name)) then
for k, object in pairs(objectlayer.objects) do
@ -23,9 +32,12 @@ function Level:loadEntities()
end
end
function Level:addEntityByNameOnGrid(name, x, y, w, h)
local layerdata = datas.entities
local objWidth, objHeight = layerdata[name].w, layerdata[name].h
function World:isEntityLayer(layername)
return (self.obj.index[layername] ~= nil)
end
function World:addEntityByNameOnGrid(name, x, y, w, h)
local objWidth, objHeight = 16, 16
local cellHor = math.ceil(w / objWidth)
local cellVert = math.ceil(h / objHeight)
for i=1, cellHor do
@ -33,90 +45,103 @@ function Level:addEntityByNameOnGrid(name, x, y, w, h)
self:addEntityByName(name, x + (i-1)*objWidth, y + (j-1)*objHeight)
end
end
end
function Level:addEntityByName(name, x, y)
if name == "coin" then
Loot(self, "coin", 1, x, y)
end
if name == "block" then
Block(self, 0, x, y)
end
function World:addEntityByName(name, x, y)
self.obj.index[name](self.scene, x, y)
end
function Level:isEntityLayer(layername)
local layerdata = datas.entities
local isEntityLayer = false
if not (layerdata[layername] == nil) then
isEntityLayer = true
end
return isEntityLayer
end
function Level:getStartPosition()
for k, objectlayer in pairs(self.map.layers) do
if objectlayer.name == "playerstart" then
for k, object in pairs(objectlayer.objects) do
self.startx = object.x + (object.width/2)
self.starty = object.y + (object.height) - 12
end
self.map:removeLayer("playerstart")
end
end
return self.startx, self.starty
end
function Level:loadCollisions()
function World:loadCollisions()
for k, objectlayer in pairs(self.map.layers) do
if self:isCollisionLayer(objectlayer.name) then
for k, object in pairs(objectlayer.objects) do
self:addCollision(objectlayer.name,object.x,object.y,object.width,object.height)
self:addCollision(object.x,object.y,object.width,object.height, objectlayer.name)
end
self.map:removeLayer(objectlayer.name)
end
end
end
function Level:addCollision(name, x, y, w, h) -- Rajouter un block solide dans le monde physique
--block.collType = name
function World:getStartPosition()
local startx, starty
for k, objectlayer in pairs(self.map.layers) do
if objectlayer.name == "playerstart" then
for k, object in pairs(objectlayer.objects) do
startx = object.x + (object.width/2)
starty = object.y + (object.height) - 12
end
self.map:removeLayer("playerstart")
end
end
return startx, starty
end
function World:isCollisionLayer(layername)
return (self.obj.collisions[layername] == true)
end
function World:addCollision(x, y, w, h, name)
-- Rajouter un block solide dans le monde physique
if w == 0 then
w = 1
end
local block = Collision(self, name, x, y, w, h)--{x=x,y=y,w=w,h=h,solid=1}
self.blocks[#self.blocks+1] = block -- On ajoute le block à la liste des blocks
--self:addPhysicalObject(block, x,y,w,h) -- On le rajoute au monde physique
self.obj.Collision(self.scene, x, y, w, h, name)
end
function Level:isCollisionLayer(layername)
layerdata = datas.layers
local isCollisionLayer = false
-- ENTITY MANAGEMENT FUNCTIONS
-- All BUMP2D wrappers
for k, validname in pairs(layerdata) do
if (layername == validname) then
isCollisionLayer = true
end
end
return isCollisionLayer
function World:addEntity(entity)
return self.entities:add(entity, entity.x, entity.y, entity.w, entity.h)
end
function Level:addPhysicalObject(object, x, y, w, h)
return self.world:add(object, x, y, w, h) -- On le rajoute au monde physique
function World:moveEntity(entity, x, y, filter)
return self.entities:move(entity, x, y, filter)
end
function Level:movePhysicalObject(object, x, y, filter)
self:addBlock(0,0,1,1)
return world:move(object, x, y, filter)
function World:removeEntity(entity)
return self.entities:remove(entity)
end
function Level:worldUpdate(dt)
function World:queryRect(x, y, w, h)
return self.entities:queryRect(x, y, w, h)
end
function World:countEntities()
return self.entities:countItems()
end
function World:getEntities()
return self.entities:getItems()
end
-- MAP FUNCTIONS
-- All map wrappers
function World:getDimensions()
return self.map.width * self.map.tilewidth,
self.map.height * self.map.tileheight
end
function World:setBackgroundColor(r, g, b)
self.backcolor = {r, g, b}
end
function World:getBackgroundColor()
return self.backcolor[1]/256, self.backcolor[2]/256, self.backcolor[3]/256
end
-- UPDATE FUNCTIONS
-- All update functions
function World:update(dt)
self:updateEntities(dt)
self:updateMap(dt)
end
function World:updateEntities(dt)
--l,t,w,h = l or 0, t or 0, w or self.width, h or self.height
local visibleThings, len = self:getVisibleEntities()
local visibleThings, len = self.scene.camera:getVisibleEntities()
--table.sort(visibleThings, sortByUpdateOrder)
for i=1, len do
@ -126,9 +151,26 @@ function Level:worldUpdate(dt)
self.activeObjects = len
end
function Level:worldDraw(dt)
function World:updateMap(dt)
self.map:update(dt)
end
-- DRAW FUNCTIONS
-- All function to draw the map, world and entities
function World:draw()
-- Ona attache puis détache la caméra pour dessiner le monde, afin que celui
-- reste "fixe" tandis que le jouer bouge.
self:drawBackgroundColor()
self.scene.camera:attach()
self:drawMap()
self:drawEntities()
self.scene.camera:detach()
end
function World:drawEntities()
--l,t,w,h = l or 0, t or 0, w or self.width, h or self.height
local visibleThings, len = self:getVisibleEntities()
local visibleThings, len = self.scene.camera:getVisibleEntities()
--table.sort(visibleThings, sortByUpdateOrder)
for i=1, len do
@ -136,10 +178,25 @@ function Level:worldDraw(dt)
end
end
function Level:updateMap(dt)
self.map:update(dt)
function World:drawMap()
-- Du à la manière dont fonctionne STI, on est obligé de récupérer les info
-- de position de camera pour afficher la carte par rapport à ces infos
local tx, ty = self.scene.camera:getCoord()
local scale = self.scene.camera:getScale()
local tx = tx
local ty = ty
tx = math.floor(tx)
ty = math.floor(ty)
self.map:draw(-tx, -ty, scale, scale)
end
function Level:getEntities()
return self.world:getItems()
function World:drawBackgroundColor()
local r, g, b = self.backcolor[1], self.backcolor[2], self.backcolor[3]
love.graphics.setColor(r/256, g/256, b/256)
love.graphics.rectangle("fill", 0, 0, 480, 272)
utils.graphics.resetColor()
end
return World

View File

@ -1,9 +1,10 @@
Block = Entity:extend()
local Entity = require "scenes.levels.entities.parent"
function Block:new(level, item, x ,y)
Block.super.new(self, level, x, y, 16, 16)
local Block = Entity:extend()
function Block:new(level, x , y, item)
Block.super.new(self, level, "block", x, y, 16, 16)
self.item = item or 0
self.collType = "block"
end
function Block:draw(dt)
@ -14,12 +15,14 @@ function Block:breakBlock()
local x, y = self:getCenter()
local spd, duration = 250, 5
local dist = 0
Debris(self.level, x+dist, y-dist, spd, 270+45, duration)
Debris(self.level, x+dist, y+dist, spd, 45, duration)
Debris(self.level, x-dist, y+dist, spd, 180+45, duration)
Debris(self.level, x-dist, y-dist, spd, 180-45, duration)
GFX(self.level, "poof", 1, self.x+8, self.y+8)
self.obj.Debris(self.level, x+dist, y-dist, spd, 270+45, duration)
self.obj.Debris(self.level, x+dist, y+dist, spd, 45, duration)
self.obj.Debris(self.level, x-dist, y+dist, spd, 180+45, duration)
self.obj.Debris(self.level, x-dist, y-dist, spd, 180-45, duration)
self.obj.GFX(self.level, self.x+8, self.y+8, "poof", 1)
assets:playSFX("break")
self.level.score = self.level.score + 10
self:destroy()
end
return Block

View File

@ -1,10 +1,11 @@
Bullet = Entity:extend()
local Entity = require "scenes.levels.entities.parent"
local Bullet = Entity:extend()
function Bullet:new(level, x, y, w, h, speed, dir)
Bullet.super.new(self, level, x - (w / 2), y - (h / 2), w, h)
Bullet.super.new(self, level, "bullet", x - (w / 2), y - (h / 2), w, h)
self.life = 0;
--world:add(self, self.x, self.y, self.w, self.h)
self.collType="bullet"
self:setMotionDirection(dir, speed)
end
@ -33,8 +34,8 @@ function Bullet:update(dt)
self.life = 1
local localx, localy = currentLevel:cameraCoords(self.x, self.y)
if (localx < 0) or (localx > 480) or (localy < 0) or (localy > (272)) or (self.xsp == 0) then
local isInsideView = self:isInsideView()
if (isInsideView == false) or (self.xsp == 0) then
self:destroy()
end
end
@ -42,3 +43,5 @@ end
function Bullet:draw(dt)
currentLevel:drawHitbox(self, 0,128,0)
end
return Bullet

View File

@ -1,8 +1,11 @@
Collision = Entity:extend()
local Entity = require "scenes.levels.entities.parent"
function Collision:new(level, collType, x, y, w, h)
Collision.super.new(self, level, x, y, w, h)
self.collType = collType
local Collision = Entity:extend()
function Collision:new(level, x, y, w, h, collType)
Collision.super.new(self, level, collType, x, y, w, h)
self:setDebugColor(0,0,0)
end
return Collision

View File

@ -1,12 +1,13 @@
Debris = Entity:extend()
local Entity = require "scenes.levels.entities.parent"
local Debris = Entity:extend()
function Debris:new(level, x, y, speed, dir, timelimit)
Debris.super.new(self, level, x - 4, y - 4, 8, 8)
Debris.super.new(self, level, "debris", x - 4, y - 4, 8, 8)
self.life = 0;
self.timer = 0
self.timelimit = timelimit
--world:add(self, self.x, self.y, self.w, self.h)
self.collType = "debris"
self:setMotionDirection(dir, speed)
self.grav = 1
self.bounce = 0.5
@ -34,8 +35,8 @@ function Debris:update(dt)
self.life = 1
local localx, localy = self.level:cameraCoords(self.x, self.y)
if (localx < 0) or (localx > 480) or (localy < 0) or (localy > (272)) or (self.xsp == 0) then
local isInsideView = self:isInsideView()
if (isInsideView == false) or (self.xsp == 0) then
self:destroy()
end
@ -52,3 +53,5 @@ function Debris:draw(dt)
assets.sprites["debris"]:draw(1, drawx, drawy, rotation,
1, 1, 4, 4)
end
return Debris

View File

@ -1,14 +1,15 @@
GFX = Entity:extend()
local Entity = require "scenes.levels.entities.parent"
function GFX:new(level, spritename, animID,x,y)
local GFX = Entity:extend()
function GFX:new(level, x, y, spritename, animID)
local width, height
self.name = spritename
self.animID = animID
self.animation = assets.sprites[spritename]:cloneAnimation(animID)
width = 16--assets.sprites[spritename].width
height = 16--assets.sprites[spritename].height
GFX.super.new(self, level, x - (width/2), y - (height/2), width, height)
self.collType = "gfx"
GFX.super.new(self, level, "gfx", x - (width/2), y - (height/2), width, height)
self.duration = assets.sprites[spritename]:getAnimationDuration(animID)
self.timer = 0
--world:add(self, self.x, self.y, self.w, self.h)
@ -25,3 +26,5 @@ end
function GFX:draw(dt)
self.animation:draw(assets.sprites[self.name].image, self.x, self.y)
end
return GFX

View File

@ -1,154 +1,27 @@
Entity = Object:extend() -- On créer la classe des entitées, c'est la classe de base
local Obj = {}
-- On charge toutes les différentes types d'entitées
require "scenes.levels.entities.collision"
require "scenes.levels.entities.block"
require "scenes.levels.entities.bullet"
require "scenes.levels.entities.loot"
require "scenes.levels.entities.weapon"
require "scenes.levels.entities.gfx"
require "scenes.levels.entities.debris"
require "scenes.levels.entities.player"
Obj.Collision = require "scenes.levels.entities.collision"
Obj.Block = require "scenes.levels.entities.block"
Obj.Bullet = require "scenes.levels.entities.bullet"
Obj.Coin = require "scenes.levels.entities.loot.coin"
Obj.Coin5 = require "scenes.levels.entities.loot.coin5"
Obj.Coin10 = require "scenes.levels.entities.loot.coin10"
Obj.Weapon = require "scenes.levels.entities.weapon"
Obj.GFX = require "scenes.levels.entities.gfx"
Obj.Debris = require "scenes.levels.entities.debris"
Obj.Player = require "scenes.levels.entities.player"
function Entity:new(level, x, y, w, h) -- On enregistre une nouvelle entité, avec par défaut sa hitbox.
self:initPhysics(level, x, y, w, h)
self.destroyed = false
self.registered = false
self:setDebugColor(0,0,0)
end
Obj.index = {}
function Entity:initPhysics(level, x, y, w, h)
self.level = level
self.world = level.world
self.collType = ""
Obj.index["coin"] = Obj.Coin
Obj.index["coin5"] = Obj.Coin5
Obj.index["coin10"] = Obj.Coin10
Obj.index["block"] = Obj.Block
self.gacc = 500
self.xsp = 0
self.ysp = 0
Obj.collisions = {}
Obj.collisions["wall"] = true
Obj.collisions["water"] = true
Obj.collisions["platform"] = true
self.bounce = 0
self.grav = 0
self.frc = 0
self.x = x or 0
self.y = y or 0
self.w = w or 16
self.h = h or 16
self.onGround = false
self.playerID = -1
self:register()
end
function Entity:setDebugColor(r,g,b)
self.debug = {}
self.debug.r = r
self.debug.g = r
self.debug.b = r
end
function Entity:update(dt)
end
function Entity:register() -- On enregistre la hitbox dans le monde, pour l'instant les deux parties du programmes sont séparé (génération et enregistrement, peut-être qu'elles seront fusionnées)
self.world:add(self, self.x, self.y, self.w, self.h)
end
function Entity:destroy()
self.world:remove(self)
end
function Entity:canBounce(bounce)
self.bounce = bounce
end
function Entity:setMotion(xsp, ysp)
self.xsp, self.ysp = xsp, ysp
end
function Entity:setMotionDirection(dir,spd)
local dir = math.rad(dir) -- On commence par convertir la vitesse en radians
local xsp, ysp, cos, sin
cos = math.cos(dir)
sin = math.sin(dir)
xsp = (spd * cos)
ysp = (spd * sin)
self.xsp, self.ysp = xsp, ysp
end
function Entity:gravity(dt)
self.ysp = self.ysp + self.gacc * self.grav * dt
end
function Entity:friction(dt)
if (math.abs(self.xsp) <= self.frc) then
self.xsp = 0
else
self.xsp = self.xsp - (self.frc * utils.math.sign(self.xsp))
end
end
function Entity:changeSpeedToCollisionNormal(nx, ny)
local xsp, ysp = self.xsp, self.ysp
if (nx < 0 and xsp > 0) or (nx > 0 and xsp < 0) then
xsp = -xsp * self.bounce
end
if (ny < 0 and ysp > 0) or (ny > 0 and ysp < 0) then
ysp = -ysp * self.bounce
end
self.xsp, self.ysp = xsp, ysp
end
function Entity:getCenter()
return self.x + self.w / 2,
self.y + self.h / 2
end
function Entity:purge()
self.world:remove(self)
end
function Entity:setFilter()
self.filter = function(item, other)
return nil
end
end
function Entity:checkGround(ny)
if not (self.grav == 0) then
if ny < 0 then self.onGround = true end
end
end
function Entity:move(dt)
self.onGround = false
local xsp, ysp = self.xsp * dt, self.ysp * dt
self.x, self.y, cols, cols_len = self.world:move(self, self.x + xsp, self.y + ysp, self.filter)
for i=1, cols_len do
local col = cols[i]
if (col.type == "touch") or (col.type == "bounce") or (col.type == "slide") then
self:changeSpeedToCollisionNormal(col.normal.x, col.normal.y)
self:checkGround(col.normal.y)
end
end
return cols, cols_len
end
function Entity:getDirection()
if not (utils.math.sign(self.xsp) == 0) then
self.direction = utils.math.sign(self.xsp)
end
end
function Entity:draw()
-- Cette fonction en contient rien par défaut
end
return Obj

View File

@ -1,26 +0,0 @@
Loot = Entity:extend()
Coin = Loot:extend()
WeaponLoot = Loot:extend()
function Loot:new(level, name, value, x, y)
Loot.super.new(self, level, x, y, 16, 16)
self.value = value
self.collType = "loot"
self.name = name
end
function Loot:takeLoot()
GFX(self.level, "sparkle", 1, self.x+8, self.y+8)
self:destroy()
self.level.gold = self.level.gold + 1
assets:playSFX("collectcoin")
end
function Loot:update(dt)
Loot.super.update(self, dt)
end
function Loot:draw()
--local localx, localy = currentLevel.camera:cameraCoords(self.x, self.y)
assets.sprites[self.name]:draw(2, self.x, self.y)
end

View File

@ -0,0 +1,18 @@
local Loot = require "scenes.levels.entities.loot.parent"
local Coin = Loot:extend()
function Coin:new(level, x, y, anim, value)
self.value = value or 1
self.anim = anim or 1
Coin.super.new(self, level, x, y, "coin", self.anim)
end
function Coin:takeLoot()
self.obj.GFX(self.level, self.x+8, self.y+8, "sparkle", 1)
self:destroy()
self.level.gold = self.level.playermanager.gold + self.value
assets:playSFX("collectcoin")
end
return Coin

View File

@ -0,0 +1,9 @@
local Coin = require "scenes.levels.entities.loot.coin"
local Coin5 = Coin:extend()
function Coin5:new(level, x, y)
Coin5.super.new(self, level, x, y, 3, 10)
end
return Coin5

View File

@ -0,0 +1,9 @@
local Coin = require "scenes.levels.entities.loot.coin"
local Coin5 = Coin:extend()
function Coin5:new(level, x, y)
Coin5.super.new(self, level, x, y, 2, 5)
end
return Coin5

View File

@ -0,0 +1,28 @@
local Entity = require "scenes.levels.entities.parent"
local Loot = Entity:extend()
function Loot:new(level, x, y, name, anim)
Loot.super.new(self, level, "loot", x, y, 16, 16)
self.collType = "loot"
self.sprite = name
self.anim = anim
end
function Loot:takeLoot()
self.obj.GFX(self.level, self.x+8, self.y+8, "sparkle", 1)
self:destroy()
self.level.gold = self.level.playermanager.gold + 1
assets:playSFX("collectcoin")
end
function Loot:update(dt)
Loot.super.update(self, dt)
end
function Loot:draw()
--local localx, localy = currentLevel.camera:cameraCoords(self.x, self.y)
assets.sprites[self.sprite]:draw(self.anim, self.x, self.y)
end
return Loot

View File

@ -0,0 +1,152 @@
local Entity = Object:extend() -- On créer la classe des entitées, c'est la classe de base
function Entity:new(level, collType, x, y, w, h) -- On enregistre une nouvelle entité, avec par défaut sa hitbox.
self:initPhysics(level, collType, x, y, w, h)
self.destroyed = false
self.registered = false
self:setDebugColor(0,0,0)
end
function Entity:initPhysics(level, collType, x, y, w, h)
self.level = level
self.world = level.world
self.camera = level.camera
self.obj = self.world.obj
self.collType = collType
self.gacc = 500
self.xsp = 0
self.ysp = 0
self.bounce = 0
self.grav = 0
self.frc = 0
self.x = x or 0
self.y = y or 0
self.w = w or 16
self.h = h or 16
self.onGround = false
self.playerID = -1
self:register()
end
function Entity:setDebugColor(r,g,b)
self.debug = {}
self.debug.r = r
self.debug.g = r
self.debug.b = r
end
function Entity:update(dt)
end
function Entity:register() -- On enregistre la hitbox dans le monde, pour l'instant les deux parties du programmes sont séparé (génération et enregistrement, peut-être qu'elles seront fusionnées)
self.world:addEntity(self, self.x, self.y, self.w, self.h)
end
function Entity:destroy()
self.world:removeEntity(self)
end
function Entity:canBounce(bounce)
self.bounce = bounce
end
function Entity:setMotion(xsp, ysp)
self.xsp, self.ysp = xsp, ysp
end
function Entity:setMotionDirection(dir,spd)
local dir = math.rad(dir) -- On commence par convertir la vitesse en radians
local xsp, ysp, cos, sin
cos = math.cos(dir)
sin = math.sin(dir)
xsp = (spd * cos)
ysp = (spd * sin)
self.xsp, self.ysp = xsp, ysp
end
function Entity:gravity(dt)
self.ysp = self.ysp + self.gacc * self.grav * dt
end
function Entity:friction(dt)
if (math.abs(self.xsp) <= self.frc) then
self.xsp = 0
else
self.xsp = self.xsp - (self.frc * utils.math.sign(self.xsp))
end
end
function Entity:changeSpeedToCollisionNormal(nx, ny)
local xsp, ysp = self.xsp, self.ysp
if (nx < 0 and xsp > 0) or (nx > 0 and xsp < 0) then
xsp = -xsp * self.bounce
end
if (ny < 0 and ysp > 0) or (ny > 0 and ysp < 0) then
ysp = -ysp * self.bounce
end
self.xsp, self.ysp = xsp, ysp
end
function Entity:getCenter()
return self.x + self.w / 2,
self.y + self.h / 2
end
function Entity:purge()
self.world:removeEntity(self)
end
function Entity:setFilter()
self.filter = function(item, other)
return nil
end
end
function Entity:checkGround(ny)
if not (self.grav == 0) then
if ny < 0 then self.onGround = true end
end
end
function Entity:move(dt)
self.onGround = false
local xsp, ysp = self.xsp * dt, self.ysp * dt
self.x, self.y, cols, cols_len = self.world:moveEntity(self, self.x + xsp, self.y + ysp, self.filter)
for i=1, cols_len do
local col = cols[i]
if (col.type == "touch") or (col.type == "bounce") or (col.type == "slide") then
self:changeSpeedToCollisionNormal(col.normal.x, col.normal.y)
self:checkGround(col.normal.y)
end
end
return cols, cols_len
end
function Entity:getDirection()
if not (utils.math.sign(self.xsp) == 0) then
self.direction = utils.math.sign(self.xsp)
end
end
function Entity:isInsideView()
return self.camera:isInsideView(self.x, self.y, self.w, self.h)
end
function Entity:draw()
-- Cette fonction en contient rien par défaut
end
return Entity

View File

@ -0,0 +1,272 @@
local Entity = require "scenes.levels.entities.parent"
local Player = Entity:extend()
-- Initialisation functions
function Player:new(level, x, y, playerID)
local w, h = 32, 24
self.direction = 1
self.startx, self.starty = x, y
self:initAnimations()
Player.super.new(self, level, "player", x - (w / 2), y - (h / 2), w, h)
self.manager = level.playermanager
self.center = {
x = self.x,
y = self.y,
}
self.stats = {}
self:getStats(playerID)
self:lifeInit()
self:initWeapon()
self.currentWeapon = 1
self:initMovement()
self:setDebugColor(0,255,0)
end
function Player:getStats(playerID)
self.pigID = self.manager.players[playerID].pigID
self.stats = game.pigmanager:getPig(1)
self.playerID = playerID
end
function Player:lifeInit()
self.hp = self.stats.maxHP
self.mp = self.stats.maxMP
end
function Player:initMovement()
self.maxxsp = 16*60
self.maxysp = self.maxxsp
self.topsp = 4.5*60
self.acc = 0.046875*60*1.5
self.dec = 0.5*60
self.frc = self.acc
self.grav = 1
self.jmp = - 6*60
self.isJumping = false
end
function Player:initWeapon()
self.weaponID = 1
self:setWeapon()
end
function Player:initAnimations()
self.animations = {}
self.animations["idle"] = 1
self.animations["walk"] = 2
self.animations["brake"] = 3
self.animations["jump"] = 4
self.animations["fall"] = 5
end
-- UPDATE and COLLISION functions
function Player:update(dt)
self.keys = self.level.keys
self:actionMove(dt)
self:shoot(dt)
self:gravity(dt)
self:limitMovement()
self:setFilter()
local cols, cols_len = self:move(dt)
self:resolveCollisions(cols, cols_len)
self.center.x, self.center.y = self:getCenter()
self:getDirection()
local _, height = self.world:getDimensions()
if self.y >= (height + 64) then
self:die()
end
end
function Player:setFilter()
self.filter = function(item, other)
if (other.collType == "wall") then return 'slide'
elseif (other.collType == "block") then return 'slide'
elseif (other.collType == "platform") and
(self.ysp > 0) and
((self.y+24) <= other.y) then return 'slide'
elseif (other.collType == "loot") then return 'cross'
else return nil
end
end
end
function Player:resolveCollisions(cols, cols_len)
local cols, cols_len = cols, cols_len
for j=1,cols_len do
local other = cols[j].other
if (other.collType == "loot") then
other:takeLoot()
end
end
end
function Player:limitMovement()
if (math.abs(self.xsp) >= self.maxxsp) then
self.xsp = self.maxxsp * math.sign(self.xsp)
end
if (math.abs(self.ysp) >= self.maxysp) then
self.ysp = self.maxysp * math.sign(self.ysp)
end
end
-- GAMEPLAY functions
function Player:shoot()
if self.keys["B"].isPressed then
self:launchWeapon()
end
if self.keys["C"].isPressed then
self:changeWeapon(self.weaponID+1)
end
end
function Player:actionMove(dt)
local dx, dy = 0, 0
if self.keys["right"].isDown and not (self.keys["left"].isDown) then
if (self.xsp < self.topsp) then
if (self.xsp < 0) then
self.xsp = self.xsp + self.dec
else
self.xsp = self.xsp + self.acc
end
end
elseif self.keys["left"].isDown and not (self.keys["right"].isDown) then
if (self.xsp > -self.topsp) then
if (self.xsp > 0) then
self.xsp = self.xsp - self.dec
else
self.xsp = self.xsp - self.acc
end
end
else
self:friction(dt)
end
if (self.grav == 0) then
if self.keys["down"].isPressed and (self.y < 1000) then
self.ysp = 160
elseif self.keys["up"].isPressed and (self.y > 0) then
self.ysp = -160
end
end
if (self.onGround == true) then
self.isJumping = false
end
multijump = true
if ((self.onGround == true) or multijump) and self.keys["A"].isPressed then
self.ysp = self.jmp
self.isJumping = true
assets:playSFX("jump")
assets.sprites["cochon"]:resetAnimation(self.animations["jump"])
end
if (self.isJumping == true) and (self.ysp < (-4 * 60)) and (not (self.keys["A"].isDown)) then
self.ysp = -4 * 60
end
return dx, dy
end
function Player:launchWeapon()
self.obj.Weapon(self.level, self.center.x, self.center.y, self.weapon, 350 * utils.math.sign(self.direction))
end
function Player:changeWeapon(id)
local maxWeapon = #self.stats.weaponList
self.weaponID = utils.math.wrap(id, 1, maxWeapon)
self:setWeapon()
end
function Player:setWeapon()
self.weapon = self.stats.weaponList[self.weaponID]
end
-- DRAW functions
function Player:getAnimation()
local animation = 1
if (self.onGround) then
if (self.xsp == 0) then
animation = "idle"
else
if (self.keys["left"].isDown and (self.xsp > 0)) or
(self.keys["right"].isDown and (self.xsp < 0)) then
animation = "brake"
else
animation = "walk"
end
end
else
if (self.ysp < 0) and (self.isJumping) then
animation = "jump"
else
animation = "fall"
end
end
if (self.animations[animation] == nil) then
animation = "idle"
end
return self.animations[animation]
end
function Player:draw(dt)
local drawx, drawy = utils.math.floorCoord(self.center.x, self.center.y)
local animation = self:getAnimation()
--if (self.direction == -1) then drawx = drawx + self.w end
assets.sprites[self.stats.race]:draw(animation, drawx, drawy, 0, self.direction, 1, 16, 36)
end
-- Death and hit functions
function Player:takeHit(damage)
if (self.hp <= damage) then
self:die()
else
self.hp = self.hp - damage
end
end
function Player:die()
--self.hp = self.stats.maxHP
--self.x = self.startx-16
--self.y = self.starty-12
--self.xsp = 0
--self.ysp = 0
--currentLevel.world:update(self, self.x,self.y)
self.manager:setDeathTimer(1)
self:destroy()
end
return Player

View File

@ -1,59 +0,0 @@
function Player:shoot()
if self.gamepad.buttons["B"].press then
self:launchWeapon()
end
if self.gamepad.buttons["C"].press then
self:changeWeapon(self.weaponID+1)
end
end
function Player:actionMove(dt)
local dx, dy = 0, 0
if self.gamepad.buttons["right"].down and not (self.gamepad.buttons["left"].down) then
if (self.xsp < self.topsp) then
if (self.xsp < 0) then
self.xsp = self.xsp + self.dec
else
self.xsp = self.xsp + self.acc
end
end
elseif self.gamepad.buttons["left"].down and not (self.gamepad.buttons["right"].down) then
if (self.xsp > -self.topsp) then
if (self.xsp > 0) then
self.xsp = self.xsp - self.dec
else
self.xsp = self.xsp - self.acc
end
end
else
self:friction(dt)
end
if (self.grav == 0) then
if self.gamepad.buttons["down"].down and (self.y < 1000) then
self.ysp = 160
elseif self.gamepad.buttons["up"].down and (self.y > 0) then
self.ysp = -160
end
end
if (self.onGround == true) then
self.isJumping = false
end
multijump = true
if ((self.onGround == true) or multijump) and self.gamepad.buttons["A"].press then
self.ysp = self.jmp
self.isJumping = true
assets:playSFX("jump")
assets.sprites["cochon"]:resetAnimation(self.animations["jump"])
end
if (self.isJumping == true) and (self.ysp < (-4 * 60)) and (not (self.gamepad.buttons["A"].down)) then
self.ysp = -4 * 60
end
return dx, dy
end

View File

@ -1,22 +0,0 @@
function Player:resolveCollisions(cols, cols_len)
local cols, cols_len = cols, cols_len
for j=1,cols_len do
local other = cols[j].other
if (other.collType == "loot") then
other:takeLoot()
end
end
end
function Player:setFilter()
self.filter = function(item, other)
if (other.collType == "wall") then return 'slide'
elseif (other.collType == "block") then return 'slide'
elseif (other.collType == "platform") and
(self.ysp > 0) and
((self.y+24) <= other.y) then return 'slide'
elseif (other.collType == "loot") then return 'cross'
else return nil
end
end
end

View File

@ -1,44 +0,0 @@
function Player:initAnimations()
self.animations = {}
self.animations["idle"] = 1
self.animations["walk"] = 2
self.animations["brake"] = 3
self.animations["jump"] = 4
self.animations["fall"] = 5
end
function Player:getAnimation()
local animation = 1
if (self.onGround) then
if (self.xsp == 0) then
animation = "idle"
else
if (self.gamepad.buttons["left"].down and (self.xsp > 0)) or
(self.gamepad.buttons["right"].down and (self.xsp < 0)) then
animation = "brake"
else
animation = "walk"
end
end
else
if (self.ysp < 0) and (self.isJumping) then
animation = "jump"
else
animation = "fall"
end
end
if (self.animations[animation] == nil) then
animation = "idle"
end
return self.animations[animation]
end
function Player:draw(dt)
local drawx, drawy = utils.math.floorCoord(self.center.x, self.center.y)
local animation = self:getAnimation()
--if (self.direction == -1) then drawx = drawx + self.w end
assets.sprites[self.stats.race]:draw(animation, drawx, drawy, 0, self.direction, 1, 16, 36)
end

View File

@ -1,47 +0,0 @@
Player = Entity:extend()
require "scenes.levels.entities.player.draw"
require "scenes.levels.entities.player.actions"
require "scenes.levels.entities.player.collisions"
require "scenes.levels.entities.player.update"
require "scenes.levels.entities.player.pad"
require "scenes.levels.entities.player.movement"
require "scenes.levels.entities.player.life"
require "scenes.levels.entities.player.weapon"
function Player:new(level, playerID, x, y)
local w, h = 32, 24
self.direction = 1
self.startx, self.starty = x, y
self:initAnimations()
Player.super.new(self, level, x - (w / 2), y - (h / 2), w, h)
self.center = {
x = self.x,
y = self.y,
}
self.stats = {}
self:getStats(playerID)
self:lifeInit()
self:initWeapon()
self.currentWeapon = 1
self:initMovement()
self:padInit()
self:setDebugColor(0,255,0)
self.collType = "player"
end
function Player:getStats(playerID)
self.pigID = self.level.players[playerID].pigID
self.stats = game.pigmanager:getPig(1)
self.playerID = playerID
end

View File

@ -1,23 +0,0 @@
function Player:lifeInit()
self.hp = self.stats.maxHP
self.mp = self.stats.maxMP
end
function Player:takeHit(damage)
if (self.hp <= damage) then
self:die()
else
self.hp = self.hp - damage
end
end
function Player:die()
--self.hp = self.stats.maxHP
--self.x = self.startx-16
--self.y = self.starty-12
--self.xsp = 0
--self.ysp = 0
--currentLevel.world:update(self, self.x,self.y)
self.level:setDeathTimer(1)
self:destroy()
end

View File

@ -1,22 +0,0 @@
function Player:initMovement()
self.maxxsp = 16*60
self.maxysp = self.maxxsp
self.topsp = 4.5*60
self.acc = 0.046875*60*1.5
self.dec = 0.5*60
self.frc = self.acc
self.grav = 1
self.jmp = - 6*60
self.isJumping = false
end
function Player:limitMovement()
if (math.abs(self.xsp) >= self.maxxsp) then
self.xsp = self.maxxsp * math.sign(self.xsp)
end
if (math.abs(self.ysp) >= self.maxysp) then
self.ysp = self.maxysp * math.sign(self.ysp)
end
end

View File

@ -1,74 +0,0 @@
function Player:padInit()
self:padReset()
self:padAddTouch("up")
self:padAddTouch("left")
self:padAddTouch("right")
self:padAddTouch("down")
self:padAddTouch("A")
self:padAddTouch("B")
self:padAddTouch("C")
self:padAddAnalogue()
self:padAddTouch("select")
end
function Player:padReset()
self.gamepad = {}
self.gamepad.buttons = {}
self.gamepad.analogs = {}
end
function Player:padAddTouch(touchname)
self.gamepad.buttons[touchname] = {}
self.gamepad.buttons[touchname].down = false
self.gamepad.buttons[touchname].rel = false
self.gamepad.buttons[touchname].press = false
end
function Player:padAddAnalogue()
local id = #self.gamepad.analogs + 1
self.gamepad.analogs[id] = {}
self.gamepad.analogs[id].angle = 0
self.gamepad.analogs[id].strenght = 0
end
function Player:padPush(touchname, value)
if (value == true) then
-- Si le bouton est enfoncé, alors on ne peut pas l'avoir relaché
self.gamepad.buttons[touchname].rel = false
if (self.gamepad.buttons[touchname].down == true) then
-- Si le bouton était déjà pressé au début, alors on indique
-- qu'il ne vient pas d'être pressé.
self.gamepad.buttons[touchname].down = true
self.gamepad.buttons[touchname].press = false
else
-- Sinon, on indique qu'il viens d'être pressé, et
-- qu'il est enfoncé
self.gamepad.buttons[touchname].down = true
self.gamepad.buttons[touchname].press = true
end
else
-- Si le bouton est relaché, alors on ne peut pas l'avoir pressé
self.gamepad.buttons[touchname].press = false
if (self.gamepad.buttons[touchname].down == true) then
-- Si le bouton était déjà pressé au début, alors on indique
-- qu'il vient d'être relaché, et qu'il n'est plus enfoncé
self.gamepad.buttons[touchname].down = false
self.gamepad.buttons[touchname].rel = true
else
-- Sinon, on indique qu'il ne viens plus d'être relaché, et
-- qu'il n'est pas enfoncé, au cas ou.
self.gamepad.buttons[touchname].down = false
self.gamepad.buttons[touchname].rel = false
end
end
end

View File

@ -1,20 +0,0 @@
function Player:update(dt)
self:actionMove(dt)
self:shoot(dt)
self:gravity(dt)
self:limitMovement()
self:setFilter()
local cols, cols_len = self:move(dt)
self:resolveCollisions(cols, cols_len)
self.center.x, self.center.y = self:getCenter()
self:getDirection()
if self.y >= ((self.level.map.height * self.level.map.tileheight) + 64) then
self:die()
end
end

View File

@ -1,18 +0,0 @@
function Player:initWeapon()
self.weaponID = 1
self:setWeapon()
end
function Player:launchWeapon()
Weapon(self.level, self.weapon, self.center.x, self.center.y, 350 * utils.math.sign(self.direction))
end
function Player:changeWeapon(id)
local maxWeapon = #self.stats.weaponList
self.weaponID = wrap(id, maxWeapon)
self:setWeapon()
end
function Player:setWeapon()
self.weapon = self.stats.weaponList[self.weaponID]
end

View File

@ -1,11 +1,12 @@
Weapon = Entity:extend()
local Entity = require "scenes.levels.entities.parent"
function Weapon:new(level, id, x, y, xsp)
Weapon.super.new(self, level, x-8, y - 8, 16, 16)
self.weaponid = id
self.collType="weapon"
self.xsp = xsp
self.ysp = 0
local Weapon = Entity:extend()
function Weapon:new(level, x, y, id, xsp, ysp)
Weapon.super.new(self, level, "weapon", x-8, y - 8, 16, 16)
self.weaponid = id or 0
self.xsp = xsp or 0
self.ysp = ysp or 0
self.rotation = 0
end
@ -42,8 +43,8 @@ function Weapon:update(dt)
self.life = 1
local localx, localy = self.level:cameraCoords(self.x, self.y)
if (localx < 0) or (localx > 480) or (localy < 0) or (localy > (272)) then
local isInsideView = self:isInsideView()
if (isInsideView == false) then
self:destroy()
end
@ -56,3 +57,5 @@ function Weapon:draw(dt)
assets.sprites["weapon"]:draw(self.weaponid, drawx, drawy, rotation,
self.direction, 1, 8, 8)
end
return Weapon

View File

@ -2,16 +2,12 @@
require "scenes.levels.sounds"
require "scenes.levels.sprites"
require "scenes.levels.controller"
require "scenes.levels.entities"
local Level = require "scenes.levels.controller"
-- On charge le module de scene et créer l'objet de scene des niveaux
local Scene = require "core.modules.scenes"
local LevelScene = Scene:extend()
local currentLevel = Level()
local previousMenu
-- On initialise les variables
--local map -- la carte
@ -22,27 +18,20 @@ local previousMenu
-- Cela permet de réduire la présence de la variable d'état à se fichier, et de communiquer
-- uniquement avec cette fonction
function levelLoad(levelID, missionID)
level_loadSounds()
loadSprites()
currentLevel:loadMission(levelID, missionID)
Gamestate.switch(stateLevel)
end
function LevelScene:new(levelID, missionID)
self.controller = Level()
LevelScene.super.new(self)
level_loadSounds()
loadSprites()
previousMenu = previous
currentLevel:loadMission(levelID, missionID)
self.controller:loadMission(levelID, missionID)
self:register()
end
function LevelScene:update(dt)
lovebird.update()
currentLevel:update(dt)
self.controller:update(dt)
end
function LevelScene:keypressed(key)
@ -59,20 +48,11 @@ function LevelScene:keypressed(key)
end
function LevelScene:draw(dt)
currentLevel:draw(dt)
self.controller:draw(dt)
end
function LevelScene:exit()
currentLevel:reset()
end
function love.resize(w, h)
currentLevel.map:resize(w, h)
end
function exitLevel()
currentLevel:reset()
Gamestate.switch(stateDebugMenu)
self.controller:reset()
end
return LevelScene