created better map and tweaked player movement
This commit is contained in:
parent
a709e4f1c4
commit
6ae7e3b1a4
@ -3,6 +3,7 @@ function love.conf(t)
|
|||||||
|
|
||||||
t.console = true
|
t.console = true
|
||||||
|
|
||||||
t.window.width = 854
|
t.window.resizable = true
|
||||||
t.window.height = 480
|
t.window.width = 640 * 2
|
||||||
|
t.window.height = 360 * 2
|
||||||
end
|
end
|
||||||
|
138
src/lib/center.lua
Normal file
138
src/lib/center.lua
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
--[[
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Semyon Entsov <swalrus@yandex.ru>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
]]--
|
||||||
|
|
||||||
|
local center = {}
|
||||||
|
|
||||||
|
function center:setupScreen(width, height)
|
||||||
|
self._WIDTH = width
|
||||||
|
self._HEIGHT = height
|
||||||
|
self._MAX_WIDTH = 0
|
||||||
|
self._MAX_HEIGHT = 0
|
||||||
|
self._MAX_RELATIVE_WIDTH = 0
|
||||||
|
self._MAX_RELATIVE_HEIGHT = 0
|
||||||
|
self._SCREEN_WIDTH = love.graphics.getWidth()
|
||||||
|
self._SCREEN_HEIGHT = love.graphics.getHeight()
|
||||||
|
self._BORDERS = {
|
||||||
|
['t'] = 0,
|
||||||
|
['r'] = 0,
|
||||||
|
['b'] = 0,
|
||||||
|
['l'] = 0
|
||||||
|
}
|
||||||
|
self:apply()
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:setBorders(top, right, bottom, left)
|
||||||
|
self._BORDERS.t = top
|
||||||
|
self._BORDERS.r = right
|
||||||
|
self._BORDERS.b = bottom
|
||||||
|
self._BORDERS.l = left
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:getScale()
|
||||||
|
return self._SCALE
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:getOffsetX()
|
||||||
|
return self._OFFSET_X
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:getOffsetY()
|
||||||
|
return self._OFFSET_Y
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:setMaxWidth(width)
|
||||||
|
self._MAX_WIDTH = width
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:setMaxHeight(height)
|
||||||
|
self._MAX_HEIGHT = height
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:setMaxRelativeWidth(width)
|
||||||
|
self._MAX_RELATIVE_WIDTH = width
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:setMaxRelativeHeight(height)
|
||||||
|
self._MAX_RELATIVE_HEIGHT = height
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:resize(width, height)
|
||||||
|
self._SCREEN_WIDTH = width
|
||||||
|
self._SCREEN_HEIGHT = height
|
||||||
|
self:apply()
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:apply()
|
||||||
|
local available_width = self._SCREEN_WIDTH - self._BORDERS.l - self._BORDERS.r
|
||||||
|
local available_height = self._SCREEN_HEIGHT - self._BORDERS.t - self._BORDERS.b
|
||||||
|
local max_width = available_width
|
||||||
|
local max_height = available_height
|
||||||
|
if self._MAX_RELATIVE_WIDTH > 0 and available_width * self._MAX_RELATIVE_WIDTH < max_width then
|
||||||
|
max_width = available_width * self._MAX_RELATIVE_WIDTH
|
||||||
|
end
|
||||||
|
if self._MAX_RELATIVE_HEIGHT > 0 and available_height * self._MAX_RELATIVE_HEIGHT < max_height then
|
||||||
|
max_height = available_height * self._MAX_RELATIVE_HEIGHT
|
||||||
|
end
|
||||||
|
if self._MAX_WIDTH > 0 and self._MAX_WIDTH < max_width then
|
||||||
|
max_width = self._MAX_WIDTH
|
||||||
|
end
|
||||||
|
if self._MAX_HEIGHT > 0 and self._MAX_HEIGHT < max_height then
|
||||||
|
max_height = self._MAX_HEIGHT
|
||||||
|
end
|
||||||
|
if max_height / max_width > self._HEIGHT / self._WIDTH then
|
||||||
|
self._CANVAS_WIDTH = max_width
|
||||||
|
self._CANVAS_HEIGHT = self._CANVAS_WIDTH * (self._HEIGHT / self._WIDTH)
|
||||||
|
else
|
||||||
|
self._CANVAS_HEIGHT = max_height
|
||||||
|
self._CANVAS_WIDTH = self._CANVAS_HEIGHT * (self._WIDTH / self._HEIGHT)
|
||||||
|
end
|
||||||
|
self._SCALE = self._CANVAS_HEIGHT / self._HEIGHT
|
||||||
|
self._OFFSET_X = self._BORDERS.l + (available_width - self._CANVAS_WIDTH) / 2
|
||||||
|
self._OFFSET_Y = self._BORDERS.t + (available_height - self._CANVAS_HEIGHT) / 2
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:start()
|
||||||
|
love.graphics.push()
|
||||||
|
love.graphics.translate(self._OFFSET_X, self._OFFSET_Y)
|
||||||
|
love.graphics.scale(self._SCALE, self._SCALE)
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:finish()
|
||||||
|
love.graphics.pop()
|
||||||
|
end
|
||||||
|
|
||||||
|
function center:toGame(x, y, w, h)
|
||||||
|
if not (self._OFFSET_X and self._OFFSET_Y and self._SCALE) then
|
||||||
|
return x, y, w, h
|
||||||
|
end
|
||||||
|
|
||||||
|
return (x - self._OFFSET_X) / self._SCALE,
|
||||||
|
(y - self._OFFSET_Y) / self._SCALE,
|
||||||
|
w and w / self._SCALE,
|
||||||
|
h and h / self._SCALE
|
||||||
|
end
|
||||||
|
|
||||||
|
return center
|
||||||
|
|
@ -1,7 +1,11 @@
|
|||||||
local Gamestate = require("lib.hump.gamestate")
|
local Gamestate = require("lib.hump.gamestate")
|
||||||
|
local ScreenScaler = require("screen-scaler")
|
||||||
pprint = require("lib.pprint")
|
pprint = require("lib.pprint")
|
||||||
|
|
||||||
PLAYER_SIZE = 20
|
PLAYER_SIZE = 10
|
||||||
|
|
||||||
|
-- 640 x 360
|
||||||
|
ScreenScaler.setVirtualDimensions(16 * 40, 9 * 40)
|
||||||
|
|
||||||
function love.load()
|
function love.load()
|
||||||
love.math.setRandomSeed(love.timer.getTime())
|
love.math.setRandomSeed(love.timer.getTime())
|
||||||
|
232
src/screen-scaler.lua
Normal file
232
src/screen-scaler.lua
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
--- Module resposible for scaling screen and centering contents
|
||||||
|
-- while respecting ratios.
|
||||||
|
-- @module ScreenScaler
|
||||||
|
local ScreenScaler = {}
|
||||||
|
|
||||||
|
-- This "Center" library will do most of the heavy lifting
|
||||||
|
-- TODO: Removed this depedency, embed needed functionality
|
||||||
|
local Center = require("lib.center")
|
||||||
|
|
||||||
|
local getRealDimensions = love.graphics.getDimensions
|
||||||
|
|
||||||
|
--- Set the "ideal" dimensions from which everything else will be scaled.
|
||||||
|
-- @tparam number w virtual width
|
||||||
|
-- @tparam number h virtual height
|
||||||
|
function ScreenScaler.setVirtualDimensions(w, h)
|
||||||
|
assert(type(w) == "number", "Expected width to be number")
|
||||||
|
assert(type(h) == "number", "Expected height to be number")
|
||||||
|
ScreenScaler.width, ScreenScaler.height = nil, nil
|
||||||
|
|
||||||
|
-- Setup library resposible for scaling the screen
|
||||||
|
Center:setupScreen(w, h)
|
||||||
|
|
||||||
|
ScreenScaler.width, ScreenScaler.height = w, h
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Unsets virtual dimensions. Effectively disables scaler.
|
||||||
|
function ScreenScaler.unsetVirtualDimensions()
|
||||||
|
ScreenScaler.width = nil
|
||||||
|
ScreenScaler.height = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get virtual dimensions.
|
||||||
|
-- @return width, height
|
||||||
|
function ScreenScaler.getVirtualDimensions()
|
||||||
|
return ScreenScaler.width, ScreenScaler.height
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns true if scaler is enabled.
|
||||||
|
-- @treturn boolean
|
||||||
|
function ScreenScaler.isEnabled()
|
||||||
|
return ScreenScaler.width ~= nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Overwrite default love.mouse functions to return position
|
||||||
|
-- relative to scaled window
|
||||||
|
do
|
||||||
|
local getX = love.mouse.getX
|
||||||
|
function love.mouse.getX()
|
||||||
|
local x = getX()
|
||||||
|
if not ScreenScaler.isEnabled() then
|
||||||
|
return x
|
||||||
|
end
|
||||||
|
return (x - Center:getOffsetX()) / Center:getScale()
|
||||||
|
end
|
||||||
|
|
||||||
|
local getY = love.mouse.getY
|
||||||
|
function love.mouse.getY()
|
||||||
|
local y = getY()
|
||||||
|
if not ScreenScaler.isEnabled() then
|
||||||
|
return y
|
||||||
|
end
|
||||||
|
return (y - Center:getOffsetY()) / Center:getScale()
|
||||||
|
end
|
||||||
|
|
||||||
|
local getPosition = love.mouse.getPosition
|
||||||
|
function love.mouse.getPosition()
|
||||||
|
if ScreenScaler.isEnabled() then
|
||||||
|
return Center:toGame(getPosition())
|
||||||
|
else
|
||||||
|
return getPosition()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO: add replacements for setX, setY, setPosition
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Overwrite default getDimensions, getWidth, getHeight
|
||||||
|
-- to return virtual width and height if scaler is enabled
|
||||||
|
do
|
||||||
|
local getWidth = love.graphics.getWidth
|
||||||
|
function love.graphics.getWidth()
|
||||||
|
return ScreenScaler.width or getWidth()
|
||||||
|
end
|
||||||
|
|
||||||
|
local getHeight = love.graphics.getHeight
|
||||||
|
function love.graphics.getHeight()
|
||||||
|
return ScreenScaler.height or getHeight()
|
||||||
|
end
|
||||||
|
|
||||||
|
function love.graphics.getDimensions()
|
||||||
|
return love.graphics.getWidth(), love.graphics.getHeight()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Adjust setScissor and intersectScissor function, so that they are relative
|
||||||
|
-- to the scaled screen. By default these functions are unaffected by transformations
|
||||||
|
do
|
||||||
|
local setScissor = love.graphics.setScissor
|
||||||
|
function love.graphics.setScissor(x, y, w, h)
|
||||||
|
if x and ScreenScaler.isEnabled() then
|
||||||
|
setScissor(Center:toGame(x, y, w, h))
|
||||||
|
else
|
||||||
|
setScissor(x, y, w, h)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local intersectScissor = love.graphics.intersectScissor
|
||||||
|
function love.graphics.intersectScissor(x, y, w, h)
|
||||||
|
if x and ScreenScaler.isEnabled() then
|
||||||
|
intersectScissor(Center:toGame(x, y, w, h))
|
||||||
|
else
|
||||||
|
intersectScissor(x, y, w, h)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function isInBounds(x, y)
|
||||||
|
if not ScreenScaler.isEnabled() then return true end
|
||||||
|
local w, h = ScreenScaler.getVirtualDimensions()
|
||||||
|
return x >= 0 and x < w and y >= 0 and y < h
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create event proccessors for converting normal screen coordinates
|
||||||
|
-- to scaled screen coordinates
|
||||||
|
-- If the user clicked out of bounds, it will not handled
|
||||||
|
local eventPreProccessor = {}
|
||||||
|
function eventPreProccessor.mousepressed(x, y, button, istouch, presses)
|
||||||
|
x, y = Center:toGame(x, y)
|
||||||
|
return isInBounds(x, y), x, y, button, istouch, presses
|
||||||
|
end
|
||||||
|
|
||||||
|
function eventPreProccessor.mousereleased(x, y, button, istouch, presses)
|
||||||
|
x, y = Center:toGame(x, y)
|
||||||
|
return isInBounds(x, y), x, y, button, istouch, presses
|
||||||
|
end
|
||||||
|
|
||||||
|
function eventPreProccessor.mousemoved(x, y, dx, dy, istouch)
|
||||||
|
local scale = Center:getScale()
|
||||||
|
x, y = Center:toGame(x, y)
|
||||||
|
dx, dy = dx / scale, dy / scale
|
||||||
|
return isInBounds(x, y), x, y, dx, dy, istouch, istouch
|
||||||
|
end
|
||||||
|
|
||||||
|
function eventPreProccessor.wheelmoved(x, y)
|
||||||
|
return isInBounds(love.mouse.getPosition()), x, y
|
||||||
|
end
|
||||||
|
|
||||||
|
local function hideOutOfBounds()
|
||||||
|
local r, g, b, a = love.graphics.getColor()
|
||||||
|
love.graphics.setColor(0, 0, 0, 1)
|
||||||
|
local w, h = getRealDimensions()
|
||||||
|
|
||||||
|
if Center._OFFSET_X ~= 0 then
|
||||||
|
love.graphics.rectangle("fill", 0, 0, Center._OFFSET_X, h)
|
||||||
|
love.graphics.rectangle("fill", Center._WIDTH*Center._SCALE+Center._OFFSET_X, 0, Center._OFFSET_X, h)
|
||||||
|
end
|
||||||
|
|
||||||
|
if Center._OFFSET_Y ~= 0 then
|
||||||
|
love.graphics.rectangle("fill", 0, 0, w, Center._OFFSET_Y)
|
||||||
|
love.graphics.rectangle("fill", 0, Center._HEIGHT*Center._SCALE+Center._OFFSET_Y, w, Center._OFFSET_Y)
|
||||||
|
end
|
||||||
|
|
||||||
|
love.graphics.setColor(r, g, b, a)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Modify core game loop so that if scaler is enabled:
|
||||||
|
-- * resize events are not handled
|
||||||
|
-- * out of bounds mouse events are not handled
|
||||||
|
-- * all drawing operations are centered
|
||||||
|
function love.run()
|
||||||
|
if love.load then love.load(love.arg.parseGameArguments(arg), arg) end
|
||||||
|
|
||||||
|
-- We don't want the first frame's dt to include time taken by love.load.
|
||||||
|
if love.timer then love.timer.step() end
|
||||||
|
|
||||||
|
local dt = 0
|
||||||
|
|
||||||
|
-- Main loop time.
|
||||||
|
return function()
|
||||||
|
-- Process events.
|
||||||
|
if love.event then
|
||||||
|
love.event.pump()
|
||||||
|
for name, a,b,c,d,e,f in love.event.poll() do
|
||||||
|
if name == "quit" then
|
||||||
|
if not love.quit or not love.quit() then
|
||||||
|
return a or 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ScreenScaler.isEnabled() then
|
||||||
|
if name == "resize" then
|
||||||
|
Center:resize(a, b)
|
||||||
|
goto continue
|
||||||
|
elseif eventPreProccessor[name] then
|
||||||
|
local success
|
||||||
|
success, a, b, c, d, e, f = eventPreProccessor[name](a, b, c, d, e, f)
|
||||||
|
if not success then goto continue end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
love.handlers[name](a, b, c, d, e, f)
|
||||||
|
::continue::
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Update dt, as we'll be passing it to update
|
||||||
|
if love.timer then dt = love.timer.step() end
|
||||||
|
|
||||||
|
-- Call update and draw
|
||||||
|
if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
|
||||||
|
|
||||||
|
if love.graphics and love.graphics.isActive() then
|
||||||
|
love.graphics.origin()
|
||||||
|
love.graphics.clear(love.graphics.getBackgroundColor())
|
||||||
|
|
||||||
|
if love.draw then
|
||||||
|
if ScreenScaler.isEnabled() then
|
||||||
|
Center:start()
|
||||||
|
love.draw()
|
||||||
|
Center:finish()
|
||||||
|
else
|
||||||
|
love.draw()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
love.graphics.present()
|
||||||
|
end
|
||||||
|
|
||||||
|
if love.timer then love.timer.sleep(0.001) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return ScreenScaler
|
@ -6,7 +6,7 @@ local rgb = require("helpers.rgb")
|
|||||||
local lerp = require("lib.lume").lerp
|
local lerp = require("lib.lume").lerp
|
||||||
local BoltMods = require("bolt-mods")
|
local BoltMods = require("bolt-mods")
|
||||||
|
|
||||||
local BOLT_DIST_FROM_PLAYER = 40
|
local BOLT_DIST_FROM_PLAYER = PLAYER_SIZE*2
|
||||||
local BOLT_SIZE = 4
|
local BOLT_SIZE = 4
|
||||||
|
|
||||||
local DRAW_COLLIDERS = false
|
local DRAW_COLLIDERS = false
|
||||||
@ -31,14 +31,24 @@ function MainState:enter()
|
|||||||
self.bolts = {}
|
self.bolts = {}
|
||||||
|
|
||||||
self.obstacles = {}
|
self.obstacles = {}
|
||||||
table.insert(self.obstacles, {{90, 90}, {100, 200}, {300, 300}, {200, 100}})
|
do
|
||||||
table.insert(self.obstacles, {{390, 90}, {500, 200}, {500, 300}})
|
table.insert(self.obstacles, {{77, 2}, {6, 60}, {5, 5}})
|
||||||
table.insert(self.obstacles, {{450, 390}, {500, 200}, {500, 300}})
|
table.insert(self.obstacles, {{576, 357}, {639, 314}, {639, 357}})
|
||||||
table.insert(self.obstacles, {{750, 390}, {500, 200}, {500, 300}})
|
table.insert(self.obstacles, {{275, 101}, {395, 101}, {392, 55}, {281, 60}})
|
||||||
table.insert(self.obstacles, {{750, 290}, {600, 200}, {600, 100}})
|
table.insert(self.obstacles, {{271, 280}, {392, 277}, {392, 322}, {252, 320}})
|
||||||
table.insert(self.obstacles, {{550, 400}, {670, 500}, {500, 500}})
|
table.insert(self.obstacles, {{222, 115}, {248, 145}, {221, 176}, {192, 151}})
|
||||||
table.insert(self.obstacles, {{700, 0}, {850, 200}, {850, 0}})
|
table.insert(self.obstacles, {{435, 112}, {401, 142}, {426, 174}, {457, 142}})
|
||||||
table.insert(self.obstacles, {{250, 350}, {200, 500}, {300, 500}})
|
table.insert(self.obstacles, {{194, 229}, {246, 260}, {192, 262}})
|
||||||
|
table.insert(self.obstacles, {{417, 260}, {466, 258}, {465, 226}})
|
||||||
|
table.insert(self.obstacles, {{141, 148}, {136, 249}, {94, 246}, {105, 149}})
|
||||||
|
table.insert(self.obstacles, {{216, 318}, {216, 359}, {134, 358}})
|
||||||
|
table.insert(self.obstacles, {{435, 0}, {434, 52}, {541, 5}})
|
||||||
|
table.insert(self.obstacles, {{507, 142}, {505, 247}, {554, 246}, {553, 138}})
|
||||||
|
table.insert(self.obstacles, {{124, 104}, {219, 34}, {230, 64}, {166, 111}})
|
||||||
|
table.insert(self.obstacles, {{429, 337}, {527, 282}, {504, 274}, {432, 312}})
|
||||||
|
table.insert(self.obstacles, {{63, 292}, {78, 314}, {40, 315}})
|
||||||
|
table.insert(self.obstacles, {{588, 92}, {565, 65}, {616, 66}})
|
||||||
|
end
|
||||||
|
|
||||||
self.obstacle_colliders = {}
|
self.obstacle_colliders = {}
|
||||||
for _, obstacle in ipairs(self.obstacles) do
|
for _, obstacle in ipairs(self.obstacles) do
|
||||||
@ -83,10 +93,9 @@ end
|
|||||||
function MainState:start_match()
|
function MainState:start_match()
|
||||||
self:stop_match()
|
self:stop_match()
|
||||||
|
|
||||||
local winw, winh = love.graphics.getDimensions()
|
self:create_player("keyboard", Vec(60, 80))
|
||||||
self:create_player("keyboard", Vec(50, 200))
|
|
||||||
-- self:create_player("joystick", Vec(winw-50, 200))
|
-- self:create_player("joystick", Vec(winw-50, 200))
|
||||||
self:create_player("joystick", Vec(50, 300))
|
self:create_player("joystick", Vec(600, 300))
|
||||||
end
|
end
|
||||||
|
|
||||||
function MainState:update(dt)
|
function MainState:update(dt)
|
||||||
@ -121,9 +130,9 @@ function MainState:update(dt)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local move_dir = player:get_move_dir()
|
local move_dir = player:get_move_dir()
|
||||||
local acc = move_dir * 300
|
local acc = move_dir * 1700
|
||||||
player.vel = player.vel + acc * dt
|
player.vel = player.vel + acc * dt
|
||||||
player.vel = player.vel * 0.98
|
player.vel = player.vel * 0.8
|
||||||
player.collider:setLinearVelocity(player.vel.x, player.vel.y)
|
player.collider:setLinearVelocity(player.vel.x, player.vel.y)
|
||||||
|
|
||||||
if not player.has_bolt then
|
if not player.has_bolt then
|
||||||
@ -158,8 +167,13 @@ function MainState:update(dt)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for _, player in ipairs(self.players) do
|
for _, player in ipairs(self.players) do
|
||||||
player.pos.x = player.collider:getX()
|
local collider = player.collider
|
||||||
player.pos.y = player.collider:getY()
|
player.pos.x = collider:getX()
|
||||||
|
player.pos.y = collider:getY()
|
||||||
|
|
||||||
|
local velx, vely = collider:getLinearVelocity()
|
||||||
|
player.vel.x = velx
|
||||||
|
player.vel.y = vely
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self.victory_timer = (self.victory_timer or 0) + dt
|
self.victory_timer = (self.victory_timer or 0) + dt
|
||||||
@ -183,9 +197,9 @@ end
|
|||||||
function MainState:create_player(controls, pos)
|
function MainState:create_player(controls, pos)
|
||||||
local player = Player:new(controls, self.world, pos)
|
local player = Player:new(controls, self.world, pos)
|
||||||
player.bolt_mods = {
|
player.bolt_mods = {
|
||||||
BoltMods.mods.speed_bounce,
|
-- BoltMods.mods.speed_bounce,
|
||||||
BoltMods.mods.bouncy,
|
BoltMods.mods.bouncy,
|
||||||
BoltMods.mods.retain_speed,
|
-- BoltMods.mods.retain_speed,
|
||||||
}
|
}
|
||||||
sort_bolt_mods(player.bolt_mods)
|
sort_bolt_mods(player.bolt_mods)
|
||||||
player.collider.fixture:setUserData("player")
|
player.collider.fixture:setUserData("player")
|
||||||
@ -340,8 +354,6 @@ function MainState:draw()
|
|||||||
love.graphics.setColor(1, 1, 1)
|
love.graphics.setColor(1, 1, 1)
|
||||||
love.graphics.line(mx-cursor_size, my, mx+cursor_size, my)
|
love.graphics.line(mx-cursor_size, my, mx+cursor_size, my)
|
||||||
love.graphics.line(mx, my-cursor_size, mx, my+cursor_size)
|
love.graphics.line(mx, my-cursor_size, mx, my+cursor_size)
|
||||||
-- love.graphics.print(mx, 200, 10)
|
|
||||||
-- love.graphics.print(my, 200, 40)
|
|
||||||
|
|
||||||
if DRAW_COLLIDERS then
|
if DRAW_COLLIDERS then
|
||||||
love.graphics.setColor(0.8, 0.1, 0.8)
|
love.graphics.setColor(0.8, 0.1, 0.8)
|
||||||
@ -350,7 +362,7 @@ function MainState:draw()
|
|||||||
|
|
||||||
if #self.players == 1 then
|
if #self.players == 1 then
|
||||||
love.graphics.setColor(0.2, 1, 0.2)
|
love.graphics.setColor(0.2, 1, 0.2)
|
||||||
love.graphics.print("Victory!", 300, 200)
|
love.graphics.print("Victory!", 150, 100)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
95
src/states/map-editor.lua
Normal file
95
src/states/map-editor.lua
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
local MapEditor = {}
|
||||||
|
|
||||||
|
function MapEditor:enter()
|
||||||
|
self.obstacles = {}
|
||||||
|
self.current_obstacle = {}
|
||||||
|
self:from_clipboard()
|
||||||
|
end
|
||||||
|
|
||||||
|
function MapEditor:keypressed(key)
|
||||||
|
if key == "escape" then
|
||||||
|
love.event.quit()
|
||||||
|
self:refresh_clipboard()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function MapEditor:mousepressed(mx, my)
|
||||||
|
mx = math.floor(mx)
|
||||||
|
my = math.floor(my)
|
||||||
|
if self.current_obstacle[1] then
|
||||||
|
local origin_x, origin_y = self.current_obstacle[1][1], self.current_obstacle[1][2]
|
||||||
|
local dist = ((origin_x-mx)^2 + (origin_y-my)^2)^0.5
|
||||||
|
if dist < 10 then
|
||||||
|
table.insert(self.obstacles, self.current_obstacle)
|
||||||
|
self.current_obstacle = {}
|
||||||
|
self:update_clipboard()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(self.current_obstacle, {mx, my})
|
||||||
|
end
|
||||||
|
|
||||||
|
function MapEditor:update_clipboard()
|
||||||
|
local lines = {}
|
||||||
|
for _, obstacle in ipairs(self.obstacles) do
|
||||||
|
local points = {}
|
||||||
|
for _, point in ipairs(obstacle) do
|
||||||
|
table.insert(points, ("{%d, %d}"):format(point[1], point[2]))
|
||||||
|
end
|
||||||
|
table.insert(lines, ("table.insert(self.obstacles, {%s})"):format(table.concat(points, ", ")))
|
||||||
|
end
|
||||||
|
|
||||||
|
local text = table.concat(lines, "\n")
|
||||||
|
love.system.setClipboardText(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
function MapEditor:from_clipboard()
|
||||||
|
self.obstacles = {}
|
||||||
|
self.current_obstacle = {}
|
||||||
|
|
||||||
|
local text = love.system.getClipboardText()
|
||||||
|
for line in text:gmatch("%s*([^\n]+)%s*") do
|
||||||
|
local points = line:match("^table%.insert%(self%.obstacles, {(.+)}%)$")
|
||||||
|
if points then
|
||||||
|
local obstacle = {}
|
||||||
|
table.insert(self.obstacles, obstacle)
|
||||||
|
for x, y in points:gmatch("{(%d+),%s*(%d+)}") do
|
||||||
|
table.insert(obstacle, {tonumber(x), tonumber(y)})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function MapEditor:draw_obstacle(obstacle)
|
||||||
|
local n = #obstacle
|
||||||
|
if n >= 2 then
|
||||||
|
love.graphics.line(obstacle[1][1], obstacle[1][2], obstacle[n][1], obstacle[n][2])
|
||||||
|
for i=1, n-1 do
|
||||||
|
love.graphics.line(obstacle[i][1], obstacle[i][2], obstacle[i+1][1], obstacle[i+1][2])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function MapEditor:draw()
|
||||||
|
for _, obstacle in ipairs(self.obstacles) do
|
||||||
|
self:draw_obstacle(obstacle)
|
||||||
|
end
|
||||||
|
|
||||||
|
do
|
||||||
|
local obstacle = self.current_obstacle
|
||||||
|
local n = #self.current_obstacle
|
||||||
|
for i=1, n-1 do
|
||||||
|
love.graphics.line(obstacle[i][1], obstacle[i][2], obstacle[i+1][1], obstacle[i+1][2])
|
||||||
|
end
|
||||||
|
if n > 0 then
|
||||||
|
local mx, my = love.mouse.getPosition()
|
||||||
|
mx = math.floor(mx)
|
||||||
|
my = math.floor(my)
|
||||||
|
local last_point = self.current_obstacle[n]
|
||||||
|
love.graphics.line(last_point[1], last_point[2], mx, my)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return MapEditor
|
Loading…
Reference in New Issue
Block a user