Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 1 of 1
  1. #1
    New to the CF scene
    Join Date
    Jun 2013
    Location
    Somewhere
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Exclamation Help with Lua game...

    Hi there!
    I recently made a prototype for my game and I'm still trying to work out the kinks on the movement. But that's besides the point.
    In order to continue I want to have 2 players on the screen that can be controlled using wasd and ijkl. I do know how to change the controls by goint to the love.update function. Here's my code for the main.lua:
    Code:
    require "player/Player"
    require "player/SpriteAnimation"
    require "camera"
    
    function love.load()
        width = love.graphics.getWidth()
        height = love.graphics.getHeight()
        love.graphics.setBackgroundColor(45, 45, 45)
        
        -- Load up the map
        loader = require("AdvTiledLoader.Loader")
        loader.path = "maps/"
        map = loader.load("map01.tmx")
        map:setDrawRange(0, 0, map.width * map.tileWidth, map.height * map.tileHeight)
        
        -- restrict the camera
        camera:setBounds(0, 0, map.width * map.tileWidth - width, map.height * map.tileHeight - height)
        
        p = Player:new()
        
        p.x = 300
        p.y = 300
        p.width = 32
        p.height = 32
        p.jumpSpeed = -800
        p.runSpeed = 500
        
        gravity = 1800
        hasJumped = false
        delay = 120
        
        -- Load player animation
        animation = SpriteAnimation:new("player/robosprites.png", 32, 32, 4, 4)
        animation:load(delay)
    end
    
    function love.update(dt)
        -- check controls
        if love.keyboard.isDown("right") then
            p:moveRight()
            animation:flip(false, false)
        end
        if love.keyboard.isDown("left") then
            p:moveLeft()
            animation:flip(true, false)
        end
        if love.keyboard.isDown("x") and not(hasJumped) then
            hasJumped = true
            p:jump()
        end
     
        -- update the player's position and check for collisions
        p:update(dt, gravity, map)
        
        -- update the sprite animation
        if (p.state == "stand") then
            animation:switch(1, 4, 200)
        end
        if (p.state == "moveRight") or (p.state == "moveLeft") then
            animation:switch(2, 4, 120)
        end
        if (p.state == "jump") or (p.state == "fall") then
            animation:reset()
            animation:switch(3, 1, 300)
        end
        
        animation:update(dt)
        
        -- center the camera on the player
        camera:setPosition(math.floor(p.x - width / 2), math.floor(p.y - height / 2))
    end
    
    function love.draw()
        camera:set()
        
        -- round our x, y values
        local x, y = math.floor(p.x), math.floor(p.y)
        
        -- draw the map
        map:draw()
        
        -- draw the player
        animation:draw(x - p.width / 2, y - p.height / 2)
        
        camera:unset()
        
        -- debug information
        local tileX = math.floor(p.x / map.tileWidth)
        local tileY = math.floor(p.y / map.tileHeight)
        
        love.graphics.setColor(255, 255, 255)
        love.graphics.print("Player coordinates: ("..x..","..y..")", 5, 5)
        love.graphics.print("Current state: "..p.state, 5, 20)
        love.graphics.print("Current tile: ("..tileX..", "..tileY..")", 5, 35)
    end
    
    function love.keyreleased(key)
        if key == "escape" then
            love.event.push("quit")   -- actually causes the app to quit
        end
        if (key == "right") or (key == "left") then
            p:stop()
        end
        if (key == "x") then
            hasJumped = false
        end
    end
    
    function math.clamp(x, min, max)
      return x < min and min or (x > max and max or x)
    end
    And here's the player.lua:

    Code:
    Player = {}
    
    -- Constructor
    function Player:new()
        -- define our parameters here
        local object = {
        x = 0,
        y = 0,
        width = 0,
        height = 0,
        xSpeed = 0,
        ySpeed = 0,
        xSpeedMax = 800,
        ySpeedMax = 800,
        state = "",
        jumpSpeed = 0,
        runSpeed = 0,
        onFloor = false
        }
        setmetatable(object, { __index = Player })
        return object
    end
    
    -- Movement functions
    function Player:jump()
        if self.onFloor then
            self.ySpeed = self.jumpSpeed
            self.onFloor = false
        end
    end
    
    function Player:moveRight()
        self.xSpeed = self.runSpeed
    end
    
    function Player:moveLeft()
        self.xSpeed = -1 * (self.runSpeed)
    end
    
    function Player:stop()
        self.xSpeed = 0
    end
    
    -- Do various things when the player hits a tile
    function Player:collide(event)
        if event == "floor" then
            self.ySpeed = 0
            self.onFloor = true
        end
        if event == "ceiling" then
            self.ySpeed = 0
        end
    end
    
    -- Update function
    function Player:update(dt, gravity, map)
        local halfX = self.width / 2
        local halfY = self.height / 2
        
        -- apply gravity
        self.ySpeed = self.ySpeed + (gravity * dt)
        
        -- limit the player's speed
        self.xSpeed = math.clamp(self.xSpeed, -self.xSpeedMax, self.xSpeedMax)
        self.ySpeed = math.clamp(self.ySpeed, -self.ySpeedMax, self.ySpeedMax)
        
        -- calculate vertical position and adjust if needed
        local nextY = math.floor(self.y + (self.ySpeed * dt))
        if self.ySpeed < 0 then -- check upward
            if not(self:isColliding(map, self.x - halfX, nextY - halfY))
                and not(self:isColliding(map, self.x + halfX - 1, nextY - halfY)) then
                -- no collision, move normally
                self.y = nextY
                self.onFloor = false
            else
                -- collision, move to nearest tile border
                self.y = nextY + map.tileHeight - ((nextY - halfY) % map.tileHeight)
                self:collide("ceiling")
            end
        elseif self.ySpeed > 0 then -- check downward
            if not(self:isColliding(map, self.x - halfX, nextY + halfY))
                and not(self:isColliding(map, self.x + halfX - 1, nextY + halfY)) then
                -- no collision, move normally
                self.y = nextY
                self.onFloor = false
            else
                -- collision, move to nearest tile border
                self.y = nextY - ((nextY + halfY) % map.tileHeight)
                self:collide("floor")
            end
        end
    
        -- calculate horizontal position and adjust if needed
        local nextX = math.floor(self.x + (self.xSpeed * dt))
        if self.xSpeed > 0 then -- check right
            if not(self:isColliding(map, nextX + halfX, self.y - halfY))
                and not(self:isColliding(map, nextX + halfX, self.y + halfY - 1)) then
                -- no collision
                self.x = nextX
            else
                -- collision, move to nearest tile
                self.x = nextX - ((nextX + halfX) % map.tileWidth)
            end
        elseif self.xSpeed < 0 then -- check left
            if not(self:isColliding(map, nextX - halfX, self.y - halfY))
                and not(self:isColliding(map, nextX - halfX, self.y + halfY - 1)) then
                -- no collision
                self.x = nextX
            else
                -- collision, move to nearest tile
                self.x = nextX + map.tileWidth - ((nextX - halfX) % map.tileWidth)
            end
        end
        
        -- update the player's state
        self.state = self:getState()
    end
    
    -- returns true if the coordinates given intersect a map tile
    function Player:isColliding(map, x, y)
        -- get tile coordinates
        local layer = map.tl["Walls"]
        local tileX, tileY = math.floor(x / map.tileWidth), math.floor(y / map.tileHeight)
        
        -- grab the tile at given point
        local tile = layer.tileData(tileX, tileY)
        
        -- return true if the point overlaps a solid tile
        return not(tile == nil)
    end
    
    -- returns player's state as a string
    function Player:getState()
        local myState = ""
        if self.onFloor then
            if self.xSpeed > 0 then
                myState = "moveRight"
            elseif self.xSpeed < 0 then
                myState = "moveLeft"
            else
                myState = "stand"
            end
        end
        if self.ySpeed < 0 then
            myState = "jump"
        elseif self.ySpeed > 0 then
            myState = "fall"
        end
        return myState
    end
    And yes I'm using the AdvTileLoader.lua for my game but I don't think that will have much to do with it.

    My theory is that I make another section in main.lua with the same code but based around a new player.lua and creat a clone of the current player.lua and name it player2.lua so that it will have the same everything.
    But otherwise I have no clue what to do.
    Hope you guys can help!

    -Sam
    Last edited by vinyl-junkie; 06-27-2013 at 02:28 PM. Reason: signatures only allowed through the control panel


 

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •