summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAki <nthirtyone@gmail.com>2017-09-21 21:05:37 +0200
committerAki <nthirtyone@gmail.com>2017-09-21 21:05:37 +0200
commite9a450d65d4fb564691cdf651ef5771dd88303ae (patch)
treef49d29582dd6877f3b3c807c3f7d9d92d368f798
parenteb8302723cd85adca0fbaf505cfb315f1db0299a (diff)
parentb97985def64b8bd8f93a7b391b12333595432e52 (diff)
downloadroflnauts-e9a450d65d4fb564691cdf651ef5771dd88303ae.zip
roflnauts-e9a450d65d4fb564691cdf651ef5771dd88303ae.tar.gz
roflnauts-e9a450d65d4fb564691cdf651ef5771dd88303ae.tar.bz2
Merge branch 'maps'
-rw-r--r--assets/backgrounds/404.pngbin0 -> 15541 bytes
-rw-r--r--assets/backgrounds/alpha.png (renamed from assets/backgrounds/alpha-1.png)bin3708 -> 3708 bytes
-rw-r--r--assets/decorations/205-exhaust-left.pngbin0 -> 299 bytes
-rw-r--r--assets/decorations/205-exhaust-right.pngbin0 -> 303 bytes
-rw-r--r--assets/decorations/205-exhaust-top.pngbin0 -> 376 bytes
-rw-r--r--assets/decorations/205-flames.pngbin0 -> 412 bytes
-rw-r--r--assets/decorations/sorona-bridge-left.pngbin0 -> 439 bytes
-rw-r--r--assets/decorations/sorona-bridge-loop.pngbin0 -> 154 bytes
-rw-r--r--assets/decorations/sorona-bridge-right.pngbin0 -> 455 bytes
-rw-r--r--assets/maps.pngbin10070 -> 10688 bytes
-rw-r--r--assets/music/404.oggbin0 -> 3338347 bytes
-rw-r--r--assets/platforms/205-left.pngbin0 -> 842 bytes
-rw-r--r--assets/platforms/205-right.pngbin0 -> 822 bytes
-rw-r--r--assets/platforms/205-top.pngbin0 -> 487 bytes
-rw-r--r--assets/platforms/404-bottom.pngbin0 -> 2054 bytes
-rw-r--r--assets/platforms/404-small.pngbin0 -> 389 bytes
-rw-r--r--assets/platforms/404-top.pngbin0 -> 1911 bytes
-rw-r--r--assets/platforms/sorona-button.png (renamed from assets/platforms/sorona-center.png)bin794 -> 794 bytes
-rw-r--r--assets/platforms/sorona-left-bottom.pngbin765 -> 0 bytes
-rw-r--r--assets/platforms/sorona-medium.pngbin0 -> 903 bytes
-rw-r--r--assets/platforms/sorona-right-bottom.pngbin1185 -> 0 bytes
-rw-r--r--assets/platforms/sorona-right-top.pngbin1569 -> 0 bytes
-rw-r--r--assets/platforms/sorona-small.pngbin0 -> 581 bytes
-rw-r--r--assets/platforms/sorona-spiked.png (renamed from assets/platforms/sorona-left-top.png)bin1496 -> 1496 bytes
-rw-r--r--assets/platforms/sorona-wide.pngbin0 -> 1539 bytes
-rw-r--r--config/animations/clouds-default.lua18
-rw-r--r--config/animations/flames.lua21
-rw-r--r--config/maps.lua9
-rw-r--r--config/maps/205.lua49
-rw-r--r--config/maps/404.lua51
-rw-r--r--config/maps/aiguillon.lua47
-rw-r--r--config/maps/alpha abyss.lua75
-rw-r--r--config/maps/alpha.lua43
-rw-r--r--config/maps/default.lua39
-rw-r--r--config/maps/ribbit.lua37
-rw-r--r--config/maps/rill.lua49
-rw-r--r--config/maps/sorona.lua71
-rw-r--r--config/maps/starstorm.lua61
-rw-r--r--config/menus/host.lua48
-rw-r--r--config/menus/select.lua76
-rw-r--r--config/platforms/205-left.lua8
-rw-r--r--config/platforms/205-right.lua8
-rw-r--r--config/platforms/205-top.lua5
-rw-r--r--config/platforms/404-bottom.lua10
-rw-r--r--config/platforms/404-small.lua5
-rw-r--r--config/platforms/404-top.lua9
-rw-r--r--config/platforms/aiguillon-left-big.lua5
-rw-r--r--config/platforms/aiguillon-left-small.lua5
-rw-r--r--config/platforms/aiguillon-middle.lua5
-rw-r--r--config/platforms/aiguillon-right-big.lua5
-rw-r--r--config/platforms/aiguillon-right-small.lua5
-rw-r--r--config/platforms/aiguillon-wide.lua5
-rw-r--r--config/platforms/alpha-big.lua31
-rw-r--r--config/platforms/alpha-small.lua31
-rw-r--r--config/platforms/default-big.lua5
-rw-r--r--config/platforms/default-side.lua5
-rw-r--r--config/platforms/default-top.lua5
-rw-r--r--config/platforms/ribbit-bottom.lua5
-rw-r--r--config/platforms/ribbit-left.lua5
-rw-r--r--config/platforms/ribbit-right.lua5
-rw-r--r--config/platforms/ribbit-top.lua5
-rw-r--r--config/platforms/rill-center.lua5
-rw-r--r--config/platforms/rill-flat-left.lua5
-rw-r--r--config/platforms/rill-flat-right.lua5
-rw-r--r--config/platforms/rill-slope-left.lua5
-rw-r--r--config/platforms/rill-slope-right.lua5
-rw-r--r--config/platforms/sorona-button.lua5
-rw-r--r--config/platforms/sorona-medium.lua5
-rw-r--r--config/platforms/sorona-small.lua5
-rw-r--r--config/platforms/sorona-spiked.lua5
-rw-r--r--config/platforms/sorona-wide.lua5
-rw-r--r--config/platforms/starstorm-center.lua5
-rw-r--r--config/platforms/starstorm-left-bottom.lua5
-rw-r--r--config/platforms/starstorm-left-middle.lua5
-rw-r--r--config/platforms/starstorm-left-top.lua8
-rw-r--r--config/platforms/starstorm-right-bottom.lua5
-rw-r--r--config/platforms/starstorm-right-middle.lua5
-rw-r--r--config/platforms/starstorm-right-top.lua8
-rw-r--r--main.lua12
-rw-r--r--not/Button.lua4
-rw-r--r--not/Camera.lua221
-rw-r--r--not/Cloud.lua84
-rw-r--r--not/CloudGenerator.lua73
-rw-r--r--not/Element.lua24
-rw-r--r--not/Group.lua116
-rw-r--r--not/Hero.lua17
-rw-r--r--not/Layer.lua45
-rw-r--r--not/MusicPlayer.lua15
-rw-r--r--not/Object.lua7
-rw-r--r--not/PhysicalBody.lua22
-rw-r--r--not/Ray.lua44
-rw-r--r--not/SceneManager.lua8
-rw-r--r--not/Selector.lua365
-rw-r--r--not/Sprite.lua17
-rw-r--r--not/Timer.lua30
-rw-r--r--not/Trap.lua51
-rw-r--r--not/Trigger.lua18
-rw-r--r--not/World.lua565
98 files changed, 1689 insertions, 1006 deletions
diff --git a/assets/backgrounds/404.png b/assets/backgrounds/404.png
new file mode 100644
index 0000000..d1d7231
--- /dev/null
+++ b/assets/backgrounds/404.png
Binary files differ
diff --git a/assets/backgrounds/alpha-1.png b/assets/backgrounds/alpha.png
index d897910..d897910 100644
--- a/assets/backgrounds/alpha-1.png
+++ b/assets/backgrounds/alpha.png
Binary files differ
diff --git a/assets/decorations/205-exhaust-left.png b/assets/decorations/205-exhaust-left.png
new file mode 100644
index 0000000..b631959
--- /dev/null
+++ b/assets/decorations/205-exhaust-left.png
Binary files differ
diff --git a/assets/decorations/205-exhaust-right.png b/assets/decorations/205-exhaust-right.png
new file mode 100644
index 0000000..95615dc
--- /dev/null
+++ b/assets/decorations/205-exhaust-right.png
Binary files differ
diff --git a/assets/decorations/205-exhaust-top.png b/assets/decorations/205-exhaust-top.png
new file mode 100644
index 0000000..9ea95ca
--- /dev/null
+++ b/assets/decorations/205-exhaust-top.png
Binary files differ
diff --git a/assets/decorations/205-flames.png b/assets/decorations/205-flames.png
new file mode 100644
index 0000000..d1a0cf4
--- /dev/null
+++ b/assets/decorations/205-flames.png
Binary files differ
diff --git a/assets/decorations/sorona-bridge-left.png b/assets/decorations/sorona-bridge-left.png
new file mode 100644
index 0000000..3543db0
--- /dev/null
+++ b/assets/decorations/sorona-bridge-left.png
Binary files differ
diff --git a/assets/decorations/sorona-bridge-loop.png b/assets/decorations/sorona-bridge-loop.png
new file mode 100644
index 0000000..40d237b
--- /dev/null
+++ b/assets/decorations/sorona-bridge-loop.png
Binary files differ
diff --git a/assets/decorations/sorona-bridge-right.png b/assets/decorations/sorona-bridge-right.png
new file mode 100644
index 0000000..22fd8d5
--- /dev/null
+++ b/assets/decorations/sorona-bridge-right.png
Binary files differ
diff --git a/assets/maps.png b/assets/maps.png
index 261622c..f0e530d 100644
--- a/assets/maps.png
+++ b/assets/maps.png
Binary files differ
diff --git a/assets/music/404.ogg b/assets/music/404.ogg
new file mode 100644
index 0000000..e952135
--- /dev/null
+++ b/assets/music/404.ogg
Binary files differ
diff --git a/assets/platforms/205-left.png b/assets/platforms/205-left.png
new file mode 100644
index 0000000..9afd1c6
--- /dev/null
+++ b/assets/platforms/205-left.png
Binary files differ
diff --git a/assets/platforms/205-right.png b/assets/platforms/205-right.png
new file mode 100644
index 0000000..4e55642
--- /dev/null
+++ b/assets/platforms/205-right.png
Binary files differ
diff --git a/assets/platforms/205-top.png b/assets/platforms/205-top.png
new file mode 100644
index 0000000..e67eb66
--- /dev/null
+++ b/assets/platforms/205-top.png
Binary files differ
diff --git a/assets/platforms/404-bottom.png b/assets/platforms/404-bottom.png
new file mode 100644
index 0000000..b3e9831
--- /dev/null
+++ b/assets/platforms/404-bottom.png
Binary files differ
diff --git a/assets/platforms/404-small.png b/assets/platforms/404-small.png
new file mode 100644
index 0000000..787cd67
--- /dev/null
+++ b/assets/platforms/404-small.png
Binary files differ
diff --git a/assets/platforms/404-top.png b/assets/platforms/404-top.png
new file mode 100644
index 0000000..7452857
--- /dev/null
+++ b/assets/platforms/404-top.png
Binary files differ
diff --git a/assets/platforms/sorona-center.png b/assets/platforms/sorona-button.png
index 835526d..835526d 100644
--- a/assets/platforms/sorona-center.png
+++ b/assets/platforms/sorona-button.png
Binary files differ
diff --git a/assets/platforms/sorona-left-bottom.png b/assets/platforms/sorona-left-bottom.png
deleted file mode 100644
index 4c02b04..0000000
--- a/assets/platforms/sorona-left-bottom.png
+++ /dev/null
Binary files differ
diff --git a/assets/platforms/sorona-medium.png b/assets/platforms/sorona-medium.png
new file mode 100644
index 0000000..519f3c9
--- /dev/null
+++ b/assets/platforms/sorona-medium.png
Binary files differ
diff --git a/assets/platforms/sorona-right-bottom.png b/assets/platforms/sorona-right-bottom.png
deleted file mode 100644
index a023482..0000000
--- a/assets/platforms/sorona-right-bottom.png
+++ /dev/null
Binary files differ
diff --git a/assets/platforms/sorona-right-top.png b/assets/platforms/sorona-right-top.png
deleted file mode 100644
index 57ccb8d..0000000
--- a/assets/platforms/sorona-right-top.png
+++ /dev/null
Binary files differ
diff --git a/assets/platforms/sorona-small.png b/assets/platforms/sorona-small.png
new file mode 100644
index 0000000..da2fabe
--- /dev/null
+++ b/assets/platforms/sorona-small.png
Binary files differ
diff --git a/assets/platforms/sorona-left-top.png b/assets/platforms/sorona-spiked.png
index e59bd99..e59bd99 100644
--- a/assets/platforms/sorona-left-top.png
+++ b/assets/platforms/sorona-spiked.png
Binary files differ
diff --git a/assets/platforms/sorona-wide.png b/assets/platforms/sorona-wide.png
new file mode 100644
index 0000000..4d595e3
--- /dev/null
+++ b/assets/platforms/sorona-wide.png
Binary files differ
diff --git a/config/animations/clouds-default.lua b/config/animations/clouds-default.lua
new file mode 100644
index 0000000..bbf8a28
--- /dev/null
+++ b/config/animations/clouds-default.lua
@@ -0,0 +1,18 @@
+return
+{
+ default = {
+ [1] = love.graphics.newQuad( 1, 1, 158,47, 478,49),
+ frames = 1,
+ repeated = true
+ },
+ default2 = {
+ [1] = love.graphics.newQuad(160, 1, 158,47, 478,49),
+ frames = 1,
+ repeated = true
+ },
+ default3 = {
+ [1] = love.graphics.newQuad(319, 1, 158,47, 478,49),
+ frames = 1,
+ repeated = true
+ }
+}
diff --git a/config/animations/flames.lua b/config/animations/flames.lua
new file mode 100644
index 0000000..62ecbb1
--- /dev/null
+++ b/config/animations/flames.lua
@@ -0,0 +1,21 @@
+return
+{
+ default = {
+ [1] = love.graphics.newQuad(0, 0, 42, 19, 168, 19),
+ [2] = love.graphics.newQuad(42, 0, 42, 19, 168, 19),
+ frames = 2,
+ repeated = true
+ },
+ fadein = {
+ [1] = love.graphics.newQuad(84, 0, 42, 19, 168, 19),
+ [2] = love.graphics.newQuad(126, 0, 42, 19, 168, 19),
+ frames = 2,
+ repeated = false
+ },
+ fadeout = {
+ [1] = love.graphics.newQuad(126, 0, 42, 19, 168, 19),
+ [2] = love.graphics.newQuad(84, 0, 42, 19, 168, 19),
+ frames = 2,
+ repeated = false
+ }
+}
diff --git a/config/maps.lua b/config/maps.lua
deleted file mode 100644
index 32e89a5..0000000
--- a/config/maps.lua
+++ /dev/null
@@ -1,9 +0,0 @@
-return {
- "default",
- "rill",
- "ribbit",
- "starstorm",
- "aiguillon",
- "sorona",
- "alpha abyss"
-}
diff --git a/config/maps/205.lua b/config/maps/205.lua
new file mode 100644
index 0000000..d0aa1f8
--- /dev/null
+++ b/config/maps/205.lua
@@ -0,0 +1,49 @@
+return
+{
+ name = "AI Station 205",
+ theme = "sorona.ogg",
+ portrait = 1, -- TODO: See `maps/ribbit`.
+ center = {x = 0, y = 0},
+ width = 360,
+ height = 240,
+ respawns = {
+ {x = -10, y = -55},
+ {x = 0, y = -55},
+ {x = 10, y = -55}
+ },
+ create = {
+ {
+ flames = true
+ },
+ {
+ x = -36,
+ y = -48,
+ platform = "205-top"
+ },
+ {
+ x = -36+9,
+ y = -48+11,
+ decoration = "assets/decorations/205-exhaust-top.png"
+ },
+ {
+ x = -122,
+ y = 10,
+ platform = "205-left"
+ },
+ {
+ x = -122+49,
+ y = 10+2,
+ decoration = "assets/decorations/205-exhaust-left.png"
+ },
+ {
+ x = 28,
+ y = 10,
+ platform = "205-right"
+ },
+ {
+ x = 28+29,
+ y = 10+2,
+ decoration = "assets/decorations/205-exhaust-right.png"
+ }
+ }
+}
diff --git a/config/maps/404.lua b/config/maps/404.lua
new file mode 100644
index 0000000..44b6c93
--- /dev/null
+++ b/config/maps/404.lua
@@ -0,0 +1,51 @@
+return
+{
+ name = "AI Station 404",
+ theme = "404.ogg",
+ portrait = 8, -- TODO: See `maps/ribbit`.
+ center = {x = 0, y = 0},
+ width = 360,
+ height = 240,
+ respawns = {
+ {x = -15, y = -80},
+ {x = -5, y = -80},
+ {x = 5, y = -80},
+ {x = 15, y = -80}
+ },
+ create = {
+ {
+ ratio = 0,
+ background = "assets/backgrounds/404.png",
+ },
+ {
+ x = -105,
+ y = -75,
+ platform = "404-top"
+ },
+ {
+ x = -123,
+ y = 25,
+ platform = "404-bottom"
+ },
+ {
+ x = 138,
+ y = -25,
+ platform = "404-small"
+ },
+ {
+ x = -180,
+ y = -25,
+ platform = "404-small"
+ },
+ {
+ x = 138,
+ y = 65,
+ platform = "404-small"
+ },
+ {
+ x = -180,
+ y = 65,
+ platform = "404-small"
+ }
+ }
+} \ No newline at end of file
diff --git a/config/maps/aiguillon.lua b/config/maps/aiguillon.lua
index 40d3928..c4f0ee3 100644
--- a/config/maps/aiguillon.lua
+++ b/config/maps/aiguillon.lua
@@ -1,58 +1,51 @@
-return {
- -- CENTER AND SIZE
- name = "aiguillon",
+return
+{
+ name = "Aiguillon",
theme = "aiguillon.ogg",
- center_x = 0,
- center_y = 10,
+ portrait = 5, -- TODO: See `maps/ribbit`.
+ center = {x = 0, y = 10},
width = 370,
height = 290,
- -- RESPAWN POINTS
respawns = {
- {x = 0, y = -80},
- {x = 0, y = -80},
- {x = 0, y = -80},
- {x = 0, y = -80},
+ {x = -15, y = -80},
+ {x = -5, y = -80},
+ {x = 5, y = -80},
+ {x = 15, y = -80},
},
- -- GRAPHICS
- clouds = false,
- background = "assets/backgrounds/aiguillon.png",
- platforms = {
+ create = {
+ {
+ ratio = 0,
+ background = "assets/backgrounds/aiguillon.png"
+ },
{
x = -108,
y = 22,
- shape = {1,0, 212,0, 212,12, 206,18, 14,18, 1,12},
- sprite = "assets/platforms/aiguillon-wide.png"
+ platform = "aiguillon-wide"
},
{
x = -46,
y = -19,
- shape = {1,0, 87,0, 87,18, 14,18, 1,12},
- sprite = "assets/platforms/aiguillon-middle.png"
+ platform = "aiguillon-middle"
},
{
x = -141,
y = -57,
- shape = {1,0, 50,0, 50,18, 5,18, 1,13},
- sprite = "assets/platforms/aiguillon-left-big.png"
+ platform = "aiguillon-left-big"
},
{
x = -132,
y = 84,
- shape = {1,0, 25,0, 25,18, 1,18},
- sprite = "assets/platforms/aiguillon-left-small.png"
+ platform = "aiguillon-left-small"
},
{
x = 77,
y = -57,
- shape = {1,0, 50,0, 50,12, 37,18, 1,18},
- sprite = "assets/platforms/aiguillon-right-big.png"
+ platform = "aiguillon-right-big"
},
{
x = 103,
y = 84,
- shape = {1,0, 25,0, 25,18, 1,18},
- sprite = "assets/platforms/aiguillon-right-small.png"
+ platform = "aiguillon-right-small"
}
},
- decorations = {}
}
diff --git a/config/maps/alpha abyss.lua b/config/maps/alpha abyss.lua
deleted file mode 100644
index 0dd2c61..0000000
--- a/config/maps/alpha abyss.lua
+++ /dev/null
@@ -1,75 +0,0 @@
--- The abyss of the alpha.
--- Animations
-local animations_small = {
- default = {
- frames = 20,
- repeated = true
- }
-}
-local animations_big = {
- default = {
- frames = 20,
- repeated = true
- }
-}
-for i=1,10 do
- local a = love.graphics.newQuad(i*118-118, 0, 118,51, 1180,51)
- animations_big.default[i*2-1] = a
- animations_big.default[i*2] = a
- local a = love.graphics.newQuad(i*60-60, 0, 60,20, 600,20)
- animations_small.default[i*2-1] = a
- animations_small.default[i*2] = a
-end
--- Map data
-return {
- -- GENERAL
- name = "alpha abyss",
- theme = "alpha.ogg",
- center_x = 0,
- center_y = -80,
- width = 360,
- height = 240,
- -- RESPAWN POINTS
- respawns = {
- {x = -30, y = 0},
- {x = 30, y = 0},
- {x = 0, y = 0},
- {x = -120, y = -50},
- {x = 120, y = -50},
- {x = 0, y = -75}
- },
- -- GRAPHICS
- clouds = false,
- background = "assets/backgrounds/alpha-1.png",
- platforms = {
- {
- x = -60,
- y = 0,
- shape = {0,0, 117,0, 101,50, 16,50},
- sprite = "assets/platforms/alpha-big.png",
- animations = animations_big
- },
- {
- x = -145,
- y = -50,
- shape = {0,0, 59,0, 59,19, 0,19},
- sprite = "assets/platforms/alpha-small.png",
- animations = animations_small
- },
- {
- x = 85,
- y = -50,
- shape = {0,0, 59,0, 59,19, 0,19},
- sprite = "assets/platforms/alpha-small.png",
- animations = animations_small
- },
- {
- x = -30,
- y = -80,
- shape = {0,0, 59,0, 59,19, 0,19},
- sprite = "assets/platforms/alpha-small.png",
- animations = animations_small
- }
- },
- decorations = {}
-}
diff --git a/config/maps/alpha.lua b/config/maps/alpha.lua
new file mode 100644
index 0000000..795b6cf
--- /dev/null
+++ b/config/maps/alpha.lua
@@ -0,0 +1,43 @@
+return
+{
+ name = "Alpha Abyss",
+ theme = "alpha.ogg",
+ portrait = 7, -- TODO: See `maps/ribbit`.
+ center = {x = 0, y = -80},
+ width = 360,
+ height = 240,
+ respawns = {
+ {x = -30, y = 0},
+ {x = 30, y = 0},
+ {x = 0, y = 0},
+ {x = -120, y = -50},
+ {x = 120, y = -50},
+ {x = 0, y = -75}
+ },
+ create = {
+ {
+ ratio = 0,
+ background = "assets/backgrounds/alpha.png",
+ },
+ {
+ x = -60,
+ y = 0,
+ platform = "alpha-big",
+ },
+ {
+ x = -145,
+ y = -50,
+ platform = "alpha-small",
+ },
+ {
+ x = 85,
+ y = -50,
+ platform = "alpha-small",
+ },
+ {
+ x = -30,
+ y = -80,
+ platform = "alpha-small",
+ }
+ },
+}
diff --git a/config/maps/default.lua b/config/maps/default.lua
index 05b8dc9..22c03f6 100644
--- a/config/maps/default.lua
+++ b/config/maps/default.lua
@@ -1,47 +1,46 @@
--- Default map from original roflnauts
-return {
- -- GENERAL
+return
+{
name = "default",
theme = "default.ogg",
- center_x = 0,
- center_y = 0,
+ portrait = 1, -- TODO: See `maps/ribbit`.
+ center = {x = 0, y = 0},
width = 360,
height = 240,
- -- RESPAWN POINTS
respawns = {
{x = -15, y = -80},
{x = -5, y = -80},
{x = 5, y = -80},
{x = 15, y = -80}
},
- -- GRAPHICS
- clouds = true,
- background = "assets/backgrounds/default.png",
- platforms = {
+ create = {
+ {
+ clouds = "assets/clouds.png",
+ animations = "clouds-default",
+ count = 8,
+ },
+ {
+ ratio = 0,
+ background = "assets/backgrounds/default.png"
+ },
{
x = -91,
y = 0,
- shape = {0,1, 180,1, 180,10, 95,76, 86,76, 0,10},
- sprite = "assets/platforms/default-big.png"
+ platform = "default-big"
},
{
x = 114,
y = 50,
- shape = {0,1, 51,1, 51,18, 0,18},
- sprite = "assets/platforms/default-side.png"
+ platform = "default-side"
},
{
x = -166,
y = 50,
- shape = {0,1, 51,1, 51,18, 0,18},
- sprite = "assets/platforms/default-side.png"
+ platform = "default-side"
},
{
x = -17,
y = -50,
- shape = {0,1, 33,1, 33,14, 0,14},
- sprite = "assets/platforms/default-top.png"
+ platform = "default-top"
}
- },
- decorations = {}
+ }
}
diff --git a/config/maps/ribbit.lua b/config/maps/ribbit.lua
index c3f5c78..08683ac 100644
--- a/config/maps/ribbit.lua
+++ b/config/maps/ribbit.lua
@@ -1,46 +1,41 @@
-return {
- -- GENERAL
- name = "ribbit",
+return
+{
+ name = "Ribbit IV",
theme = "ribbit.ogg",
- center_x = 0,
- center_y = 50,
+ portrait = 3, -- TODO: Either separate portraits now or change `iconsList` and `menu/host`. See also both mentioned files.
+ center = {x = 0, y = 50},
width = 360,
height = 240,
- -- RESPAWN POINTS
respawns = {
{x = -15, y = -80},
{x = -5, y = -80},
{x = 5, y = -80},
{x = 15, y = -80}
},
- -- GRAPHICS
- clouds = false,
- background = "assets/backgrounds/ribbit.png",
- platforms = {
+ create = {
+ {
+ ratio = 0,
+ background = "assets/backgrounds/ribbit.png"
+ },
{
x = -154,
y = 10,
- shape = {1,12, 48,12, 48,32, 1,32},
- sprite = "assets/platforms/ribbit-left.png"
+ platform = "ribbit-left"
},
{
x = 67,
y = 7,
- shape = {36,14, 83,14, 83,29, 36,29},
- sprite = "assets/platforms/ribbit-right.png"
+ platform = "ribbit-right"
},
{
x = -70,
y = -5,
- shape = {0,3, 139,3, 134,24, 5,24},
- sprite = "assets/platforms/ribbit-top.png"
+ platform = "ribbit-top"
},
{
x = -54,
y = 63,
- shape = {0,3, 107,3, 75,44, 32,44},
- sprite = "assets/platforms/ribbit-bottom.png"
+ platform = "ribbit-bottom"
}
- },
- decorations = {}
-} \ No newline at end of file
+ }
+}
diff --git a/config/maps/rill.lua b/config/maps/rill.lua
index 83c02f2..b027923 100644
--- a/config/maps/rill.lua
+++ b/config/maps/rill.lua
@@ -1,73 +1,66 @@
-return {
- -- CENTER AND SIZE
- name = "rill",
+return
+{
+ name = "Rill",
theme = "rill.ogg",
- center_x = 0,
- center_y = 75,
+ portrait = 2, -- TODO: See `maps/ribbit`.
+ center = {x = 0, y = 75},
width = 400,
height = 260,
- -- RESPAWN POINTS
respawns = {
{x = -135, y = 10},
{x = -135, y = 10},
{x = 135, y = 10},
{x = 135, y = 10}
},
- -- GRAPHICS
- clouds = false,
- background = "assets/backgrounds/rill.png",
- platforms = {
+ create = {
+ {
+ ratio = 0,
+ background = "assets/backgrounds/rill.png"
+ },
{
x = -151,
y = 25,
- shape = {0,0, 55,0, 55,11, 0,11},
- sprite = "assets/platforms/rill-flat-left.png"
+ platform = "rill-flat-left"
},
{
x = 93,
y = 25,
- shape = {0,0, 55,0, 55,11, 0,11},
- sprite = "assets/platforms/rill-flat-right.png"
+ platform = "rill-flat-right"
},
{
x = -24,
y = 55,
- shape = {0,0, 48,0, 47,15, 1,15},
- sprite = "assets/platforms/rill-center.png"
+ platform = "rill-center"
},
{
x = -112,
y = 80,
- shape = {77,30, 17,0, 0,0, 0,7, 77,44},
- sprite = "assets/platforms/rill-slope-left.png"
+ platform = "rill-slope-left"
},
{
x = 35,
y = 80,
- shape = {0,30, 60,0, 77,0, 77,7, 0,44},
- sprite = "assets/platforms/rill-slope-right.png"
- }
- },
- decorations = {
+ platform = "rill-slope-right"
+ },
{
x = 98,
y = -20,
- sprite = "assets/decorations/rill-lollipop-big-purple.png"
+ decoration = "assets/decorations/rill-lollipop-big-purple.png"
},
{
x = 127,
y = 4,
- sprite = "assets/decorations/rill-lollipop-small-green.png"
+ decoration = "assets/decorations/rill-lollipop-small-green.png"
},
{
x = -152,
y = -20,
- sprite = "assets/decorations/rill-lollipop-big-orange.png"
+ decoration = "assets/decorations/rill-lollipop-big-orange.png"
},
{
x = -121,
y = 4,
- sprite = "assets/decorations/rill-lollipop-small-blue.png"
- },
+ decoration = "assets/decorations/rill-lollipop-small-blue.png"
+ }
}
}
diff --git a/config/maps/sorona.lua b/config/maps/sorona.lua
index 8ec4727..4cc87cd 100644
--- a/config/maps/sorona.lua
+++ b/config/maps/sorona.lua
@@ -1,53 +1,50 @@
--- Sorona, but with the worms and such.
-return {
- -- GENERAL
- name = "sorona",
+return
+{
+ name = "Sorona",
theme = "sorona.ogg",
- center_x = 0,
- center_y = 0,
+ portrait = 6, -- TODO: See `maps/ribbit`.
+ center = {x = 0, y = 0},
width = 360,
height = 240,
- -- RESPAWN POINTS
respawns = {
- {x = -98, y = -70},
- {x = 70, y = -70},
- {x = -30, y = -20},
- {x = -90, y = 40},
+ {x = -10, y = -20},
+ {x = 0, y = -20},
+ {x = 10, y = -20}
},
- -- GRAPHICS
- clouds = false,
- background = "assets/backgrounds/sorona.png",
- platforms = {
+ create = {
{
- x = -60,
- y = 0,
- shape = {0,1, 59,1, 59,17, 0,17},
- sprite = "assets/platforms/sorona-center.png"
+ ratio = 0,
+ background = "assets/backgrounds/sorona.png",
},
{
- x = -40,
- y = 55,
- shape = {3,0, 180,0, 180,20, 3,20},
- sprite = "assets/platforms/sorona-right-bottom.png"
+ x = -71,
+ y = 50,
+ platform = "sorona-wide"
},
{
- x = -120,
- y = 55,
- shape = {3,0, 62,0, 62,23, 3,23},
- sprite = "assets/platforms/sorona-left-bottom.png"
+ x = -84,
+ y = -5,
+ platform = "sorona-small"
},
{
- x = 0,
- y = -50,
- shape = {1,1, 140,1, 1,17, 140,17},
- sprite = "assets/platforms/sorona-right-top.png"
+ x = -50,
+ y = -4,
+ decoration = "assets/decorations/sorona-bridge-left.png"
},
{
- x = -150,
- y = -55,
- shape = {1,9, 106,9, 40,27, 1,27},
- sprite = "assets/platforms/sorona-left-top.png"
+ x = -14,
+ y = -4,
+ decoration = "assets/decorations/sorona-bridge-loop.png"
+ },
+ {
+ x = 14,
+ y = -4,
+ decoration = "assets/decorations/sorona-bridge-right.png"
+ },
+ {
+ x = 43,
+ y = -5,
+ platform = "sorona-small"
}
- },
- decorations = {}
+ }
}
diff --git a/config/maps/starstorm.lua b/config/maps/starstorm.lua
index 7f00633..b4fabcd 100644
--- a/config/maps/starstorm.lua
+++ b/config/maps/starstorm.lua
@@ -1,12 +1,11 @@
-return {
- -- CENTER AND SIZE
- name = "starstorm",
+return
+{
+ name = "Starstorm",
theme = "starstorm.ogg",
- center_x = 0,
- center_y = -20,
+ portrait = 4, -- TODO: See `maps/ribbit`.
+ center = {x = 0, y = -20},
width = 400,
height = 260,
- -- RESPAWN POINTS
respawns = {
{x = 100, y = 45},
{x = -100, y = 45},
@@ -15,79 +14,65 @@ return {
{x = -110, y = -70},
{x = 110, y = -70}
},
- -- GRAPHICS
- clouds = false,
- background = "assets/backgrounds/starstorm.png",
- platforms = {
+ create = {
+ {
+ ratio = 0,
+ background = "assets/backgrounds/starstorm.png"
+ },
{
x = -170,
y = -55,
- shape = {
- {0,1, 33,1, 39,6, 39,21, 31,21, 0,21},
- {40,6, 115,6, 115,14, 40,14}
- },
- sprite = "assets/platforms/starstorm-left-top.png"
+ platform = "starstorm-left-top"
},
{
x = -156,
y = -2,
- shape = {0,0, 109,0, 109,20, 0,20},
- sprite = "assets/platforms/starstorm-left-middle.png"
+ platform = "starstorm-left-middle"
},
{
x = -160,
y = 69,
- shape = {0,4, 8,4, 13,1, 102,1, 102,16, 19,16, 0,11},
- sprite = "assets/platforms/starstorm-left-bottom.png"
+ platform = "starstorm-left-bottom"
},
{
x = 52,
y = -55,
- shape = {
- {115,1, 82,1, 76,6, 76,21, 84,21, 115,21},
- {75,6, 0,6, 0,14, 75,14}
- },
- sprite = "assets/platforms/starstorm-right-top.png"
+ platform = "starstorm-right-top"
},
{
x = 44,
y = -2,
- shape = {109,0, 0,0, 0,20, 109,20},
- sprite = "assets/platforms/starstorm-right-middle.png"
+ platform = "starstorm-right-middle"
},
{
x = 55,
y = 69,
- shape = {102,4, 94,4, 89,1, 0,1, 0,16, 83,16, 102,11},
- sprite = "assets/platforms/starstorm-right-bottom.png"
+ platform = "starstorm-right-bottom"
},
{
x = -27,
y = 40,
- shape = {0,6, 53,6, 53,14, 0,14},
- sprite = "assets/platforms/starstorm-center.png"
- }
- },
- decorations = {
+ platform = "starstorm-center"
+ },
{
x = -166,
y = -37,
- sprite = "assets/decorations/starstorm-left-top.png"
+ decoration = "assets/decorations/starstorm-left-top.png"
},
{
x = -163,
y = 19,
- sprite = "assets/decorations/starstorm-left-bottom.png"
+ decoration = "assets/decorations/starstorm-left-bottom.png"
},
{
x = 119,
y = -37,
- sprite = "assets/decorations/starstorm-right-top.png"
+ decoration = "assets/decorations/starstorm-right-top.png"
},
{
- x = 52+77,
+ x = 129,
y = 19,
- sprite = "assets/decorations/starstorm-right-bottom.png"
+ decoration = "assets/decorations/starstorm-right-bottom.png"
}
}
}
diff --git a/config/menus/host.lua b/config/menus/host.lua
index a180736..c8ef4d8 100644
--- a/config/menus/host.lua
+++ b/config/menus/host.lua
@@ -6,37 +6,49 @@ local Selector = require "not.Selector"
local width, height = love.graphics.getWidth()/getScale(), love.graphics.getHeight()/getScale()
local bx = width/2-29
-local map_Selector = Selector(menu)
-
-require "iconsList"
-local icons, maps = getMapsIconsList()
-
if background == nil or not background:is(require "not.MenuBackground") then
background = require "not.MenuBackground"(menu)
end
+-- TODO: This is temporary solution for generating available maps list and portraits for them to pass to Selector. See also: `iconsList`.
+local icons, maps = {}, {}
+do
+ local files = love.filesystem.getDirectoryItems("config/maps")
+ for _,filename in pairs(files) do
+ local path = string.format("config/maps/%s", filename)
+ if love.filesystem.isFile(path) and filename ~= "readme.md" then
+ local map = love.filesystem.load(path)()
+ local i, name = map.portrait, map.name
+ map.filename = path
+ if i then
+ table.insert(icons, love.graphics.newQuad((i-1)*76, 0, 76, 37, 608, 37))
+ table.insert(maps, map)
+ end
+ end
+ end
+end
+
+local mapSelector = Selector(maps, nil, menu)
+
return {
background,
- map_Selector
- :setPosition(width/2, 40)
- :setSize(80, 42)
- :setMargin(0)
- :set("global", true)
- :set("first", true)
- :set("list", maps)
- :set("icons_i", love.graphics.newImage("assets/maps.png"))
- :set("icons_q", icons)
- :set("shape", "panorama")
- :init()
+ mapSelector
+ :setPosition(width/2-40, 40)
+ :set("shape", Selector.SHAPE_PANORAMA)
+ :set("icons_quads", icons)
+ :set("icons_atlas", love.graphics.newImage("assets/maps.png"))
+ :set("getText", function (self)
+ return self:getSelected().name
+ end)
,
Button(menu)
:setText("Next")
:setPosition(bx,101)
:set("isEnabled", function ()
- return map_Selector:isLocked()
+ return mapSelector:getLocked()
end)
:set("active", function (self)
- MAP = map_Selector:getFullSelection(true)[1][1] -- please, don't kill me for this, kek
+ MAP = mapSelector:getSelected()
self.parent:open("select")
end)
,
diff --git a/config/menus/select.lua b/config/menus/select.lua
index 23f9374..1e57960 100644
--- a/config/menus/select.lua
+++ b/config/menus/select.lua
@@ -3,46 +3,75 @@ local menu, background = ...
local Button = require "not.Button"
local Selector = require "not.Selector"
local Element = require "not.Element"
+local Group = require "not.Group"
local width, height = love.graphics.getWidth()/getScale(), love.graphics.getHeight()/getScale()
local bx = width/2-29
-local naut_Selector = Selector(menu)
local start_Button = Button(menu)
-require "iconsList"
-local nautsIcons, nautsList = getNautsIconsList()
-
if background == nil or not background:is(require "not.MenuBackground") then
background = require "not.MenuBackground"(menu)
end
+-- TODO: Temporary group for naut selectors. This isn't production code at any means!
+local group, get
+do
+ local atlas = love.graphics.newImage("assets/portraits.png")
+ local nauts = require("config.nauts")
+ local icons = {}
+ for i=0,#nauts-1 do
+ table.insert(icons, love.graphics.newQuad(i*28, 0, 28, 27, 1008, 27))
+ end
+
+ group = Group(menu)
+
+ local
+ function attack (self)
+ if not self.lock then
+ if self.index == 1 then
+ return
+ end
+ if self.index == 2 then
+ self.index = self:rollRandom({1, 2})
+ end
+ if self:isUnique() then
+ self.lock = true
+ end
+ end
+ end
+
+ for i,_ in pairs(Controller.getSets()) do
+ group:addChild(Selector(nauts, group, menu))
+ :set("icons_atlas", atlas)
+ :set("icons_quads", icons)
+ :set("attack", attack)
+ end
+
+ group:set("margin", 16)
+ local gw, gh = group:getSize()
+ group:setPosition((width - gw)/2, 55)
+
+ function get ()
+ local selection = group:callEach("getLocked")
+ for i,naut in ipairs(selection) do
+ selection[i] = {naut, Controller.getSets()[i]}
+ end
+ return selection
+ end
+end
+
return {
background,
- naut_Selector
- :setPosition(width/2,60)
- :setMargin(8)
- :setSize(32, 32)
- :set("list", nautsList)
- :set("global", false)
- :set("icons_i", love.graphics.newImage("assets/portraits.png"))
- :set("icons_q", nautsIcons)
- :init()
- ,
+ group,
start_Button
:setText("Force start")
:setPosition(bx,134)
:set("isEnabled", function ()
- if #naut_Selector:getFullSelection(false) > 1 then
- return true
- end
- return false
+ return #get() > 1
end)
:set("active", function (self)
- local nauts = naut_Selector:getFullSelection(false)
- if #nauts > 1 then
- sceneManager:changeScene(World(MAP, nauts))
- end
+ sceneManager:changeScene(World(MAP, get()))
end)
,
Button(menu)
@@ -67,8 +96,7 @@ return {
end
end)
:set("update", function (self, dt)
- local total = #naut_Selector:getFullSelection(false)
- if total > 1 then
+ if #get() > 1 then
self.the_final_countdown = self.the_final_countdown - dt
else
self.the_final_countdown = 9
diff --git a/config/platforms/205-left.lua b/config/platforms/205-left.lua
new file mode 100644
index 0000000..b04a17f
--- /dev/null
+++ b/config/platforms/205-left.lua
@@ -0,0 +1,8 @@
+return
+{
+ sprite = "assets/platforms/205-left.png",
+ shape = {
+ {8,0, 54,0, 54,31, 8,27},
+ {55,29, 94,29, 92,36, 55,36}
+ }
+}
diff --git a/config/platforms/205-right.lua b/config/platforms/205-right.lua
new file mode 100644
index 0000000..c5bcca6
--- /dev/null
+++ b/config/platforms/205-right.lua
@@ -0,0 +1,8 @@
+return
+{
+ sprite = "assets/platforms/205-right.png",
+ shape = {
+ {86,0, 40,0, 40,31, 86,27},
+ {39,29, 0,29, 2,36, 39,36}
+ }
+}
diff --git a/config/platforms/205-top.lua b/config/platforms/205-top.lua
new file mode 100644
index 0000000..8470ed6
--- /dev/null
+++ b/config/platforms/205-top.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/205-top.png",
+ shape = {0,1, 72,1, 70,8, 2,8}
+}
diff --git a/config/platforms/404-bottom.lua b/config/platforms/404-bottom.lua
new file mode 100644
index 0000000..4e59a98
--- /dev/null
+++ b/config/platforms/404-bottom.lua
@@ -0,0 +1,10 @@
+return
+{
+ sprite = "assets/platforms/404-bottom.png",
+ shape = {
+ {0,0, 69,0, 87,17, 87,28, 0,28},
+ {161,17, 178,0, 247,0, 247,28, 161,28},
+ {33,28, 214,28, 214,57, 33,57},
+ {87,17, 161,17, 168,28, 87,28}
+ }
+}
diff --git a/config/platforms/404-small.lua b/config/platforms/404-small.lua
new file mode 100644
index 0000000..36b8a1d
--- /dev/null
+++ b/config/platforms/404-small.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/404-small.png",
+ shape = {0,0, 43,0, 43,8, 0,8}
+}
diff --git a/config/platforms/404-top.lua b/config/platforms/404-top.lua
new file mode 100644
index 0000000..3d3ba2b
--- /dev/null
+++ b/config/platforms/404-top.lua
@@ -0,0 +1,9 @@
+return
+{
+ sprite = "assets/platforms/404-top.png",
+ shape = {
+ {45,0, 166,0, 166,13, 45,13},
+ {23,14, 188,14, 188,26, 23,26},
+ {0,27, 211,27, 211,45, 0,45}
+ }
+}
diff --git a/config/platforms/aiguillon-left-big.lua b/config/platforms/aiguillon-left-big.lua
new file mode 100644
index 0000000..41ae46d
--- /dev/null
+++ b/config/platforms/aiguillon-left-big.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/aiguillon-left-big.png",
+ shape = {1,0, 50,0, 50,18, 5,18, 1,13}
+}
diff --git a/config/platforms/aiguillon-left-small.lua b/config/platforms/aiguillon-left-small.lua
new file mode 100644
index 0000000..7495374
--- /dev/null
+++ b/config/platforms/aiguillon-left-small.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/aiguillon-left-small.png",
+ shape = {1,0, 25,0, 25,18, 1,18}
+}
diff --git a/config/platforms/aiguillon-middle.lua b/config/platforms/aiguillon-middle.lua
new file mode 100644
index 0000000..9107dcd
--- /dev/null
+++ b/config/platforms/aiguillon-middle.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/aiguillon-middle.png",
+ shape = {1,0, 87,0, 87,18, 14,18, 1,12}
+}
diff --git a/config/platforms/aiguillon-right-big.lua b/config/platforms/aiguillon-right-big.lua
new file mode 100644
index 0000000..e5d525b
--- /dev/null
+++ b/config/platforms/aiguillon-right-big.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/aiguillon-right-big.png",
+ shape = {1,0, 50,0, 50,12, 37,18, 1,18}
+}
diff --git a/config/platforms/aiguillon-right-small.lua b/config/platforms/aiguillon-right-small.lua
new file mode 100644
index 0000000..b0baf3d
--- /dev/null
+++ b/config/platforms/aiguillon-right-small.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/aiguillon-right-small.png",
+ shape = {1,0, 25,0, 25,18, 1,18}
+}
diff --git a/config/platforms/aiguillon-wide.lua b/config/platforms/aiguillon-wide.lua
new file mode 100644
index 0000000..7b653a2
--- /dev/null
+++ b/config/platforms/aiguillon-wide.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/aiguillon-wide.png",
+ shape = {1,0, 212,0, 212,12, 206,18, 14,18, 1,12}
+}
diff --git a/config/platforms/alpha-big.lua b/config/platforms/alpha-big.lua
new file mode 100644
index 0000000..a0cfb32
--- /dev/null
+++ b/config/platforms/alpha-big.lua
@@ -0,0 +1,31 @@
+return
+{
+ sprite = "assets/platforms/alpha-big.png",
+ shape = {0,0, 117,0, 101,50, 16,50},
+ animations = {
+ default = {
+ [1] = love.graphics.newQuad(0, 0, 118, 51, 1180, 51),
+ [2] = love.graphics.newQuad(0, 0, 118, 51, 1180, 51),
+ [3] = love.graphics.newQuad(118, 0, 118, 51, 1180, 51),
+ [4] = love.graphics.newQuad(118, 0, 118, 51, 1180, 51),
+ [5] = love.graphics.newQuad(236, 0, 118, 51, 1180, 51),
+ [6] = love.graphics.newQuad(236, 0, 118, 51, 1180, 51),
+ [7] = love.graphics.newQuad(354, 0, 118, 51, 1180, 51),
+ [8] = love.graphics.newQuad(354, 0, 118, 51, 1180, 51),
+ [9] = love.graphics.newQuad(472, 0, 118, 51, 1180, 51),
+ [10] = love.graphics.newQuad(472, 0, 118, 51, 1180, 51),
+ [11] = love.graphics.newQuad(590, 0, 118, 51, 1180, 51),
+ [12] = love.graphics.newQuad(590, 0, 118, 51, 1180, 51),
+ [13] = love.graphics.newQuad(708, 0, 118, 51, 1180, 51),
+ [14] = love.graphics.newQuad(708, 0, 118, 51, 1180, 51),
+ [15] = love.graphics.newQuad(826, 0, 118, 51, 1180, 51),
+ [16] = love.graphics.newQuad(826, 0, 118, 51, 1180, 51),
+ [17] = love.graphics.newQuad(944, 0, 118, 51, 1180, 51),
+ [18] = love.graphics.newQuad(944, 0, 118, 51, 1180, 51),
+ [19] = love.graphics.newQuad(1062, 0, 118, 51, 1180, 51),
+ [20] = love.graphics.newQuad(1062, 0, 118, 51, 1180, 51),
+ frames = 20,
+ repeated = true
+ }
+ }
+}
diff --git a/config/platforms/alpha-small.lua b/config/platforms/alpha-small.lua
new file mode 100644
index 0000000..3c72af9
--- /dev/null
+++ b/config/platforms/alpha-small.lua
@@ -0,0 +1,31 @@
+return
+{
+ sprite = "assets/platforms/alpha-small.png",
+ shape = {0,0, 59,0, 59,19, 0,19},
+ animations = {
+ default = {
+ [1] = love.graphics.newQuad(0, 0, 60, 20, 600, 20),
+ [2] = love.graphics.newQuad(0, 0, 60, 20, 600, 20),
+ [3] = love.graphics.newQuad(60, 0, 60, 20, 600, 20),
+ [4] = love.graphics.newQuad(60, 0, 60, 20, 600, 20),
+ [5] = love.graphics.newQuad(120, 0, 60, 20, 600, 20),
+ [6] = love.graphics.newQuad(120, 0, 60, 20, 600, 20),
+ [7] = love.graphics.newQuad(180, 0, 60, 20, 600, 20),
+ [8] = love.graphics.newQuad(180, 0, 60, 20, 600, 20),
+ [9] = love.graphics.newQuad(240, 0, 60, 20, 600, 20),
+ [10] = love.graphics.newQuad(240, 0, 60, 20, 600, 20),
+ [11] = love.graphics.newQuad(300, 0, 60, 20, 600, 20),
+ [12] = love.graphics.newQuad(300, 0, 60, 20, 600, 20),
+ [13] = love.graphics.newQuad(360, 0, 60, 20, 600, 20),
+ [14] = love.graphics.newQuad(360, 0, 60, 20, 600, 20),
+ [15] = love.graphics.newQuad(420, 0, 60, 20, 600, 20),
+ [16] = love.graphics.newQuad(420, 0, 60, 20, 600, 20),
+ [17] = love.graphics.newQuad(480, 0, 60, 20, 600, 20),
+ [18] = love.graphics.newQuad(480, 0, 60, 20, 600, 20),
+ [19] = love.graphics.newQuad(540, 0, 60, 20, 600, 20),
+ [20] = love.graphics.newQuad(540, 0, 60, 20, 600, 20),
+ frames = 20,
+ repeated = true
+ }
+ }
+}
diff --git a/config/platforms/default-big.lua b/config/platforms/default-big.lua
new file mode 100644
index 0000000..85893b3
--- /dev/null
+++ b/config/platforms/default-big.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/default-big.png",
+ shape = {0,1, 180,1, 180,10, 95,76, 86,76, 0,10}
+}
diff --git a/config/platforms/default-side.lua b/config/platforms/default-side.lua
new file mode 100644
index 0000000..77b55bd
--- /dev/null
+++ b/config/platforms/default-side.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/default-side.png",
+ shape = {0,1, 51,1, 51,18, 0,18}
+}
diff --git a/config/platforms/default-top.lua b/config/platforms/default-top.lua
new file mode 100644
index 0000000..dbe4cbe
--- /dev/null
+++ b/config/platforms/default-top.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/default-top.png",
+ shape = {0,1, 33,1, 33,14, 0,14}
+}
diff --git a/config/platforms/ribbit-bottom.lua b/config/platforms/ribbit-bottom.lua
new file mode 100644
index 0000000..38e4d95
--- /dev/null
+++ b/config/platforms/ribbit-bottom.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/ribbit-bottom.png",
+ shape = {0,3, 107,3, 75,44, 32,44},
+}
diff --git a/config/platforms/ribbit-left.lua b/config/platforms/ribbit-left.lua
new file mode 100644
index 0000000..69039dd
--- /dev/null
+++ b/config/platforms/ribbit-left.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/ribbit-left.png",
+ shape = {1,12, 48,12, 48,32, 1,32},
+}
diff --git a/config/platforms/ribbit-right.lua b/config/platforms/ribbit-right.lua
new file mode 100644
index 0000000..1aa6e9e
--- /dev/null
+++ b/config/platforms/ribbit-right.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/ribbit-right.png",
+ shape = {36,14, 83,14, 83,29, 36,29},
+}
diff --git a/config/platforms/ribbit-top.lua b/config/platforms/ribbit-top.lua
new file mode 100644
index 0000000..1493114
--- /dev/null
+++ b/config/platforms/ribbit-top.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/ribbit-top.png",
+ shape = {0,3, 139,3, 134,24, 5,24},
+}
diff --git a/config/platforms/rill-center.lua b/config/platforms/rill-center.lua
new file mode 100644
index 0000000..72104b3
--- /dev/null
+++ b/config/platforms/rill-center.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/rill-center.png",
+ shape = {0,0, 48,0, 47,15, 1,15}
+}
diff --git a/config/platforms/rill-flat-left.lua b/config/platforms/rill-flat-left.lua
new file mode 100644
index 0000000..f1fdd5e
--- /dev/null
+++ b/config/platforms/rill-flat-left.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/rill-flat-left.png",
+ shape = {0,0, 55,0, 55,11, 0,11}
+}
diff --git a/config/platforms/rill-flat-right.lua b/config/platforms/rill-flat-right.lua
new file mode 100644
index 0000000..8bf70a9
--- /dev/null
+++ b/config/platforms/rill-flat-right.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/rill-flat-right.png",
+ shape = {0,0, 55,0, 55,11, 0,11}
+}
diff --git a/config/platforms/rill-slope-left.lua b/config/platforms/rill-slope-left.lua
new file mode 100644
index 0000000..49052b4
--- /dev/null
+++ b/config/platforms/rill-slope-left.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/rill-slope-left.png",
+ shape = {77,30, 17,0, 0,0, 0,7, 77,44}
+}
diff --git a/config/platforms/rill-slope-right.lua b/config/platforms/rill-slope-right.lua
new file mode 100644
index 0000000..3eca829
--- /dev/null
+++ b/config/platforms/rill-slope-right.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/rill-slope-right.png",
+ shape = {0,30, 60,0, 77,0, 77,7, 0,44}
+}
diff --git a/config/platforms/sorona-button.lua b/config/platforms/sorona-button.lua
new file mode 100644
index 0000000..2ca3bae
--- /dev/null
+++ b/config/platforms/sorona-button.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/sorona-button.png",
+ shape = {0,1, 59,1, 59,17, 0,17}
+}
diff --git a/config/platforms/sorona-medium.lua b/config/platforms/sorona-medium.lua
new file mode 100644
index 0000000..50eaeeb
--- /dev/null
+++ b/config/platforms/sorona-medium.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/sorona-medium.png",
+ shape = {3,1, 61,1, 61,23, 3,23}
+}
diff --git a/config/platforms/sorona-small.lua b/config/platforms/sorona-small.lua
new file mode 100644
index 0000000..1a01c69
--- /dev/null
+++ b/config/platforms/sorona-small.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/sorona-small.png",
+ shape = {3,1, 39,1, 39,18, 3,18}
+}
diff --git a/config/platforms/sorona-spiked.lua b/config/platforms/sorona-spiked.lua
new file mode 100644
index 0000000..00d975b
--- /dev/null
+++ b/config/platforms/sorona-spiked.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/sorona-spiked.png",
+ shape = {1,9, 106,9, 40,27, 1,27}
+}
diff --git a/config/platforms/sorona-wide.lua b/config/platforms/sorona-wide.lua
new file mode 100644
index 0000000..d0916c9
--- /dev/null
+++ b/config/platforms/sorona-wide.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/sorona-wide.png",
+ shape = {1,1, 140,1, 1,17, 140,17}
+}
diff --git a/config/platforms/starstorm-center.lua b/config/platforms/starstorm-center.lua
new file mode 100644
index 0000000..77af4f8
--- /dev/null
+++ b/config/platforms/starstorm-center.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/starstorm-center.png",
+ shape = {0,6, 53,6, 53,14, 0,14}
+}
diff --git a/config/platforms/starstorm-left-bottom.lua b/config/platforms/starstorm-left-bottom.lua
new file mode 100644
index 0000000..f40185b
--- /dev/null
+++ b/config/platforms/starstorm-left-bottom.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/starstorm-left-bottom.png",
+ shape = {0,4, 8,4, 13,1, 102,1, 102,16, 19,16, 0,11},
+}
diff --git a/config/platforms/starstorm-left-middle.lua b/config/platforms/starstorm-left-middle.lua
new file mode 100644
index 0000000..0804309
--- /dev/null
+++ b/config/platforms/starstorm-left-middle.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/starstorm-left-middle.png",
+ shape = {0,0, 109,0, 109,20, 0,20}
+}
diff --git a/config/platforms/starstorm-left-top.lua b/config/platforms/starstorm-left-top.lua
new file mode 100644
index 0000000..9cc1944
--- /dev/null
+++ b/config/platforms/starstorm-left-top.lua
@@ -0,0 +1,8 @@
+return
+{
+ sprite = "assets/platforms/starstorm-left-top.png",
+ shape = {
+ {0,1, 33,1, 39,6, 39,21, 31,21, 0,21},
+ {40,6, 115,6, 115,14, 40,14}
+ }
+}
diff --git a/config/platforms/starstorm-right-bottom.lua b/config/platforms/starstorm-right-bottom.lua
new file mode 100644
index 0000000..16462cb
--- /dev/null
+++ b/config/platforms/starstorm-right-bottom.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/starstorm-right-bottom.png",
+ shape = {102,4, 94,4, 89,1, 0,1, 0,16, 83,16, 102,11}
+}
diff --git a/config/platforms/starstorm-right-middle.lua b/config/platforms/starstorm-right-middle.lua
new file mode 100644
index 0000000..af9b712
--- /dev/null
+++ b/config/platforms/starstorm-right-middle.lua
@@ -0,0 +1,5 @@
+return
+{
+ sprite = "assets/platforms/starstorm-right-middle.png",
+ shape = {109,0, 0,0, 0,20, 109,20}
+}
diff --git a/config/platforms/starstorm-right-top.lua b/config/platforms/starstorm-right-top.lua
new file mode 100644
index 0000000..4470754
--- /dev/null
+++ b/config/platforms/starstorm-right-top.lua
@@ -0,0 +1,8 @@
+return
+{
+ sprite = "assets/platforms/starstorm-right-top.png",
+ shape = {
+ {115,1, 82,1, 76,6, 76,21, 84,21, 115,21},
+ {75,6, 0,6, 0,14, 75,14}
+ }
+}
diff --git a/main.lua b/main.lua
index ac04383..a71b9e2 100644
--- a/main.lua
+++ b/main.lua
@@ -47,12 +47,18 @@ function love.draw ()
love.graphics.setFont(Font)
love.graphics.setColor(255, 0, 0, 255)
love.graphics.print("Debug ON", 10, 10, 0, scale, scale)
- love.graphics.setColor(255, 255, 255, 255)
- love.graphics.print("Current FPS: "..tostring(love.timer.getFPS()), 10, 10+9*scale, 0, scale, scale)
+ if dbg_msg then
+ love.graphics.setColor(255, 255, 255, 255)
+ love.graphics.print(dbg_msg, 10, 10+9*scale, 0, scale, scale)
+ end
end
end
-function love.update (dt) sceneManager:update(dt) end
+function love.update (dt)
+ dbg_msg = string.format("FPS: %d\n", love.timer.getFPS())
+ sceneManager:update(dt)
+end
+
function love.quit () Settings.save() end
-- Pass input to Controller
diff --git a/not/Button.lua b/not/Button.lua
index a2f7a19..3493a84 100644
--- a/not/Button.lua
+++ b/not/Button.lua
@@ -15,6 +15,10 @@ function Button:new (parent)
self.sprite, self.quads = parent:getSheet()
end
+function Button:getSize ()
+ return 58, 15
+end
+
function Button:setText (text)
self.text = text or ""
return self
diff --git a/not/Camera.lua b/not/Camera.lua
index aa4df5b..65395cb 100644
--- a/not/Camera.lua
+++ b/not/Camera.lua
@@ -1,37 +1,46 @@
---- `Camera`
--- Used in drawing.
-Camera = {
- x = 0,
- y = 0,
- dest_x = 0,
- dest_y = 0,
- shake = 0,
- timer = 0,
- delay = 0,
- origin_x = 0,
- origin_y = 0,
- shake_x = 0,
- shake_y = 0,
- world = --[[not.World]]nil,
-}
-
--- Constructor of `Camera`
-function Camera:new (world)
- local o = {}
- setmetatable(o, self)
- self.__index = self
- o.world = world
- o:setPosition(o:follow())
- o:setDestination(o:follow())
- return o
-end
-
--- Drawing offsets
-function Camera:getOffsets ()
- return -self.x,-self.y
-end
-
--- Position
+--- Used in drawing other stuff in places.
+-- TODO: Camera is missing documentation on every important method.
+Camera = require "not.Object":extends()
+
+Camera.SHAKE_LENGTH = 0.6
+Camera.SHAKE_INTERVAL = 0.03
+
+-- TODO: Camera would really make use of vec2s (other classes would use them too).
+function Camera:new (x, y, world)
+ self.world = world
+ self:setPosition(x, y)
+ self:resetSum()
+ self:initShake()
+end
+
+function Camera:initShake ()
+ self.shakeTime = 0
+ self.shakeInterval = 0
+ self.shakeShift = {
+ theta = love.math.random() * 2,
+ radius = 0
+ }
+end
+
+function Camera:push ()
+ love.graphics.push()
+end
+
+function Camera:transform (scale, ratio, vw, vh)
+ local px, py = self:getPosition()
+ local sx, sy = self:getShake()
+ local dx, dy = (px + sx) * ratio, (py + sy) * ratio
+
+ vw, vh = vw / scale / 2, vh / scale / 2
+
+ love.graphics.scale(scale, scale)
+ love.graphics.translate(vw - dx, vh - dy)
+end
+
+function Camera:pop ()
+ love.graphics.pop()
+end
+
function Camera:setPosition (x, y)
local x = x or 0
local y = y or 0
@@ -42,102 +51,86 @@ function Camera:getPosition ()
return self.x, self.y
end
-function Camera:getPositionScaled ()
- return self.x*getScale(), self.y*getScale()
-end
-
--- Destination
-function Camera:setDestination (x, y)
- local x = x or 0
- local y = y or 0
- self.dest_x, self.dest_y = x, y
+function Camera:getBoundaries (scale, vw, vh)
+ local x, y = self:getPosition()
+ local width, height = vw / scale / 2, vh / scale / 2
+ return x - width, y - height, x + width, y + height
end
-function Camera:getDestination ()
- return self.dest_x, self.dest_y
+function Camera:startShake ()
+ self.shakeTime = Camera.SHAKE_LENGTH
end
--- Translate points
-function Camera:translatePosition (x, y)
- local x = x or 0
- local y = y or 0
- return (x-self.x)*getScale(), (y-self.y)*getScale()
+local
+function limit (theta)
+ if theta > 2 then
+ return limitAngle(theta - 2)
+ end
+ if theta < 0 then
+ return limitAngle(theta + 2)
+ end
+ return theta
end
-function Camera:translatePoints(...)
- local a = {...}
- local r = {}
- local x,y = self:getOffsets()
- for k,v in pairs(a) do
- if k%2 == 1 then
- table.insert(r, (v + x) * getScale())
+-- TODO: Magic numbers present in Camera's shake.
+function Camera:shake (dt)
+ if self.shakeTime > 0 then
+ self.shakeTime = self.shakeTime - dt
+ if self.shakeInterval < 0 then
+ self.shakeShift.theta = self.shakeShift.theta - 1.3 + love.math.random() * 0.6
+ self.shakeShift.radius = 50 * self.shakeTime
+ self.shakeInterval = Camera.SHAKE_INTERVAL
else
- table.insert(r, (v + y) * getScale())
+ self.shakeShift.radius = self.shakeShift.radius * 0.66
+ self.shakeInterval = self.shakeInterval - dt
+ end
+ if self.shakeTime < 0 then
+ self.shakeShift.radius = 0
end
end
- return r
-end
-
--- Shake it
--- Really bad script, but for now it works
-function Camera:shake ()
- if self.shake_x == 0 then
- self.shake_x = math.random(-10, 10) * 2
- elseif self.shake_x > 0 then
- self.shake_x = math.random(-10, -1) * 2
- elseif self.shake_x < 0 then
- self.shake_x = math.random(10, 1) * 2
- end
- if self.shake_y == 0 then
- self.shake_y = math.random(-10, 10) * 2
- elseif self.shake_y > 0 then
- self.shake_y = math.random(-10, -1) * 2
- elseif self.shake_y < 0 then
- self.shake_y = math.random(10, 1) * 2
- end
- local x = self.origin_x + self.shake_x
- local y = self.origin_y + self.shake_y
- self:setDestination(x, y)
end
-function Camera:startShake ()
- self.timer = 0.3
- self.origin_x, self.origin_y = self:getPosition()
+function Camera:getShake ()
+ local radius = self.shakeShift.radius
+ local theta = self.shakeShift.theta * math.pi
+ return radius * math.cos(theta), radius * math.sin(theta)
end
--- Move follow
-function Camera:follow ()
+function Camera:resetSum ()
+ self.sumX = 0
+ self.sumY = 0
+ self.sumI = 0
+end
+
+function Camera:sum (x, y)
local map = self.world.map
- local sum_x,sum_y,i = map.center_x, map.center_y, 1
- for k,naut in pairs(self.world.Nauts) do
- local naut_x,naut_y = naut:getPosition()
- if math.abs(naut_x - map.center_x) < map.width/2 and
- math.abs(naut_y - map.center_y) < map.height/2 then
- i = i + 1
- sum_x = naut_x + sum_x
- sum_y = naut_y + sum_y
- end
+ if math.abs(x - map.center.x) < map.width/2 and
+ math.abs(y - map.center.y) < map.height/2 then
+ self.sumX = self.sumX + x
+ self.sumY = self.sumY + y
+ self.sumI = self.sumI + 1
end
- local x = sum_x / i - love.graphics.getWidth()/getScale()/2
- local y = sum_y / i - love.graphics.getHeight()/getScale()/2 + 4*getScale() -- hotfix
- return x,y
end
--- Update
-function Camera:update (dt)
- if self.timer > 0 then
- self.timer = self.timer - dt
- if self.delay <= 0 then
- self:shake()
- self.delay = 0.02
- else
- self.delay = self.delay - dt
- end
- else
- self:setDestination(self:follow())
+function Camera:getSumPostion ()
+ if self.sumI > 0 then
+ return self.sumX / self.sumI, self.sumY / self.sumI
end
- local dx, dy = self:getDestination()
- dx = (dx - self.x) * 6 * dt
- dy = (dy - self.y) * 6 * dt
- self:setPosition(self.x + dx, self.y + dy)
+ return 0, 0
+end
+
+function Camera:step (dt)
+ local x, y = self:getSumPostion()
+ local dx, dy = (x - self.x), (y - self.y)
+ if math.abs(dx) > 0.4 or math.abs(dy) > 0.4 then
+ x = self.x + (x - self.x) * dt * 6
+ y = self.y + (y - self.y) * dt * 6
+ end
+ self:setPosition(x, y)
+end
+
+function Camera:update (dt)
+ self:step(dt)
+ self:shake(dt)
+ self:resetSum()
end
diff --git a/not/Cloud.lua b/not/Cloud.lua
index 25169c0..4851042 100644
--- a/not/Cloud.lua
+++ b/not/Cloud.lua
@@ -1,61 +1,45 @@
-require "not.Decoration"
-
--- `Cloud`
--- That white thing moving in the background.
--- TODO: extends variables names to be readable.
-Cloud = Decoration:extends()
-Cloud.t = 1 -- type (sprite number)
-Cloud.v = 13 -- velocity
-
--- TODO: allow maps to use other quads and sprites for clouds
--- TODO: you know this isn't right, don't you?
-local animations = {
- default = {
- [1] = love.graphics.newQuad( 1, 1, 158,47, 478,49),
- frames = 1,
- repeated = true
- },
- default2 = {
- [1] = love.graphics.newQuad(160, 1, 158,47, 478,49),
- frames = 1,
- repeated = true
- },
- default3 = {
- [1] = love.graphics.newQuad(319, 1, 158,47, 478,49),
- frames = 1,
- repeated = true
- }
-}
-
--- Constructor of `Cloud`.
-function Cloud:new (x, y, t, v, world)
- if self:getImage() == nil then
- self:setImage(Sprite.newImage("assets/clouds.png"))
- end
- Cloud.__super.new(self, x, y, world, nil)
- self:setAnimationsList(animations)
- self:setVelocity(v)
- self:setType(t)
+-- Moving decorations with limited lifespan.
+Cloud = require "not.Decoration":extends()
+
+function Cloud:new (x, y, world, imagePath)
+ Cloud.__super.new(self, x, y, world, imagePath)
+ self.velocity_x = 0
+ self.velocity_y = 0
+ self.boundary_x = 0
+ self.boundary_y = 0
end
--- Setters for cloud type and velocity.
-function Cloud:setType (type)
- local animation = "default"
- if type > 1 then
- animation = animation .. type
- end
- self:setAnimation(animation)
- self.t = type
+function Cloud:setVelocity (x, y)
+ self.velocity_x = x
+ self.velocity_y = y
+end
+
+function Cloud:setBoundary (x, y)
+ self.boundary_x = x
+ self.boundary_y = y
end
-function Cloud:setVelocity (velocity)
- self.v = velocity
+
+function Cloud:setStyle (style)
+ self:setAnimation(style)
+end
+
+function Cloud:getStyle ()
+ return self:getAnimation()
+end
+
+function Cloud:testPosition ()
+ if self.x > self.boundary_x or self.y > self.boundary_y then
+ return true
+ end
end
--- Update of `Cloud`, returns x for world to delete cloud after reaching right corner.
+-- Cloud will get deleted if this function returns true.
function Cloud:update (dt)
Cloud.__super.update(self, dt)
- self.x = self.x + self.v*dt
- return self.x
+ self.x = self.x + self.velocity_x * dt
+ self.y = self.y + self.velocity_y * dt
+ return self:testPosition()
end
return Cloud
diff --git a/not/CloudGenerator.lua b/not/CloudGenerator.lua
new file mode 100644
index 0000000..e72514b
--- /dev/null
+++ b/not/CloudGenerator.lua
@@ -0,0 +1,73 @@
+--- Generates clouds over time with randomized positions and styles.
+-- Also used as factory for Clouds.
+CloudGenerator = require "not.Object":extends()
+
+require "not.Cloud"
+
+function CloudGenerator:new (atlas, animations, count, world)
+ self.world = world
+ self.atlas = atlas
+ self.quads = animations
+ self.count = count
+ self.interval = 12
+ self.timer = self.interval
+ self.layer = false
+end
+
+-- TODO: This was a bad idea. Move Cloud creation back to World, pass created Cloud here for configuration.
+function CloudGenerator:createCloud (x, y, style)
+ local cloud = Cloud(x, y, self.world, self.atlas)
+ cloud:setAnimationsList(self.quads)
+ cloud:setAnimation(style)
+ cloud:setVelocity(13, 0)
+ cloud:setBoundary(340, 320)
+ cloud.generator = self
+ cloud.layer = self.layer
+ return cloud
+end
+
+-- TODO: CloudGen's randomization methods are too static (not configurable).
+-- TODO: Random position for Clouds inside map shouldn't be random. Make them place them where no clouds are present.
+function CloudGenerator:getRandomPosition (inside)
+ local x, y
+ local map = self.world.map
+ if not inside then
+ x = map.center.x - map.width*1.2 + love.math.random(-50, 20)
+ else
+ x = love.math.random(map.center.x - map.width / 2, map.center.x + map.width / 2)
+ end
+ y = love.math.random(map.center.y - map.height / 2, map.center.y + map.height / 2)
+ return x, y
+end
+
+function CloudGenerator:getRandomStyle ()
+ local num = love.math.random(1, 3)
+ local style = "default"
+ if num > 1 then
+ style = style .. tostring(num)
+ end
+ return style
+end
+
+function CloudGenerator:run (count, inside)
+ count = count or 1
+ for i=1,count do
+ local x, y = self:getRandomPosition(inside)
+ local style = self:getRandomStyle()
+ self.world:insertCloud(self:createCloud(x, y, style))
+ end
+end
+
+function CloudGenerator:update (dt)
+ local count = self.world:getCloudsCountFrom(self)
+ if self.timer < 0 then
+ if self.count > count then
+ self.timer = self.timer + self.interval
+ self:run()
+ end
+ else
+ self.timer = self.timer - dt
+ end
+end
+
+return CloudGenerator
diff --git a/not/Element.lua b/not/Element.lua
index 24576e6..3b0d13a 100644
--- a/not/Element.lua
+++ b/not/Element.lua
@@ -1,22 +1,22 @@
-require "not.Object"
-
--- `Element`
-- Empty element used inside `Menu`.
-Element = Object:extends()
-
-Element.parent = --[[not.Menu]]nil
-Element.x = 0
-Element.y = 0
+Element = require "not.Object":extends()
function Element:new (parent)
self.parent = parent
+ self.x = 0
+ self.y = 0
end
-function Element:delete () end -- deletes Element
+-- TODO: Element's getSize is temporary. Create BoxElement and move it there.
+function Element:getSize ()
+ return 0, 0
+end
function Element:getPosition ()
return self.x, self.y
end
+
function Element:setPosition (x, y)
self.x = x or 0
self.y = y or 0
@@ -30,12 +30,14 @@ function Element:set (name, func)
return self
end
--- Called when menu tries to focus on this element.
+--- Called when menu tries to focus on this element.
-- If it will return false then menu will skip element and go to next in list.
function Element:focus ()
return false
-end
-function Element:blur () end -- Called when Element loses focus.
+end
+
+--- Called when Element loses focus.
+function Element:blur () end
-- LÖVE2D callbacks
function Element:draw (scale) end
diff --git a/not/Group.lua b/not/Group.lua
new file mode 100644
index 0000000..970d3bc
--- /dev/null
+++ b/not/Group.lua
@@ -0,0 +1,116 @@
+--- Element used for grouping elements and passing input to selected child based on controller set.
+Group = require "not.Element":extends()
+
+function Group:new (parent)
+ Group.__super.new(self, parent)
+ self.children = {}
+ self.margin = 0
+end
+
+function Group:addChild (element)
+ table.insert(self.children, element)
+ return element
+end
+
+-- TODO: Missing semi-important docs on Group's setPosition.
+function Group:setPosition (x, y)
+ local dx = 0
+ for _,child in ipairs(self.children) do
+ child:setPosition(x + dx, y)
+ dx = dx + child:getSize() + self.margin
+ end
+ return Group.__super.setPosition(self, x, y)
+end
+
+function Group:getSize ()
+ local twidth = -self.margin
+ local theight = 0
+ for _,child in ipairs(self.children) do
+ local cwidth, cheight = child:getSize()
+ twidth = twidth + child:getSize() + self.margin
+ if theight < cheight then
+ theight = cheight
+ end
+ end
+ return twidth, theight
+end
+
+--- Calls function with parameters for each child.
+-- @param func key of function to call
+-- @param ... parameters passed to function
+-- @return table with calls' results
+function Group:callEach (func, ...)
+ local results = {}
+ for _,child in ipairs(self.children) do
+ if type(child[func]) == "function" then
+ table.insert(results, child[func](child, ...) or nil)
+ end
+ end
+ return results
+end
+
+--- Calls function with parameters for each but one child.
+-- @param avoid child to avoid calling
+-- @param func key of function to call
+-- @param ... parameters passed to function
+-- @return table with calls' results
+function Group:callEachBut (avoid, func, ...)
+ local results = {}
+ for _,child in ipairs(self.children) do
+ if child ~= avoid then
+ if type(child[func]) == "function" then
+ table.insert(results, child[func](child, ...) or nil)
+ end
+ end
+ end
+ return results
+end
+
+--- Calls function with parameters for one child based on controller set.
+-- @param set controller set
+-- @param func key of function to call
+-- @param ... parameters passed to function
+-- @return results of called function
+function Group:callWithSet (set, func, ...)
+ for i,test in ipairs(Controller.getSets()) do
+ if test == set then
+ local child = self.children[i]
+ if child then
+ return child[func](child, ...)
+ end
+ end
+ end
+end
+
+function Group:focus ()
+ self:callEach("focus")
+ self.focused = true
+ return true
+end
+
+function Group:blur ()
+ self:callEach("blur")
+ self.focused = false
+end
+
+function Group:draw (scale)
+ self:callEach("draw", scale)
+end
+
+function Group:update (dt)
+ self:callEach("update", dt)
+end
+
+function Group:controlpressed (set, action, key)
+ if self.focused then
+ self:callWithSet(set, "controlpressed", set, action, key)
+ end
+end
+
+function Group:controlreleased (set, action, key)
+ if self.focused then
+ self:callWithSet(set, "controlreleased", set, action, key)
+ end
+end
+
+return Group
diff --git a/not/Hero.lua b/not/Hero.lua
index 039aeb8..66bc511 100644
--- a/not/Hero.lua
+++ b/not/Hero.lua
@@ -27,7 +27,7 @@ function Hero:new (name, x, y, world)
Hero.load()
Hero.__super.new(self, x, y, world, imagePath)
-- Physics
- self.group = -1-#world.Nauts
+ self.group = -1-#world:getNautsAll()
self:setBodyType("dynamic")
self:setBodyFixedRotation(true)
self:newFixture()
@@ -87,8 +87,8 @@ function Hero:update (dt)
-- TODO: World/Map function for testing if Point is inside playable area.
local m = self.world.map
local x, y = self:getPosition()
- if (x < m.center_x - m.width*1.5 or x > m.center_x + m.width*1.5 or
- y < m.center_y - m.height*1.5 or y > m.center_y + m.height*1.5) and
+ if (x < m.center.x - m.width*1.5 or x > m.center.x + m.width*1.5 or
+ y < m.center.y - m.height*1.5 or y > m.center.y + m.height*1.5) and
self.isAlive
then
self:die()
@@ -165,16 +165,17 @@ function Hero:getOffset ()
return 12,15
end
--- Draw of `Hero`
-function Hero:draw (offset_x, offset_y, scale, debug)
+function Hero:draw (debug)
if not self.isAlive then return end
- Hero.__super.draw(self, offset_x, offset_y, scale, debug)
+ Hero.__super.draw(self, debug)
end
-function Hero:drawTag (offset_x, offset_y, scale)
+-- TODO: Hero@drawTag's printf is not readable.
+function Hero:drawTag ()
local x,y = self:getPosition()
love.graphics.setFont(Font)
- love.graphics.printf(string.format("Player %d", math.abs(self.group)), (math.floor(x)+offset_x)*scale, (math.floor(y)+offset_y-26)*scale,100,'center',0,scale,scale,50,0)
+ love.graphics.setColor(255, 255, 255)
+ love.graphics.printf(string.format("Player %d", math.abs(self.group)), math.floor(x), math.floor(y)-26 ,100,'center',0,1,1,50,0)
end
-- Draw HUD of `Hero`
diff --git a/not/Layer.lua b/not/Layer.lua
new file mode 100644
index 0000000..14dac32
--- /dev/null
+++ b/not/Layer.lua
@@ -0,0 +1,45 @@
+--- A little bit more than just a Canvas.
+Layer = require "not.Object":extends()
+
+function Layer:new (width, height)
+ self.canvas = love.graphics.newCanvas(width, height)
+ self.transformScale = getScale()
+ self.transformRatio = 1
+ self.drawScale = 1
+end
+
+function Layer:delete ()
+ self.canvas = nil
+end
+
+--- Sets this layer as current canvas for drawing with love.graphics functions.
+-- @return old canvas used by love
+function Layer:setAsCanvas ()
+ local c = love.graphics.getCanvas()
+ love.graphics.setCanvas(self.canvas)
+ return c
+end
+
+function Layer:renderTo (func, ...)
+ local c = self:setAsCanvas()
+ func(...)
+ love.graphics.setCanvas(c)
+end
+
+function Layer:renderToWith (camera, func, ...)
+ camera:push()
+ camera:transform(self.transformScale, self.transformRatio, self.canvas:getDimensions())
+ self:renderTo(func, ...)
+ camera:pop()
+end
+
+function Layer:clear ()
+ self:renderTo(love.graphics.clear)
+end
+
+function Layer:draw ()
+ love.graphics.setColor(255, 255, 255, 255)
+ love.graphics.draw(self.canvas, nil, nil, nil, self.drawScale, self.drawScale)
+end
+
+return Layer
diff --git a/not/MusicPlayer.lua b/not/MusicPlayer.lua
index 4634ed9..17beda4 100644
--- a/not/MusicPlayer.lua
+++ b/not/MusicPlayer.lua
@@ -1,8 +1,5 @@
-require "not.Object"
-
---- `MusicPlayer`
--- Simple music player object that plays and loops selected track.
-MusicPlayer = Object:extends()
+--- Simple music player object that stores, playes and loops tracks..
+MusicPlayer = require "not.Object":extends()
function MusicPlayer:new (trackName)
self.tracks = {}
@@ -13,8 +10,9 @@ function MusicPlayer:new (trackName)
end
function MusicPlayer:delete ()
- self.tracks = nil
self:stop()
+ self.tracks = nil
+ self.source = nil
end
function MusicPlayer:setTrack (trackName)
@@ -40,7 +38,10 @@ function MusicPlayer:getCurrentTrack ()
end
end
-function MusicPlayer:play ()
+function MusicPlayer:play (trackName)
+ if trackName then
+ self:setTrack(trackName)
+ end
self.source:play()
end
diff --git a/not/Object.lua b/not/Object.lua
index 30b91b5..352e9e3 100644
--- a/not/Object.lua
+++ b/not/Object.lua
@@ -1,3 +1,8 @@
--- Wrapping library to game's hierarchy in a shameless way.
+--- Wrapping library to game's hierarchy in a shameless way.
Object = require "lib.object.Object"
+
+--- Called before Object references are removed from parent.
+-- This is not called when Object is garbage collected.
+function Object:delete () end
+
return Object
diff --git a/not/PhysicalBody.lua b/not/PhysicalBody.lua
index 804c706..5081836 100644
--- a/not/PhysicalBody.lua
+++ b/not/PhysicalBody.lua
@@ -62,22 +62,30 @@ function PhysicalBody:update (dt)
PhysicalBody.__super.update(self, dt)
end
--- Draw of `PhysicalBody`.
-function PhysicalBody:draw (offset_x, offset_y, scale, debug)
- PhysicalBody.__super.draw(self, offset_x, offset_y, scale)
+function PhysicalBody:draw (debug)
+ PhysicalBody.__super.draw(self, debug)
if debug then
for _,fixture in pairs(self.body:getFixtureList()) do
local category = fixture:getCategory()
+ -- TODO: Fixture drawing of PhysicalBodies could take activity into account in every case.
if category == 1 then
- love.graphics.setColor(255, 69, 0, 140)
+ love.graphics.setColor(255, 69, 0, 150)
end
if category == 2 then
- love.graphics.setColor(137, 255, 0, 120)
+ love.graphics.setColor(137, 255, 0, 150)
end
if category == 3 then
- love.graphics.setColor(137, 0, 255, 40)
+ love.graphics.setColor(137, 0, 255, 50)
end
- love.graphics.polygon("fill", self.world.camera:translatePoints(self.body:getWorldPoints(fixture:getShape():getPoints())))
+ if category == 4 then
+ if self.body:isActive() then
+ love.graphics.setColor(255, 230, 0, 50)
+ else
+ love.graphics.setColor(255, 230, 0, 10)
+ end
+ end
+ local camera = self.world.camera
+ love.graphics.polygon("fill", self.body:getWorldPoints(fixture:getShape():getPoints()))
end
end
end
diff --git a/not/Ray.lua b/not/Ray.lua
index 16a9bee..4ae640a 100644
--- a/not/Ray.lua
+++ b/not/Ray.lua
@@ -1,21 +1,10 @@
-require "not.Object"
+--- That awesome effect that blinks when player dies!
+Ray = require "not.Object":extends()
---- `Ray`
--- That awesome effect that blinks when player dies!
-Ray = Object:extends()
-
-Ray.naut =--[[not.Hero]]nil
-Ray.world =--[[not.World]]nil
-Ray.canvas =--[[love.graphics.newCanvas]]nil
-Ray.delay = 0.3
-
-function Ray:new (naut, world)
- self.naut = naut
+function Ray:new (source, world)
+ self.source = source
self.world = world
- -- Cavas, this is temporary, I believe.
- local scale = getScale()
- local w, h = love.graphics.getWidth(), love.graphics.getHeight()
- self.canvas = love.graphics.newCanvas(w/scale, h/scale)
+ self.delay = 0.3
end
function Ray:update (dt)
@@ -26,25 +15,16 @@ function Ray:update (dt)
return false
end
-function Ray:draw (offset_x, offset_y, scale)
- love.graphics.setCanvas(self.canvas)
- love.graphics.clear()
+-- TODO: Ray should use Camera boundaries just-in-case.
+-- TODO: Ray uses magic numbers.
+function Ray:draw ()
love.graphics.setColor(255, 247, 228, 247)
love.graphics.setLineStyle("rough")
love.graphics.setLineWidth(self.delay*160)
- local x, y = self.naut:getPosition()
- local m = self.world.map
- local dy = m.height
- if y > m.center_y then
- dy = -dy
- end
- love.graphics.line(-x+offset_x,-y+offset_y-dy*0.7,x+offset_x,y+dy*0.7+offset_y)
- -- reset
- love.graphics.setCanvas()
- love.graphics.setLineWidth(1)
- love.graphics.setColor(255,255,255,255)
- -- draw on screen
- love.graphics.draw(self.canvas, 0, 0, 0, scale, scale)
+
+ local x, y = self.source:getPosition()
+
+ love.graphics.line(x, y, -x, -y)
end
return Ray
diff --git a/not/SceneManager.lua b/not/SceneManager.lua
index c076448..4f9edfd 100644
--- a/not/SceneManager.lua
+++ b/not/SceneManager.lua
@@ -9,7 +9,10 @@ end
-- This function should be removed when multiple scenes will be handled properly by SceneManager and other things.
function SceneManager:changeScene (scene)
- table.remove(self.scenes, #self.scenes)
+ local removed = table.remove(self.scenes, #self.scenes)
+ if removed then
+ removed:delete()
+ end
return self:addScene(scene)
end
@@ -20,7 +23,8 @@ end
-- Not nice, not nice.
function SceneManager:removeTopScene ()
- table.remove(self.scenes, #self.scenes)
+ local scene = table.remove(self.scenes, #self.scenes)
+ scene:delete()
end
function SceneManager:getAllScenes ()
diff --git a/not/Selector.lua b/not/Selector.lua
index ef78778..ee6f0e3 100644
--- a/not/Selector.lua
+++ b/not/Selector.lua
@@ -1,282 +1,195 @@
-require "not.Element"
-
--- `Selector`
--- Used in Menu for selecting various things from list. Works for each Controller set or globally.
---[[
-How to use `Selector` in `Menu` config file?
-selector:new(menu)
- :setPosition(x, y)
- :setMargin(8) -- each block has marigin on both sides; they do stack
- :setSize(32, 32) -- size of single graphics frame
- :set("list", require "nautslist")
- :set("icons_i", love.graphics.newImage("assets/portraits.png"))
- :set("icons_q", require "portraits")
- :set("global", false) -- true: single selector; false: selector for each controller set present
- :init()
-]]
-Selector = Element:extends()
+-- Element for selecting variable from list.
+Selector = require "not.Element":extends()
-Selector.width = 0
-Selector.height = 0
-Selector.margin = 0
-Selector.focused = false
-Selector.global = false
-Selector.delay = 2
-Selector.first = false
-Selector.list = --[[]]nil
-Selector.sets = --[[]]nil
-Selector.locks = --[[]]nil
-Selector.selections = --[[]]nil
-Selector.shape = "portrait"
-Selector.sprite = --[[]]nil
-Selector.quads = --[[]]nil
-Selector.icons_i = --[[]]nil
-Selector.icons_q = --[[]]nil
+Selector.DEFAULT_DELAY = 2
+Selector.SHAPE_PORTRAIT = 1
+Selector.SHAPE_PANORAMA = 2
--- Constructor
-function Selector:new (parent)
+function Selector:new (list, group, parent)
Selector.__super.new(self, parent)
- self.sprite, self.quads = parent:getSheet()
+ self.atlas, self.quads = parent:getSheet()
+ self.group = group
+ self.list = list
+ self.delay = Selector.DEFAULT_DELAY
+ self.shape = Selector.SHAPE_PORTRAIT
+ self.focused = false
+ self.lock = false
+ self.index = 1
end
--- Size of single block
+-- TODO: See `not/Element@getSize`.
function Selector:getSize ()
- return self.width, self.height
-end
-function Selector:setSize (width, height)
- self.width, self.height = width, height
- return self
-end
-
--- Spacing between two blocks
-function Selector:getMargin ()
- return self.margin
-end
-function Selector:setMargin (margin)
- self.margin = margin
- return self
+ if self.shape == Selector.SHAPE_PORTRAIT then
+ return 32, 32
+ end
+ if self.shape == Selector.SHAPE_PANORAMA then
+ return 80, 42
+ end
end
--- Initialize Selector with current settings.
-function Selector:init ()
- -- Make sure that there is list present
- if self.list == nil then
- self.list = {}
+--- Makes sure that n is in <1, total> range.
+local
+function limit (n, total)
+ if n > total then
+ return limit(n - total, total)
end
- -- Initialize global Selector
- if self.global then
- self.sets = {}
- self.locks = {false}
- self.selections = {1}
- -- Initialize Selector for Controllers
- else
- self.sets = Controller.getSets()
- self.locks = {}
- self.selections = {}
- for n=1,#self.sets do
- self.locks[n] = false
- self.selections[n] = 1
- end
+ if n < 1 then
+ return limit(n + total, total)
end
- return self
+ return n
end
--- Cycle through list on given number
-function Selector:next (n)
- local current = self.selections[n]
- self:setSelection(n, current + 1)
-end
-function Selector:previous (n)
- local current = self.selections[n]
- self:setSelection(n, current - 1)
+--- Chooses item with an index.
+-- @param index selected item's index
+-- @return old index
+function Selector:setIndex (index)
+ local old = self.index
+ self.index = limit(index, #self.list)
+ return old
end
--- Get number associated with a given set
-function Selector:checkNumber (set)
- if self.global then return 1 end -- For global Selector
- for n,check in pairs(self.sets) do
- if check == set then return n end
+function Selector:rollRandom (exclude)
+ local exclude = exclude or {}
+ local index = love.math.random(1, #self.list)
+ local elgible = true
+ for _,i in ipairs(exclude) do
+ if index == i then
+ elgible = false
+ break
+ end
+ end
+ if not elgible or not self:isUnique(self.list[index]) then
+ table.insert(exclude, index)
+ return self:rollRandom(exclude)
end
+ return index
end
--- Check if given number is locked
-function Selector:isLocked (n)
- local n = n or 1
- return self.locks[n]
+--- Returns selected item's value.
+-- @return item selected from the list
+function Selector:getSelected ()
+ return self.list[self.index]
end
--- Sets value of selection of given number. Returns old.
-function Selector:setSelection (n, new)
- -- Functception. It sounds like fun but it isn't.
- local function limit(new, total)
- if new > total then
- return limit(new - total, total)
- elseif new < 1 then
- return limit(total + new, total)
- else
- return new
- end
+--- Checks if selection is locked and returns item's value.
+-- @return item selected from the list if Selector is locked, nil otherwise
+function Selector:getLocked ()
+ if self.lock then
+ return self:getSelected()
end
- local n = n or 1
- local old = self.selections[n]
- self.selections[n] = limit(new, #self.list)
- return old
end
--- Get value of selection of given number
-function Selector:getSelection (n)
- local n = n or 1
- return self.selections[n]
+--- Checks if Selected value is unique in group's scope.
+-- @param index optional parameter to fill in place of currently selected item
+-- @return boolean answering question
+function Selector:isUnique (item)
+ local item = item or self:getSelected()
+ if self.group then
+ local locked = self.group:callEachBut(self, "getLocked")
+ for _,value in pairs(locked) do
+ if value == item then
+ return false
+ end
+ end
+ end
+ return true
end
--- Get value from list by selection
-function Selector:getListValue (i)
- return self.list[i]
+function Selector:getText ()
+ return tostring(self:getSelected())
end
--- Checks if selection of given number is unique within Selector scope.
-function Selector:isUnique (n)
- local selection = self:getSelection(n)
- for fn,v in pairs(self.selections) do
- if fn ~= n and self:isLocked(fn) and v == selection then
- return false
- end
- end
+function Selector:focus ()
+ self.focused = true
return true
end
--- Get list of selections, checks if not locked are allowed.
-function Selector:getFullSelection (allowed)
- local allowed = allowed
- if allowed == nil then allowed = false end
- local t = {}
- for n,v in pairs(self.selections) do
- local name = self:getListValue(self:getSelection(n))
- local locked = self:isLocked(n)
- if locked or allowed then
- local a = {name}
- if self.sets[n] then table.insert(a, self.sets[n]) end
- table.insert(t, a)
- end
- end
- return t
+function Selector:blur ()
+ self.focused = false
end
--- Rolls and returns random selection from list that is not locked.
-function Selector:rollRandom (avoids)
- -- Me: You should make it simpler.
- -- Inner me: Nah, it works. Leave it.
- -- Me: Ok, let's leave it as it is.
- local avoids = avoids or {}
- local total = #self.list
- local random = love.math.random(1, total)
- local eligible = true
- for _,avoid in ipairs(avoids) do
- if random == avoid then
- eligible = false
- break
- end
+-- TODO: Temporary function to determine quad to use. Will be obsolete when BoxElement will be done. See also `not/Element@getSize`.
+function Selector:getShapeString ()
+ if self.shape == Selector.SHAPE_PORTRAIT then
+ return "portrait"
end
- if not eligible or self:isLocked(random) then
- table.insert(avoids, random)
- return self:rollRandom(avoid)
- else
- return random
+ if self.shape == Selector.SHAPE_PANORAMA then
+ return "panorama"
end
end
--- Draw single block of Selector
-function Selector:drawBlock (n, x, y, scale)
- if self.quads == nil or self.sprite == nil then return end
- local x, y = x or 0, y or 0
- local name = self:getListValue(self:getSelection(n))
- local locked = self:isLocked(n)
- local sprite = self.sprite
- local quad = self.quads
- local icon = self.icons_i
- local iconq = self.icons_q[name]
- local w,h = self:getSize()
- local unique = self:isUnique(n)
- if unique then
- love.graphics.setColor(255, 255, 255, 255)
- else
- love.graphics.setColor(140, 140, 140, 255)
+function Selector:draw (scale)
+ local x, y = self:getPosition()
+ local w, h = self:getSize()
+
+ local boxType = "normal"
+ if self:getLocked() then
+ boxType = "active"
+ end
+
+ love.graphics.setColor(255, 255, 255, 255)
+ if not self:isUnique() then
+ love.graphics.setColor(120, 120, 120, 255)
end
- if not locked then
- love.graphics.draw(sprite, quad[self.shape].normal, x*scale, y*scale, 0, scale, scale)
- else
- love.graphics.draw(sprite, quad[self.shape].active, x*scale, y*scale, 0, scale, scale)
+ love.graphics.draw(self.atlas, self.quads[self:getShapeString()][boxType], x*scale, y*scale, 0, scale, scale)
+ -- TODO: That is one way to draw icon for selected value. Find better one. See: `config/menus/host`.
+ if self.icons_atlas and self.icons_quads then
+ love.graphics.draw(self.icons_atlas, self.icons_quads[self.index], (x+2)*scale, (y+3)*scale, 0, scale, scale)
end
- love.graphics.draw(icon, iconq, (x+2)*scale, (y+3)*scale, 0, scale, scale)
+
+ love.graphics.setColor(255, 255, 255, 255)
+
if self.focused then
local dy = (h-6)/2
- if not locked then
- love.graphics.draw(sprite, quad.arrow_l, (x+0-2-math.floor(self.delay))* scale, (y+dy)*scale, 0, scale, scale)
- love.graphics.draw(sprite, quad.arrow_r, (x+w-4+math.floor(self.delay))*scale, (y+dy)*scale, 0, scale, scale)
- else
- love.graphics.draw(sprite, quad.arrow_r, (x+0-2-math.floor(self.delay))* scale, (y+dy)*scale, 0, scale, scale)
- love.graphics.draw(sprite, quad.arrow_l, (x+w-4+math.floor(self.delay))*scale, (y+dy)*scale, 0, scale, scale)
+ local al, ar = self.quads.arrow_r, self.quads.arrow_l
+ if self.lock then
+ al, ar = ar, al
end
- end
- if (self:getSelection(n) ~= 1 or self.first) then
- love.graphics.setFont(Font)
- love.graphics.setColor(255, 255, 255, 255)
- love.graphics.printf(string.upper(name), (x-w)*scale, (y+h+1)*scale, w*3, "center", 0, scale, scale)
- end
-end
--- Menu callbacks
-function Selector:focus () -- Called when Element gains focus
- self.focused = true
- return true
-end
-function Selector:blur () -- Called when Element loses focus
- self.focused = false
-end
-
--- LÖVE2D callbacks
-function Selector:draw (scale)
- local x,y = self:getPosition()
- local margin = self:getMargin()
- local width = self:getSize()
- x = x - #self.selections*0.5*(margin+margin+width)
- for n=1,#self.selections do
- self:drawBlock(n, x+(margin+width)*(n-1)+margin*n, y, scale)
+ love.graphics.draw(self.atlas, ar, (x+0-2-math.floor(self.delay))*scale, (y+dy)*scale, 0, scale, scale)
+ love.graphics.draw(self.atlas, al, (x+w-4+math.floor(self.delay))*scale, (y+dy)*scale, 0, scale, scale)
end
+
+ love.graphics.setFont(Font)
+ love.graphics.printf(self:getText(), (x-w)*scale, (y+h+1)*scale, w*3, "center", 0, scale, scale)
end
+
function Selector:update (dt)
self.delay = self.delay + dt
- if self.delay > Selector.delay then -- Selector.delay is initial
- self.delay = self.delay - Selector.delay
+ if self.delay > Selector.DEFAULT_DELAY then
+ self.delay = self.delay - Selector.DEFAULT_DELAY
end
end
--- Controller callbacks
--- TODO: Add action to perform when key is pressed and selector is locked in e.g. to move into character selection from map selection.
function Selector:controlpressed (set, action, key)
if set and self.focused then
- local n = self:checkNumber(set)
- local locked = self:isLocked(n)
- if action == "left" and not locked then self:previous(n) end
- if action == "right" and not locked then self:next(n) end
- if action == "attack" then
- local name = self:getListValue(self:getSelection(n))
- if name == "random" then
- self:setSelection(n, self:rollRandom({1,2})) -- avoid empty naut
- self.locks[n] = true
- else
- -- If not empty or if first is allowed. Additionaly must be unique selection.
- if (self:getSelection(n) ~= 1 or self.first) and self:isUnique(n) then
- self.locks[n] = true
- end
- end
- end
- if action == "jump" then
- if locked then
- self.locks[n] = false
- end
+ local handler = self[action]
+ if handler then
+ handler(self)
end
end
end
+function Selector:left ()
+ if not self.lock then
+ self:setIndex(self.index - 1)
+ end
+end
+
+function Selector:right ()
+ if not self.lock then
+ self:setIndex(self.index + 1)
+ end
+end
+
+function Selector:attack ()
+ self.lock = true
+end
+
+-- Selector doesn't actually jump, haha, I tricked you!
+function Selector:jump ()
+ self.lock = false
+end
+
return Selector
diff --git a/not/Sprite.lua b/not/Sprite.lua
index 3951e6e..ec23eac 100644
--- a/not/Sprite.lua
+++ b/not/Sprite.lua
@@ -11,6 +11,7 @@ Sprite.frame = 1
Sprite.delay = .1
-- Constructor of `Sprite`.
+-- TODO: Sprites' in general don't take actual Image in constructor. That is not only case of Decoration.
function Sprite:new (imagePath)
if type(imagePath) == "string" then
self:setImage(Sprite.newImage(imagePath))
@@ -84,26 +85,24 @@ function Sprite:getOffset () return 0,0 end
-- Drawing self to LOVE2D buffer.
-- If there is no Quad, it will draw entire image. It won't draw anything if there is no image.
+-- TODO: Sprite@draw requires a serious review!
-- TODO: it doesn't follow same pattern as `not.Hero.draw`. It should implement so it can be called from `not.World`.
-- TODO: change children if above changes are in effect: `not.Platform`, `not.Decoration`.
-function Sprite:draw (offset_x, offset_y, scale)
- local offset_x = offset_x or 0
- local offset_y = offset_y or 0
-
+function Sprite:draw (debug)
local i, q = self:getImage(), self:getQuad()
local x, y = self:getPosition()
local angle = self:getAngle()
- local scaleX = self:getHorizontalMirror()*(scale or 1)
- local scaleY = self:getVerticalMirror()*(scale or 1)
+ local scaleX = self:getHorizontalMirror()
+ local scaleY = self:getVerticalMirror()
-- pixel grid ; `approx` selected to prevent floating characters on certain conditions
local approx = math.floor
if (y - math.floor(y)) > 0.5 then approx = math.ceil end
- local draw_y = (approx(y) + offset_y) * scale
- local draw_x = (math.floor(x) + offset_x) * scale
+ local draw_y = approx(y)
+ local draw_x = math.floor(x)
- if i then
+ if i and not self.hidden then
love.graphics.setColor(255,255,255,255)
if q then
love.graphics.draw(i, q, draw_x, draw_y, angle, scaleX, scaleY, self:getOffset())
diff --git a/not/Timer.lua b/not/Timer.lua
new file mode 100644
index 0000000..9ae0de8
--- /dev/null
+++ b/not/Timer.lua
@@ -0,0 +1,30 @@
+Timer = require "not.Trigger":extends()
+
+function Timer:new (delay)
+ Timer.__super.new(self)
+ self.delay = delay
+ self.left = 0
+ self.active = false
+ self.restart = false
+end
+
+function Timer:start ()
+ self.left = self.delay
+ self.active = true
+end
+
+function Timer:update (dt)
+ if self.active then
+ if self.left < 0 then
+ self:emit()
+ self.active = false
+ if self.restart then
+ self:start()
+ end
+ else
+ self.left = self.left - dt
+ end
+ end
+end
+
+return Timer
diff --git a/not/Trap.lua b/not/Trap.lua
new file mode 100644
index 0000000..0867a36
--- /dev/null
+++ b/not/Trap.lua
@@ -0,0 +1,51 @@
+Trap = require "not.PhysicalBody":extends()
+
+function Trap:new (direction, x, y, world, imagePath)
+ Trap.__super.new(self, x, y, world, imagePath)
+ self:setAnimationsList(require("config.animations.flames"))
+ self:setBodyType("static")
+
+ local mirror = 1
+ if direction == "left" then mirror = -1 end
+ local fixture = self:addFixture({0, 0, 41 * mirror, 0, 41 * mirror, 18, 0, 18})
+ fixture:setCategory(4)
+ fixture:setMask(1,3,4)
+ fixture:setUserData({direction})
+ fixture:setSensor(true)
+
+ self.mirror = mirror
+end
+
+function Trap:fadeIn ()
+ self.hidden = false
+ self:setBodyActive(true)
+ if self.animations.fadein then
+ self:setAnimation("fadein")
+ end
+end
+
+function Trap:fadeOut ()
+ self:setBodyActive(false)
+ if self.animations.fadeout then
+ self:setAnimation("fadeout")
+ else
+ self.hidden = true
+ end
+end
+
+function Trap:getHorizontalMirror ()
+ return self.mirror
+end
+
+function Trap:goToNextFrame ()
+ if self.current.repeated or not (self.frame == self.current.frames) then
+ self.frame = (self.frame % self.current.frames) + 1
+ elseif self.current == self.animations.fadeout then
+ self:setAnimation("default")
+ self.hidden = true
+ else
+ self:setAnimation("default")
+ end
+end
+
+return Trap
diff --git a/not/Trigger.lua b/not/Trigger.lua
new file mode 100644
index 0000000..c6ef7c7
--- /dev/null
+++ b/not/Trigger.lua
@@ -0,0 +1,18 @@
+Trigger = require "not.Object":extends()
+
+function Trigger:new ()
+ self.calls = {}
+end
+
+function Trigger:register (func, ...)
+ local call = {func = func, params = {...}}
+ table.insert(self.calls, call)
+end
+
+function Trigger:emit ()
+ for _,call in pairs(self.calls) do
+ call.func(unpack(call.params))
+ end
+end
+
+return Trigger
diff --git a/not/World.lua b/not/World.lua
index c73a3da..4523efa 100644
--- a/not/World.lua
+++ b/not/World.lua
@@ -1,82 +1,183 @@
---- `World`
--- Used to manage physical world and everything inside it: clouds, platforms, nauts, background etc.
+--- Used to manage physical world and everything inside it: clouds, platforms, nauts, background etc.
-- TODO: Possibly move common parts of `World` and `Menu` to abstract class `Scene`.
World = require "not.Scene":extends()
-World.world =--[[love.physics.newWorld]]nil
-World.Nauts =--[[{not.Hero}]]nil
-World.Platforms =--[[{not.Platform}]]nil
-World.Clouds =--[[{not.Cloud}]]nil
-World.Decorations =--[[{not.Decoration}]]nil
-World.Effects =--[[{not.Effect}]]nil
-World.Rays =--[[{not.Ray}]]nil
-World.camera =--[[not.Camera]]nil
-World.music =--[[not.Music]]nil
-World.clouds_delay = 5
-World.map =--[[config.maps.*]]nil
-World.background =--[[image?]]nil
-World.lastNaut = false
-
require "not.Platform"
require "not.Player"
-require "not.Cloud"
require "not.Effect"
require "not.Decoration"
require "not.Ray"
+require "not.Cloud"
+require "not.CloudGenerator"
+require "not.Layer"
+require "not.Timer"
+require "not.Trap"
+require "not.Entity"
--- Constructor of `World` ZA WARUDO!
+--- ZA WARUDO!
+-- TODO: Missing documentation on most of World's methods.
function World:new (map, nauts)
- -- Box2D physical world.
love.physics.setMeter(64)
self.world = love.physics.newWorld(0, 9.81*64, true)
- self.world:setCallbacks(self.beginContact, self.endContact)
- -- Tables for entities. TODO: It is still pretty bad!
- self.Nauts = {}
- self.Platforms = {}
- self.Clouds = {}
- self.Effects = {}
- self.Decorations = {}
- self.Rays = {}
- -- Map and misc.
- local map = map or "default"
- self:loadMap(map)
+ self.world:setCallbacks(self:getContactCallbacks())
+
+ self.lastNaut = false
+ self.entities = {}
+ self.map = map
+
+ self.camera = Camera(self.map.center.x, self.map.center.y, self)
+
+ self:initLayers()
+ self:buildMap()
self:spawnNauts(nauts)
- self.camera = Camera:new(self)
- musicPlayer:setTrack(self.map.theme)
- musicPlayer:play()
+
+ musicPlayer:play(self.map.theme)
end
-- The end of the world
function World:delete ()
- for _,platform in pairs(self.Platforms) do
- platform:delete()
+ for _,entity in pairs(self.entities) do
+ entity:delete()
end
- for _,naut in pairs(self.Nauts) do
- naut:delete()
+ for layer in self.layers() do
+ layer:delete()
end
self.world:destroy()
+ collectgarbage()
+end
+
+--- Custom iterator for layers table.
+-- Iterates over elements in reversed order. Doesn't pay attention to any changes in table.
+local
+function layersIterator (layers)
+ local i = layers.n + 1
+ return function ()
+ i = i - 1
+ return layers[i]
+ end
+end
+
+--- Layers in World may exists as two references. Every reference is stored inside `instance.layers`.
+-- First reference is indexed with number, it exists for every layer.
+-- Second reference is indexed with string, it exists only for selected layers.
+-- Mentioned special layers are initialized in this method.
+-- Additionally layer count is stored inside `instance.layers.n`.
+-- Layers are drawn in reverse order, meaning that `instance.layers[1]` will be on the top.
+-- Calling `instance.layers` will return iterator.
+function World:initLayers ()
+ self.layers = setmetatable({}, {__call = layersIterator})
+ self.layers.n = 0
+ do
+ local width, height = love.graphics.getWidth() / getScale(), love.graphics.getHeight() / getScale()
+ local rays = self:addLayer(width, height)
+ rays.transformScale = 1
+ rays.transformRatio = 0
+ rays.drawScale = getScale()
+ self.layers.rays = rays
+ end
+ do
+ local width, height = love.graphics.getDimensions()
+ self.layers.tags = self:addLayer(width, height)
+ self.layers.platforms = self:addLayer(width, height)
+ self.layers.effects = self:addLayer(width, height)
+ self.layers.heroes = self:addLayer(width, height)
+ self.layers.decorations = self:addLayer(width, height)
+ self.layers.clouds = self:addLayer(width, height)
+ end
+end
+
+-- TODO: Make collisions for category 3 more customizable or create new category for traps/area effects.
+local
+function createFlame (self, x, y, direction, timerIn, timerOut)
+ local trap = Trap(direction, x, y, self, "assets/decorations/205-flames.png")
+
+ trap.layer = self.layers.platforms
+
+ timerIn:register(trap.fadeIn, trap)
+ timerOut:register(trap.fadeOut, trap)
+
+ self:insertEntity(trap)
end
--- Load map from file
--- TODO: Change current map model to function-based one.
-function World:loadMap (name)
- local name = name or "default"
- local map = love.filesystem.load(string.format("config/maps/%s.lua", name))
- self.map = map()
- -- Platforms
- for _,platform in pairs(self.map.platforms) do
- self:createPlatform(platform.x, platform.y, platform.shape, platform.sprite, platform.animations)
- end
- -- Decorations
- for _,decoration in pairs(self.map.decorations) do
- self:createDecoration(decoration.x, decoration.y, decoration.sprite)
- end
- -- Background
- self.background = love.graphics.newImage(self.map.background)
- -- Clouds
- if self.map.clouds then
- for i=1,6 do
- self:randomizeCloud(false)
+local
+function getAnimations (a)
+ if type(a) == "string" then
+ return require("config.animations." .. a)
+ end
+ if type(a) == "table" then
+ return a
+ end
+end
+
+--- Builds map using one of tables frin config files located in `config/maps/` directory.
+-- TODO: Clean World@buildMap. Possibly explode into more methods.
+-- TODO: Move buildMap along with getAnimations to Factory.
+function World:buildMap ()
+ local width, height = love.graphics.getDimensions()
+
+ for _,op in pairs(self.map.create) do
+ if op.platform then
+ -- TODO: Merge configs imported from other files to currently processed element.
+ local config = love.filesystem.load(string.format("config/platforms/%s.lua", op.platform))()
+ local platform = Platform(config.animations, config.shape, op.x, op.y, self, config.sprite)
+ platform.layer = self.layers.platforms
+ self:insertEntity(platform)
+ end
+ if op.decoration or op.background then
+ local imagePath = op.decoration or op.background
+ local entity = Decoration(0, 0, self, imagePath)
+
+ local x, y = 0, 0
+ if op.x and op.y then
+ x = op.x
+ y = op.y
+ elseif op.animations then
+ entity:setAnimationsList(getAnimations(op.animations))
+ _,_,x,y = bg:getAnimation()[1]:getViewport()
+ bg:setPosition(x / -2, y / -2)
+ else
+ local image = love.graphics.newImage(imagePath)
+ x = image:getWidth() / -2
+ y = image:getHeight() / -2
+ end
+ entity:setPosition(x, y)
+
+ local layer = self.layers.decorations
+ if op.ratio then
+ layer = self:addLayer(width, height)
+ layer.transformRatio = op.ratio
+ if op.background then
+ layer.transformScale = getRealScale()
+ end
+ end
+ entity.layer = layer
+
+ self:insertEntity(entity)
+ end
+ if op.clouds then
+ local animations = getAnimations(op.animations)
+ local cg = CloudGenerator(op.clouds, animations, op.count, self)
+ if op.ratio then
+ cg.layer = self:addLayer(width, height)
+ cg.layer.transformRatio = op.ratio
+ end
+ self:insertEntity(cg)
+ cg:run(op.count, true)
+ end
+ -- TODO: Make flames and other traps more configurable through map config file.
+ if op.flames then
+ local timerIn = Timer(10)
+ local timerOut = Timer(5)
+
+ timerIn:register(timerOut.start, timerOut)
+ timerOut:register(timerIn.start, timerIn)
+
+ createFlame(self, -62, 16, "right", timerIn, timerOut)
+ createFlame(self, 63, 16, "left", timerIn, timerOut)
+
+ self:insertEntity(timerIn)
+ self:insertEntity(timerOut)
+ timerOut:start()
end
end
end
@@ -96,89 +197,107 @@ function World:getSpawnPosition ()
return self.map.respawns[n].x, self.map.respawns[n].y
end
--- Add new platform to the world
--- TODO: it would be nice if function parameters would be same as `not.Platform.new`.
-function World:createPlatform (x, y, polygon, sprite, animations)
- table.insert(self.Platforms, Platform(animations, polygon, x, y, self, sprite))
+function World:addLayer (width, height)
+ local layer = Layer(width, height)
+ local n = self.layers.n + 1
+ self.layers[n] = layer
+ self.layers.n = n
+ return layer
end
--- Add new naut to the world
--- TODO: separate two methods for `not.Hero` and `not.Player`.
+-- TODO: Standardize `create*` methods with corresponding constructors. Pay attention to both params' order and names.
function World:createNaut (x, y, name)
- local naut = Player(name, x, y, self)
- table.insert(self.Nauts, naut)
- return naut
-end
-
--- Add new decoration to the world
--- TODO: `not.World.create*` functions often have different naming for parameters. It is not ground-breaking but it makes reading code harder for no good reason.
-function World:createDecoration (x, y, sprite)
- table.insert(self.Decorations, Decoration(x, y, self, sprite))
+ local h = Player(name, x, y, self)
+ table.insert(self.entities, h)
+ h.layer = self.layers.heroes
+ return h
end
--- Add new cloud to the world
--- TODO: extend variables names to provide better readability.
--- TODO: follow new parameters in `not.Cloud.new` based on `not.Cloud.init`.
-function World:createCloud (x, y, t, v)
- table.insert(self.Clouds, Cloud(x, y, t, v, self))
+function World:createEffect (name, x, y)
+ local e = Effect(name, x, y, self)
+ table.insert(self.entities, e)
+ e.layer = self.layers.effects
+ return e
end
--- Randomize Cloud creation
-function World:randomizeCloud (outside)
- if outside == nil then
- outside = true
- else
- outside = outside
- end
- local x,y,t,v
- local m = self.map
- if outside then
- x = m.center_x-m.width*1.2+love.math.random(-50,20)
- else
- x = love.math.random(m.center_x-m.width/2,m.center_x+m.width/2)
- end
- y = love.math.random(m.center_y-m.height/2, m.center_y+m.height/2)
- t = love.math.random(1,3)
- v = love.math.random(8,18)
- self:createCloud(x, y, t, v)
+function World:createRay (naut)
+ local r = Ray(naut, self)
+ table.insert(self.entities, r)
+ r.layer = self.layers.rays
+ return r
end
--- Add an effect behind nauts
--- TODO: follow new parameters in `not.Effect.new` based on `not.Effect.init`.
--- TODO: along with `createRay` move this nearer reast of `create*` methods for readability.
-function World:createEffect (name, x, y)
- table.insert(self.Effects, Effect(name, x, y, self))
+function World:insertCloud (cloud)
+ table.insert(self.entities, cloud)
+ if not cloud.layer then
+ cloud.layer = self.layers.clouds
+ end
+ return cloud
end
--- Add a ray
-function World:createRay (naut)
- table.insert(self.Rays, Ray(naut, self))
+--- Verbose wrapper for inserting entities into entities table.
+-- @param entity entity to insert
+function World:insertEntity (entity)
+ if entity then
+ table.insert(self.entities, entity)
+ return entity
+ end
end
--- get Nauts functions
--- more than -1 lives
-function World:getNautsPlayable ()
- local nauts = {}
- for _,naut in pairs(self.Nauts) do
- if naut.lives > -1 then
- table.insert(nauts, naut)
+--- Searches entities for those which return true with filtering function.
+-- @param filter function with entity as parameter
+-- @return table containing results of search
+function World:getEntities (filter)
+ local result = {}
+ for _,entity in pairs(self.entities) do
+ if filter(entity) then
+ table.insert(result, entity)
end
end
- return nauts
+ return result
end
--- are alive
-function World:getNautsAlive ()
- local nauts = {}
- for _,naut in self.Nauts do
- if naut.isAlive then
- table.insert(nauts, naut)
+
+--- Counts entities returning true with filtering function.
+-- @param filter function with entity as parameter
+-- @return entity count
+function World:countEntities (filter)
+ local count = 0
+ for _,entity in pairs(self.entities) do
+ if filter(entity) then
+ count = count + 1
end
end
- return nauts
+ return count
+end
+
+function World:getCloudsCount ()
+ return self:countEntities(function (entity)
+ return entity:is(Cloud)
+ end)
end
--- all of them
+
+function World:getCloudsCountFrom (generator)
+ return self:countEntities(function (entity)
+ return entity:is(Cloud) and entity.generator == generator
+ end)
+end
+
function World:getNautsAll ()
- return self.Nauts
+ return self:getEntities(function (entity)
+ return entity:is(require("not.Hero")) and not entity.body:isDestroyed()
+ end)
+end
+
+function World:getNautsPlayable ()
+ return self:getEntities(function (entity)
+ return entity:is(require("not.Hero")) and entity.lives > -1
+ end)
+end
+
+function World:getNautsAlive ()
+ return self:getEntities(function (entity)
+ return entity:is(require("not.Hero")) and entity.isAlive
+ end)
end
-- get Map name
@@ -206,121 +325,63 @@ end
function World:update (dt)
self.world:update(dt)
self.camera:update(dt)
- -- Engine world: Nauts, Grounds (kek) and Decorations - all Animateds (top kek)
- for _,naut in pairs(self.Nauts) do
- naut:update(dt)
- end
- for _,platform in pairs(self.Platforms) do
- platform:update(dt)
- end
- for _,decoration in pairs(self.Decorations) do
- decoration:update(dt)
- end
- -- Clouds
- if self.map.clouds then
- -- generator
- local n = table.getn(self.Clouds)
- self.clouds_delay = self.clouds_delay - dt
- if self.clouds_delay < 0 and
- n < 18
- then
- self:randomizeCloud()
- self.clouds_delay = self.clouds_delay + World.clouds_delay -- World.clouds_delay is initial
- end
- -- movement
- for _,cloud in pairs(self.Clouds) do
- if cloud:update(dt) > 340 then
- table.remove(self.Clouds, _)
- end
- end
- end
- -- Effects
- for _,effect in pairs(self.Effects) do
- if effect:update(dt) then
- table.remove(self.Effects, _)
+
+ for key,entity in pairs(self.entities) do
+ if entity:update(dt) then
+ table.remove(self.entities, key):delete()
end
end
- -- Rays
- for _,ray in pairs(self.Rays) do
- if ray:update(dt) then
- table.remove(self.Rays, _)
- end
+
+ -- TODO: Possibly rename Camera@sum because this code part in World doesn't make sense without reading further.
+ self.camera:sum(self.map.center.x, self.map.center.y)
+ for _,hero in pairs(self:getNautsAll()) do
+ self.camera:sum(hero:getPosition())
end
+
+ -- Some additional debug info.
+ local stats = love.graphics.getStats()
+ dbg_msg = string.format("%sMap: %s\nClouds: %d\nLoaded: %d\nMB: %.2f", dbg_msg, self.map.filename, self:getCloudsCount(), stats.images, stats.texturememory / 1024 / 1024)
end
--- Draw
-function World:draw ()
- -- Camera stuff
- local offset_x, offset_y = self.camera:getOffsets()
- local scale = getScale()
- local scaler = getRealScale()
-
- -- Background
- love.graphics.draw(self.background, 0, 0, 0, scaler, scaler)
-
- -- TODO: this needs to be reworked!
- -- Draw clouds
- for _,cloud in pairs(self.Clouds) do
- cloud:draw(offset_x, offset_y, scale)
- end
- -- Draw decorations
- for _,decoration in pairs(self.Decorations) do
- decoration:draw(offset_x, offset_y, scale)
+function World:draw ()
+ for _,entity in pairs(self.entities) do
+ if entity.draw and entity.layer then
+ entity.layer:renderToWith(self.camera, entity.draw, entity, debug)
+ end
+ if entity.drawTag then
+ self.layers.tags:renderToWith(self.camera, entity.drawTag, entity, debug)
+ end
end
- -- Draw effects
- for _,effect in pairs(self.Effects) do
- effect:draw(offset_x,offset_y, scale)
+ for layer in self.layers() do
+ layer:draw()
+ layer:clear()
end
- -- Draw player
- for _,naut in pairs(self.Nauts) do
- naut:draw(offset_x, offset_y, scale, debug)
- end
+ -- TODO: Debug information could possibly get its own layer so it could follow flow of draw method.
+ if debug then
+ local center = self.map.center
+ local ax, ay, bx, by = self.camera:getBoundaries(getScale(), love.graphics.getDimensions())
- -- Draw ground
- for _,platform in pairs(self.Platforms) do
- platform:draw(offset_x, offset_y, scale, debug)
- end
+ love.graphics.setLineWidth(1 / getScale())
+ love.graphics.setLineStyle("rough")
- -- Draw rays
- for _,ray in pairs(self.Rays) do
- ray:draw(offset_x, offset_y, scale)
- end
+ self.camera:push()
+ self.camera:transform(getScale(), 1, love.graphics.getDimensions())
- -- draw center
- if debug then
- local c = self.camera
- local w, h = love.graphics.getWidth(), love.graphics.getHeight()
- -- draw map center
love.graphics.setColor(130,130,130)
- love.graphics.setLineWidth(1)
- love.graphics.setLineStyle("rough")
- local cx, cy = c:getPositionScaled()
- local x1, y1 = c:translatePosition(self.map.center_x, cy)
- local x2, y2 = c:translatePosition(self.map.center_x, cy+h)
- love.graphics.line(x1,y1,x2,y2)
- local x1, y1 = c:translatePosition(cx, self.map.center_y)
- local x2, y2 = c:translatePosition(cx+w, self.map.center_y)
- love.graphics.line(x1,y1,x2,y2)
- -- draw ox, oy
- love.graphics.setColor(200,200,200)
- love.graphics.setLineStyle("rough")
- local cx, cy = c:getPositionScaled()
- local x1, y1 = c:translatePosition(0, cy)
- local x2, y2 = c:translatePosition(0, cy+h)
- love.graphics.line(x1,y1,x2,y2)
- local x1, y1 = c:translatePosition(cx, 0)
- local x2, y2 = c:translatePosition(cx+w, 0)
- love.graphics.line(x1,y1,x2,y2)
- end
+ love.graphics.line(ax,center.y,bx,center.y)
+ love.graphics.line(center.x,ay,center.x,by)
- for _,naut in pairs(self.Nauts) do
- naut:drawTag(offset_x, offset_y, scale)
+ love.graphics.setColor(200,200,200)
+ love.graphics.line(ax,0,bx,0)
+ love.graphics.line(0,ay,0,by)
+ self.camera:pop()
end
-
- -- Draw HUDs
- for _,naut in pairs(self.Nauts) do
+
+ -- TODO: Draw method beyond this point is a very, very dark place (portraits drawing to review).
+ local scale = getScale()
+ for _,naut in pairs(self:getNautsAll()) do
-- I have no idea where to place them T_T
-- let's do: bottom-left, bottom-right, top-left, top-right
local w, h = love.graphics.getWidth()/scale, love.graphics.getHeight()/scale
@@ -330,15 +391,29 @@ function World:draw ()
end
end
--- Box2D callbacks
--- TODO: Rather than here, these contacts should be in `Hero` (most likely).
--- TODO: Explode these into more functions.\
--- TODO: Stop using magical numbers:
--- [1] -> Platform
--- [2] -> Hero
--- [3] -> Punch sensor
-function World.beginContact (a, b, coll)
- if a:getCategory() == 1 then
+--- Wraps World's beginContact and endContact to functions usable as callbacks for Box2D's world.
+-- Only difference in new functions is absence of self as first argument.
+-- @return wrapper for beginContact
+-- @return wrapper for endContact
+function World:getContactCallbacks ()
+ local b = function (a, b, coll)
+ self:beginContact(a, b, coll)
+ end
+ local e = function (a, b, coll)
+ self:endContact(a, b, coll)
+ end
+ return b, e
+end
+
+-- TODO: Move these constants to a proper place (I have no idea where proper place is).
+local COLL_HERO = 2
+local COLL_PLATFORM = 1
+local COLL_PUNCH = 3
+local COLL_TRAP = 4
+
+-- TODO: Review current state of both Box2D callbacks (again).
+function World:beginContact (a, b, coll)
+ if a:getCategory() == COLL_PLATFORM then
local x,y = coll:getNormal()
if y < -0.6 then
b:getUserData():land()
@@ -348,37 +423,49 @@ function World.beginContact (a, b, coll)
b:getUserData():playSound(3)
end
end
- if a:getCategory() == 3 then
- if b:getCategory() == 2 then
+ if a:getCategory() == COLL_PUNCH then
+ if b:getCategory() == COLL_HERO then
b:getUserData():damage(a:getUserData()[2])
end
- if b:getCategory() == 3 then
+ if b:getCategory() == COLL_PUNCH then
a:getBody():getUserData():damage(b:getUserData()[2])
b:getBody():getUserData():damage(a:getUserData()[2])
local x1,y1 = b:getBody():getUserData():getPosition()
local x2,y2 = a:getBody():getUserData():getPosition()
local x = (x2 - x1) / 2 + x1 - 12
local y = (y2 - y1) / 2 + y1 - 15
- a:getBody():getUserData().world:createEffect("clash", x, y)
+ self:createEffect("clash", x, y)
end
end
- if b:getCategory() == 3 then
- if a:getCategory() == 2 then
+ if b:getCategory() == COLL_PUNCH then
+ if a:getCategory() == COLL_HERO then
a:getUserData():damage(b:getUserData()[2])
end
end
+ if a:getCategory() == COLL_TRAP then
+ if b:getCategory() == COLL_HERO then
+ b:getUserData():damage(a:getUserData()[1])
+ end
+ end
+ if b:getCategory() == COLL_TRAP then
+ if a:getCategory() == COLL_HERO then
+ a:getUserData():damage(b:getUserData()[1])
+ end
+ end
end
-function World.endContact (a, b, coll)
- if a:getCategory() == 1 then
+
+function World:endContact (a, b, coll)
+ if a:getCategory() == COLL_PLATFORM then
b:getUserData().inAir = true
end
end
-- Controller callbacks
--- TODO: names of this methods don't follow naming patterns in this project. See `Controller` and change it.
function World:controlpressed (set, action, key)
if key == "f6" and debug then
- local map = self:getMapName()
+ local filename = self.map.filename
+ local map = love.filesystem.load(filename)()
+ map.filename = filename
local nauts = {}
for _,naut in pairs(self:getNautsAll()) do
table.insert(nauts, {naut.name, naut:getControllerSet()})