First commit, lots of work since a while back.

This commit is contained in:
Gonzalo Delgado 2024-08-17 09:13:37 -03:00
commit 58fe857de1
3 changed files with 1880 additions and 0 deletions

5
conf.lua Normal file
View File

@ -0,0 +1,5 @@
function love.conf(t)
t.version = "11.4"
t.window.fullscreen = true
t.title = "Literate Flicky Clone"
end

1575
flickyclone.org Normal file

File diff suppressed because it is too large Load Diff

300
main.lua Normal file
View File

@ -0,0 +1,300 @@
local inspect = require("inspect/inspect")
local Vector = require("vector")
local helpers = require("helpers")
function swept_aabb(box1, box2, dt)
local x_inv_entry, y_inv_entry, x_inv_exit, y_inv_exit
if box1.dx > 0 then
x_inv_entry = box2.x - (box1.x + box1.w)
x_inv_exit = (box2.x + box2.w) - box1.x
else
x_inv_entry = (box2.x + box2.w) - box1.x
x_inv_exit = box2.x - (box1.x + box1.w)
end
if (box1.dy > 0) then
y_inv_entry = box2.y - (box1.y + box1.h)
y_inv_exit = (box2.y + box2.h) - box1.y
else
y_inv_entry = (box2.y + box2.h) - box1.y
y_inv_exit = box2.y - (box1.y + box1.h)
end
local x_entry_time, y_entry_time, x_exit_time, y_exit_time
if (box1.dx == 0) then
x_entry_time = -math.huge
x_exit_time = math.huge
else
x_entry_time = x_inv_entry / box1.dx
x_exit_time = x_inv_exit / box1.dx
end
if (box1.dy == 0) then
y_entry_time = -math.huge
y_exit_time = math.huge
else
y_entry_time = y_inv_entry / box1.dy
y_exit_time = y_inv_exit / box1.dy
end
local entry_time = math.max(y_entry_time, x_entry_time)
local exit_time = math.min(y_exit_time, x_exit_time)
local normalx, normaly
if (entry_time > exit_time or x_entry_time < 0 and y_entry_time < 0 or x_entry_time > 1 or y_entry_time > 1) then
normalx = 0
normaly = 0
entry_time = 1
else
if x_entry_time > y_entry_time then
if x_inv_entry < 0 then
normalx = 1
normaly = 0
else
normalx = -1
normaly = 0
end
else
if y_inv_entry < 0 then
normalx = 0
normaly = 1
else
normalx = 0
normaly = -1
end
end
end
print("SWEPT AABB TIME:", entry_time )
return {normal={x=normalx, y=normaly}, dt=entry_time}
end
function get_displacement_rect(entity, next_pos)
local displacement_rect = {
x=entity.x,
y=entity.y,
w=entity.w,
h=entity.h,
}
if entity.dx > 0 then
displacement_rect.x = entity.x
displacement_rect.w = next_pos.x + entity.w - entity.x
elseif entity.dx < 0 then
displacement_rect.x = next_pos.x
displacement_rect.w = entity.x + entity.w - next_pos.x
end
if entity.dy > 0 then
displacement_rect.y = entity.y
displacement_rect.h = next_pos.y + entity.h - entity.y
elseif entity.dy < 0 then
displacement_rect.y = next_pos.y
displacement_rect.h = entity.y + entity.h - next_pos.y
end
return displacement_rect
end
function distance(point_a, point_b)
return math.sqrt(math.pow(point_a.x - point_b.x, 2) + math.pow(point_a.y - point_b.y, 2))
end
function find_closest_tile_in_rectangle(entity, rect, game)
local closest
local center = {x=entity.x + entity.w/2, y=entity.y + entity.h/2}
local min_distance = math.huge
local top_left_tile = game:pixel_to_tile(rect)
local bottom_right_tile = game:pixel_to_tile({
x=rect.x + rect.w,
y=rect.y + rect.h,
})
for tx=top_left_tile.x, bottom_right_tile.x do
for ty=top_left_tile.y, bottom_right_tile.y do
local value = game:tile_value({x=tx, y=ty})
if value ~= 0 then
local tile_center = {x=game:x_to_pixel(tx) + game.map.tilewidth/2, y=game:y_to_pixel(ty) + game.map.tileheight/2}
local current_distance = distance(center, tile_center)
if current_distance < min_distance then
closest = {x=game:x_to_pixel(tx), y=game:y_to_pixel(ty), w=game.map.tilewidth, h=game.map.tileheight, value=value, tx=tx, ty=ty}
min_distance = current_distance
end
end
end
end
return closest
end
local game = {
current_frame = 0,
input = {
right=false,
left=false,
up=false,
down=false,
jump=false,
}
}
function game:updateInput(dt)
self.input.right = love.keyboard.isDown("d", "right")
self.input.left = love.keyboard.isDown("a", "left")
self.input.up = love.keyboard.isDown("w", "up")
self.input.down = love.keyboard.isDown("down", "s")
self.input.jump = love.keyboard.isDown("space")
end
function game:loadWorldMap(filename)
self.map = dofile(filename)
local platform_layers = helpers.filter(self.map.layers, function (layer) return layer.name == "platforms" end)
self.platforms = platform_layers[1].data
self.physics = {
gravity=self.map.tileheight*9.8, -- somewhat exagerated gravity (3x)
maxdx=self.map.tilewidth*8, -- max horizontal speed
maxdy=self.map.tileheight*24, -- max vertical speed
jump=self.map.tileheight*512, -- instant jump impulse
}
self.physics.horizontal_acc = self.physics.maxdx*2 -- horizontal acceleration
self.physics.friction = self.physics.maxdx*1.5 -- horizontal friction
end
function game:pixel_to_tile(pixel)
return {
x=math.floor(pixel.x/self.map.tilewidth) + 1,
y=math.floor(pixel.y/self.map.tileheight) + 1,
}
end
function game:x_to_pixel(tile_x)
return (tile_x - 1)*self.map.tilewidth
end
function game:y_to_pixel(tile_y)
return (tile_y - 1)*self.map.tileheight
end
function game:tile_to_pixel(tile)
local pixel = {
x=self:x_to_pixel(tile.x),
y=self:y_to_pixel(tile.y),
}
return pixel
end
function game:tile_to_rect(tile)
local pixel = self:tile_to_pixel(tile)
return {
x=pixel.x,
y=pixel.y,
w=self.map.tilewidth,
h=self.map.tileheight,
}
end
function rectangles_overlap(rect1, rect2)
local x_overlaps = rect1.x < rect2.x + rect2.w and rect1.x + rect1.w > rect2.x
local y_overlaps = rect1.y < rect2.y + rect2.h and rect1.y + rect1.h > rect2.y
return {x_overlaps and y_overlaps, x_overlaps, y_overlaps}
end
function game:tile_value(tile)
return self.platforms[tile.x + (tile.y - 1)*self.map.width]
end
function game:initializeGraphics()
local screen_width = self.map.width*self.map.tilewidth
local screen_height = self.map.height*self.map.tileheight
love.graphics.setDefaultFilter("nearest", "nearest")
local desktop_width, desktop_height = love.window.getDesktopDimensions()
self.scale_width = desktop_width/screen_width
self.scale_height = desktop_height/screen_height
self.screen_width = screen_width
self.screen_height = screen_height
self.debug_font = love.graphics.newFont(8, "normal", 2)
end
function game:draw_debug_infos()
love.graphics.setColor(0.1, 0.1, 0.1)
love.graphics.setFont(self.debug_font)
love.graphics.print("pos:("..math.floor(self.player_entity.pos.x)..", "..math.floor(self.player_entity.pos.y)..") g="..tostring(self.player_entity.grounded), 2, 2)
love.graphics.print(
"vel:("..math.floor(self.player_entity.vel.x)..", "..math.floor(self.player_entity.vel.y)..")", 96, 2)
love.graphics.print("input:(L="..tostring(self.input.left)..",R="..tostring(self.input.right)..",U="..tostring(self.input.up)..",D="..tostring(self.input.down)..",J="..tostring(self.input.jump)..")", 2, 12)
end
local Tile = require("tile")
local Entity = require("entity")
function game:initPlayer(x, y)
self.player_entity = Entity:new(x, y, 4, 8, self.physics.gravity, 2*8, self.physics.horizontal_acc, self.physics.friction)
end
function love.load()
game:loadWorldMap("map.lua")
game:initializeGraphics()
game:initPlayer(180, 100)
end
function love.update(dt)
game.current_frame = game.current_frame + 1
game:updateInput(dt)
game:updatePlayer(dt)
game:updateCamera(dt)
game:updateItems(dt)
game:updateEnemies(dt)
game:updateChirps(dt)
end
function game:updatePlayer(dt)
-- local accel = {x=0, y=self.physics.gravity}
-- if self.input.right then
-- accel.x = self.physics.accel
-- elseif wasright then
-- accel.x = -self.physics.friction
-- end
-- if self.input.left then
-- accel.x = -self.physics.accel
-- elseif wasleft then
-- accel.x = self.physics.friction
-- end
-- if self.input.jump and self.player_entity.grounded then
-- accel.y = -self.physics.jump
-- end
-- self.player_entity = self.player_entity:update(accel, dt)
self.player_entity = self.player_entity:move(self.input, dt, self.current_frame)
end
function game:updateCamera(dt)
end
function game:updateItems(dt)
end
function game:updateEnemies(dt)
end
function game:updateChirps(dt)
end
function love.draw()
love.graphics.setColor(1, 1, 1)
love.graphics.push()
love.graphics.scale(game.scale_width, game.scale_height)
love.graphics.setColor(0.2, 0.2, 0.2)
for ty = 1, game.map.height do
for tx = 1, game.map.width do
love.graphics.setColor(0.9, 0.8, 0.7)
local tile = {x=tx, y=ty}
local pixel = game:tile_to_pixel(tile)
local value = game:tile_value(tile)
if value > 0 then
love.graphics.setColor(0.2, 0.2, 0.2)
end
local tile_rect = {
x=pixel.x,
y=pixel.y,
w=game.map.tilewidth,
h=game.map.tileheight,
}
love.graphics.rectangle("fill", pixel.x, pixel.y, game.map.tilewidth, game.map.tileheight)
love.graphics.setColor(0.9, 0.1, 0.3)
love.graphics.rectangle("line", pixel.x, pixel.y, game.map.tilewidth, game.map.tileheight)
end
end
game:draw_debug_infos()
love.graphics.setColor(0, 0.8, 0.1)
game.player_entity:draw()
love.graphics.pop()
end