Compare commits

..

20 commits

Author SHA1 Message Date
Kazhnuz
29137efd6a meta: import radiance settings 2021-11-25 10:29:55 +01:00
Kazhnuz
0e2a6ced4d Merge branch 'master' of https://git.chlore.net/game-projects/sonic-bluestreak 2020-06-04 22:38:34 +02:00
Kazhnuz
fa4964a877 feat: prepare badnics support 2020-06-04 19:37:34 +02:00
Kazhnuz
baa59db9c2 chore: separate the weapon system 2020-04-25 12:29:07 +02:00
Kazhnuz
a4a1bc94a3 feat: dumb test map system 2020-04-25 12:15:21 +02:00
Kazhnuz
318e297095 feat: basic weapon system 2020-04-25 12:15:12 +02:00
Kazhnuz
a7a0bde8ea feat: add basic autorun on shoot maps 2020-02-02 08:27:33 +01:00
Kazhnuz
93ce28f3ba fix: simplify shadows handling 2020-02-01 16:44:38 +01:00
Kazhnuz
89c5940116 improvement: optimise chunk system
Diminishe the number of chunks and floor generated. Level loading will 
be a bit slower, but we basically double fps on test level
2020-02-01 14:24:23 +01:00
Kazhnuz
759d0d24e0 feat: initial loading of mission files 2020-01-26 15:30:00 +01:00
Kazhnuz
5d46f54e99 chore: stop bypassing datas in test level 2020-01-26 12:32:36 +01:00
Kazhnuz
46c1a53f5e feat:initial addition of collectible actors 2020-01-26 12:28:53 +01:00
Kazhnuz
b4fcd33163 chore: add level collisions in a specific folder 2020-01-26 11:08:47 +01:00
Kazhnuz
37fb2c8b74 feat: add ring toss gfx 2020-01-26 10:57:20 +01:00
Kazhnuz
ae58ecd659 fix: better forest background 2020-01-25 20:32:03 +01:00
Kazhnuz
3d511358e1 feat: add worldmap concept 2020-01-21 09:51:32 +01:00
Kazhnuz
63dbac57fd feat: add floor collisions 2020-01-12 00:02:06 +01:00
Kazhnuz
9385d9deb9 chore: remove forgotten print 2020-01-04 11:14:13 +01:00
Kazhnuz
6bbd6e40f7 feat: add chunk loading to shoot maps 2020-01-03 19:41:30 +01:00
Kazhnuz
4aeab15340 feat: load map data from layout files 2020-01-02 21:56:42 +01:00
44 changed files with 722 additions and 133 deletions

21
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,21 @@
{
"Lua.diagnostics.globals": [
"love",
"unpack",
"loadstring",
"game",
"core",
"scenes",
"utils",
"birb",
"enum"
],
"Lua.runtime.version": "LuaJIT",
"Lua.workspace.library": [
"${3rd}/love2d/library"
],
"Lua.workspace.checkThirdParty": false,
"Lua.diagnostics.disable": [
"redundant-parameter"
]
}

View file

@ -2,19 +2,13 @@
## 1. Niveaux de Shadow Shoot
En bon jeu de flemmard, je reprend les 6 niveaux de Shadow Shoot :D Ces jeux serviront comme base aux jeux, et les niveaux supplémentaires à les améliorer.
### Jadeite Forest
Un premier niveau sylvestre mélangeant forêt et "GHZ-like" histoire d'éviter d'en avoir un.
**Gimmicks** : Hautes herbes (qui ralenti)
En bon jeu de flemmard, je reprend les 7 niveaux de Shadow Shoot :D Ces jeux serviront comme base aux jeux, et les niveaux supplémentaires à les améliorer.
### Diamound Highway
Un niveau de ville lumineuse et "joyeuse", à la manière de City Escape (ainsi que l'act 3/Knuckles de Speed Highway). Il représente une ville pleine d'énergie et de vitalité. Quelques éléments de villes "modernes" tel que des zones d'acceleration et de "retour en arrière" pourront être présent.
Un niveau de ville, à la manière de City Escape et Mission Street (ainsi que l'act 3/Knuckles de Speed Highway). Il représente une ville pleine d'énergie et de vitalité.
**Gimmicks** : Barre de grinds, zone d'acceleration, zone de "retour arrière".
**Gimmicks** : Barre de grinds
### Peridot Tunnel
@ -22,12 +16,25 @@ Un niveau de base sous-marine, à la manière de Ocean et Aquatic Bases (SAdv3 e
**Gimmicks** : Espace sous-marin(?)
### Jadeite Forest
Un niveau de forêt, à la manière de Green Forest. Sert de premier niveau dans le monde inspiré de Neo Sonic Boom.
**Gimmicks** : Hautes herbes (qui ralenti)
### Pearl Mountain
Un niveau de neige, à la manière de ceux qu'on trouve dans les Advances.
**Gimmicks** : Glace (le personnage glisse sur les côté), snowboard(?)
### Calcite Hill
Un niveau de collines vertes, à la manière de Green Hill Zone.
**Gimmicks** : Eau
### Carnelian Bridge
Un nouveau de pont/route, à la manière de Radical et Speed Highway de SA et SA2. Aura quelques inspirations aussi de Starlight Zone.
@ -36,18 +43,12 @@ Un nouveau de pont/route, à la manière de Radical et Speed Highway de SA et SA
### Ametist Castle
Le niveau hanté du jeu, sera ici plus un chateau avec quelques éléments de niveaux de "lave" : visiblement ce chateau hanté de Eggman est construit sur un volcan. Heureusement qu'il est génie du mal et pas promoteur immobilié...
Le niveau de ruine du jeu, sera ici plus un chateau que des ruines "classic". Aura tout l'attirail des ruines : les trucs qui se cassent sous vos pieds, etc.
**Gimmicks** : Fantômes, Grilles d'où sort du feu, boules de piques, lave.
**Gimmicks** : Colonne (obstacle haut, indestructible), sol qui s'effondre
## 2. Niveaux supplémentaires
Le but des niveaux complémentaires va être de contenir les tropes qui ne sont pas présents dans les niveaux de bases du jeu. Il y aura 6+1 niveaux, pour atteindre un total de 12 niveaux principaux, plus 1 "special" (Crystal Realm).
### Olivine Coast
Un immense pont au dessus de l'eau, inspiré aussi bien d'Emerald Coast que de Bridge Zone.
**Gimmicks** : Eau
Le but des niveaux complémentaires va être de contenir les tropes qui ne sont pas présents dans les niveaux de bases du jeu. Il y aura 9 niveaux, pour atteindre un total de 16 niveaux (4×4 pour le mode "tournois).
### Zircon Desert
@ -61,17 +62,23 @@ Une base d'Eggman classic, à la Secret Base, Chemical Plant.
**Gimmicks** :
### Moonstone Relics
### Silicon Matrix
Un niveau de ruines/canyon venteux, à la manière de Windy Valley, Angel Island et Sky Canyon. Aura également tout l'attirail des ruines : les trucs qui se cassent sous vos pieds, etc.
Un niveau numérique, à la manière de Mad Matrix, Digital Circuit, Cyber Track and Techno Base.
**Gimmicks** : Vents (ralentissant ou poussant tout les ennemis, s'activent ou se désactivent avec des boutons), ventilateurs sur le sol, colonne (obstacle haut, indestructible), sol qui s'effondre
**Gimmicks** :
### Obsidian Gadgets
### Moonstone Canyon
Une centrale chaotique, avec des éléments inspirés aussi bien du Death Egg et de l'ARK que de niveaux "numériques" à la manière de Mad Matrix, Digital Circuit, Cyber Track and Techno Base.
Un niveau de ruines/canyon venteux, à la manière de Windy Valley, Angel Island et Sky Canyon.
**Gimmicks** : Liquide drainant la vie (corruption), laser, etc.
**Gimmicks** : Vents (ralentissant ou poussant tout les ennemis, s'activent ou se désactivent avec des boutons), ventilateurs sur le sol
### Obsidian Station
Une station spatiale, à la manière du Death Egg et de l'ARK.
**Gimmicks** :
### Agate Park
@ -79,26 +86,39 @@ Un park/cirque/casino. Mélange des éléments des trois dans un éclat d'amusem
**Gimmicks** : Jetons de Bingo/Série de 5 trucs à avoir
### Crystal Realm
### Garnet Crater
Une route "hors de ce monde", pleine de lumière et d'énergie. Inspirée de la [Milky Way](https://www.youtube.com/watch?v=JhI9H_S85WE), des niveaux espaces des jeux Sonic et de la special zone. Peut avoir aussi bien un background abstrait qu'un type "dans l'espace".
De la lave. Du magma. Un peu comme Hot Crater et tout les niveaux du genre.
**Gimmicks** : Astéroides de couleurs différentes avec différents effets, blue/red sphere (en mode special stage)
**Gimmicks** : Magma
## Correspondance de niveaux (mode classique/Boom)
- Niveau 1 : **Jadeite Forest** / **Olivine Coast**
- Niveau 2 : **Graphite Mechanics** / **Diamound Highway**
- Niveau 3 : **Agate Park**
- Niveau 4 : **Zircon Desert** / **Pearl Mountain**
- Niveau 5 : **Carnelian Bridge**
- Niveau 6 : **Moonstone Relics** / **Peridot Tunnel**
- Niveau 7 : **Obsidian Gadgets** / **Amethist Castle**
- Niveau Bonus : **Crystal Realm**
### Lithium Metropolis
La ville moderne "lumineuse", à la manière de Grand Metropolis et Monopole. Aura quelques inspirations aussi de Metropolis de Sonic Forces. Ce sera une ville blanche, de lumière.
**Gimmicks** :
### Crystal Cosmos
Une route dans l'espace, pleine de lumière et d'énergie. Inspirée de la [Milky Way](https://www.youtube.com/watch?v=JhI9H_S85WE) et des niveaux espaces des jeux Sonic.
**Gimmicks** : Astéroides de couleurs différentes avec différents effets
## Correspondance de niveaux (mode classique)
- Niveau 1 : **Jadeite Forest** / **Calcite Hill**
- Niveau 2 : **Diamound Highway** / **Citrine Park**
- Niveau 3 : **Peridot Tunnel** / **Zircon Desert**
- Niveau 4 : **Pearl Mountain** / **Carnelian Bridge**
- Niveau 5 : **Graphit Mechanics** / **Moonstone Canyon**
- Niveau 6 : **Garnet Crater** / **Silicon Matrix**
- Niveau 7 : **Obsidian Station** / **Ametist Castle**
- Niveau Bonus : **Crystal Cosmos**
## Coupes (mode tournoi)
- Chao Cup : **Jadeite Forest 1** - **Olivine Coast 1** - **Agate Park** - **Zircon Desert**
- Ring Cup : **Diamound Highway** - **Jadeite Forest 2** - **Olivine Coast 2** - **Graphit Mechanics**
- Emerald Cup : **Pearl Mountain** - **Carnelian Bridge** - **Moonstone Relic 1** - **Ametist Castle**
- Master Cup : **Peridot Tunnel** - **Moonstone Relic 2** - **Obsidian Gadget** - **Crystal Cosmos**
- Chao Cup : Calcite Hill - ????? - ????? - ?????
- Ring Cup : ????? - ????? - ????? - ?????
- Emerald Cup : ????? - ????? - ????? - ?????
- Master Cup : ????? - ????? - ????? - **Crystal Cosmos**

View file

@ -19,6 +19,7 @@ Le but est de pouvoir proposer plusieurs types d'objectif
- Arènes (Sonic Battle)
- Map Tiled
- Mode Tornado ? (Shooter 2D + classique... Peut-être le hardcoder comme un truc totalement différent)
- World Map ? (grande map avec vue de plus loin, où on pourrait booster librement à travers une map à la Adventure of Link, avec combat aléatoire, endroit caché, grand lieux, etc)
## "Effet de niveaux" ?

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View file

@ -0,0 +1,18 @@
return {
metadata = {
height = 24,
width = 32,
defaultAnim = "default",
oy = 12,
ox = 20,
},
animations = {
["default"] = {
startAt = 1,
endAt = 2,
loop = 1,
speed = 20,
pauseAtEnd = false,
},
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 B

View file

@ -0,0 +1,16 @@
return {
metadata = {
height = 16,
width = 16,
defaultAnim = "default"
},
animations = {
["default"] = {
startAt = 1,
endAt = 8,
loop = 1,
speed = 8,
pauseAtEnd = false,
},
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View file

@ -164,7 +164,7 @@ function VirtualPad:checkKey(key)
self.keys[key].isReleased = false
else
if (self.keys[key].isPressed) then
core.debug:print("virtualpad", "key " .. key .. " is Down")
--core.debug:print("virtualpad", "key " .. key .. " is Down")
self.keys[key].isPressed = false
end
end

View file

@ -218,7 +218,10 @@ end
-- Handle everything related to shadow
function Actor3D:castShadow()
local shadowTargets = self.world:getTerrainInRect(self.x, self.y, self.w, self.d)
local SHADOW_CAST_AREA = 12
local xshad, yshad = self.x-(SHADOW_CAST_AREA), self.y-(SHADOW_CAST_AREA)
local wshad, dshad = self.w+(SHADOW_CAST_AREA*2), self.d+(SHADOW_CAST_AREA*2)
local shadowTargets = self.world:getTerrainInRect(xshad, yshad, wshad, dshad)
-- initialize the shadowTargetsPrevious variable if it doesn't exist
if (self.shadowTargetsPrevious == nil) then
self.shadowTargetsPrevious = {}

View file

@ -45,7 +45,7 @@ function OptionsManager:reset()
self.data.video.crtfilter = false
self.data.video.resolution = 2
self.data.video.border = true
self.data.video.vsync = true
self.data.video.vsync = false
self.data.video.fullscreen = false
-- We load the default files

View file

@ -0,0 +1,14 @@
return {
datas = {
zone = "forest",
bypass_zone = true,
bypass_data = {
tiles = nil,
background = nil
}
},
layout = {{"self", {00}}, {"basics", {00, 00}},},
parts = {
[0] = { {"basics", {01}}, {"basics", {00}}, }
}
}

View file

@ -0,0 +1,6 @@
return {
description="Test the world",
music="1-01- Beyond The Speed Of.mp3",
maptype="shoot",
map="testlevel.test1",
}

View file

@ -0,0 +1,20 @@
return {
[1] = {
name = "basic",
launch = {{0, 0, 0}},
zspeed = 0,
xspeed = 360,
color = {1, 1, 1},
explode = false,
bounce = false,
},
[2] = {
name = "fire",
launch = {{0, 0, 0}},
zspeed = 360,
xspeed = 360,
color = {1, 0.2, 0.2},
explode = false,
bounce = false,
},
}

View file

@ -1,26 +0,0 @@
return {
datas = {
zone = "forest",
bypass_zone = false,
bypass_data = {
name = nil,
borders = 3,
tiles = 3,
background = nil,
music = nil
},
missiondata = {
leveltype = "loop",
missiontype = "goal",
turns = 4
}
},
layout = {{"self", {00}}, {"basics", {00, 00}},},
parts = {
[0] = {{"basics", {01}}, {"basics", {00}}}
},
endless_parts = {
{"basics", 00},
{"self", 00}
}
}

View file

@ -11,6 +11,7 @@ function Frame:draw()
utils.graphics.resetColor()
love.graphics.draw(self.guiborder, 424, 20, 0, -1, -1)
love.graphics.draw(self.guiborder2, 424, 220, 0, 1, 1, 424, 0)
love.graphics.print(love.timer.getFPS(), 200, 8)
end
return Frame

View file

@ -8,7 +8,9 @@ return {
{"hudring", "assets/gui/hud/ring.png"}
},
["sprites"] = {
{"ring", "assets/sprites/items/ring"}
{"ring", "assets/sprites/items/ring"},
{"ringweapon", "assets/sprites/items/ringweapon"},
{"ringtoss", "assets/sprites/items/ringtoss"}
},
["imagefonts"] = {
{"menu", "assets/gui/fonts/SA2font"},
@ -21,6 +23,7 @@ return {
{"cancel", "assets/sfx/menu/cancel.wav"},
},
["tilesets"] = {
{"weapons", "assets/gui/status/weapons"}
{"weapons", "assets/gui/status/weapons"},
{"sptiles", "assets/backgrounds/specialtile"}
}
}

View file

@ -5,12 +5,13 @@ local PauseMenu = require("game.modules.playstyle.pause")
local TestWorld = require("game.modules.world.parent")
function PlayStyle:new(playerList)
function PlayStyle:new(supportedLevels, missionfile, playerList)
local playerList = playerList or {"sonic"}
PlayStyle.super.new(self)
self.timer = 0
self.assets:batchImport("game.modules.playstyle.assets")
self:loadMissionFile(supportedLevels, missionfile)
PauseMenu(self)
@ -21,6 +22,11 @@ function PlayStyle:new(playerList)
self:startLevel()
end
function PlayStyle:loadMissionFile(supportedLevels, missionfile)
self.mission = require("datas.gamedata.missions." .. missionfile)
self.assets:setMusic("assets/music/" .. self.mission.music)
end
function PlayStyle:initWorld()
TestWorld(self)
end
@ -73,6 +79,7 @@ end
function PlayStyle:startLevel()
self.world:loadMap()
self.assets:playMusic()
end
function PlayStyle:restartLevel()

View file

@ -0,0 +1,29 @@
local Base = require "core.modules.world.actors.actor3D"
local FakeFloor = Base:extend()
function FakeFloor:new(world, x, y, z, w, h, d)
FakeFloor.super.new(self, world, "fakefloor", x, y, z, w, h, d, false)
self:setDebugColor(0,0,0)
self.boxes.Base(self, w, h, d, false)
end
function FakeFloor:update(dt)
end
function FakeFloor:draw()
local drawx, drawy, drawz = self.x, self.y, self.z
if (self.world.maptype == "shoot") then
drawx = drawx + math.floor(drawy/2)
end
self:drawStart()
if (self.box ~= nil) then
self.box:draw(drawx, drawy, drawz)
else
local x, y = math.floor(drawx), math.floor(drawy - drawz - self.d + (self.h/2))
self:drawSprite(x, y)
end
self:drawEnd()
end
return FakeFloor

View file

@ -0,0 +1,29 @@
local Base = require "core.modules.world.actors.actor3D"
local Floor = Base:extend()
function Floor:new(world, x, y, z, w, h, d)
Floor.super.new(self, world, "wall", x, y, z, w, h, d, true)
self:setDebugColor(0,0,0)
self.boxes.Base(self, w, h, d, false)
end
function Floor:update(dt)
end
function Floor:draw()
local drawx, drawy, drawz = self.x, self.y, self.z
if (self.world.maptype == "shoot") then
drawx = drawx + math.floor(drawy/2)
end
self:drawStart()
if (self.box ~= nil) then
self.box:draw(drawx, drawy, drawz)
else
local x, y = math.floor(drawx), math.floor(drawy - drawz - self.d + (self.h/2))
self:drawSprite(x, y)
end
self:drawEnd()
end
return Floor

View file

@ -0,0 +1,6 @@
local Parent = require "game.modules.world.actors.ennemies.parent"
local Motobug = Parent:extend()
return Motobug

View file

@ -0,0 +1,18 @@
local Parent = require "game.modules.world.actors.parent"
local EnnemyParent = Parent:extend()
function EnnemyParent:new(world, x, y, z, w, h, d)
EnnemyParent.super.new(self, world, "ennemy", x, y, z, w, h, d, true)
end
function EnnemyParent:getHurt(hp)
if (self.hp <= hp) then
self:die()
else
self.hp = self.hp - hp;
end
end
function EnnemyParent:die()
self:destroy()
end

View file

@ -1,14 +0,0 @@
local Base = require "core.modules.world.actors.actor3D"
local Floor = Base:extend()
function Floor:new(world, x, y, z, w, h, d)
Floor.super.new(self, world, "wall", x, y, z, w, h, d, true)
self:setDebugColor(0,0,0)
self.boxes.Base(self, w, h, d, false)
end
function Floor:update(dt)
end
return Floor

View file

@ -3,14 +3,21 @@ local Obj = {}
-- On charge toutes les différentes types d'acteurs
local cwd = (...):gsub('%.init$', '') .. "."
Obj.Player = require(cwd .. "player")
Obj.Ring = require(cwd .. "items.ring")
Obj.Weapon = require(cwd .. "weapons.parent")
Obj.index = {}
Obj.index["player"] = Obj.Player
Obj.collisions = {}
Obj.collisions["wall"] = require(cwd .. "wall")
Obj.collisions["invisible"] = require(cwd .. "invisible")
Obj.collisions["floor"] = require(cwd .. "floor")
Obj.collisions["textured"] = require(cwd .. "textured")
Obj.collisions["wall"] = require(cwd .. "collisions.wall")
Obj.collisions["invisible"] = require(cwd .. "collisions.invisible")
Obj.collisions["floor"] = require(cwd .. "collisions.floor")
Obj.collisions["textured"] = require(cwd .. "collisions.textured")
Obj.collisions["fakefloor"] = require(cwd .. "collisions.fakefloor")
Obj.index = {}
Obj.index[01] = Obj.Ring
Obj.index[02] = Obj.Ring
return Obj

View file

@ -0,0 +1,12 @@
local Parent = require "game.modules.world.actors.parent"
local Collectible = Parent:extend()
function Collectible:new(world, x, y, z, w, h, d)
Collectible.super.new(self, world, "collectible", x, y, z, w, h, d, false)
end
function Collectible:getPicked(player)
self:destroy()
end
return Collectible

View file

@ -0,0 +1,17 @@
local cwd = (...):gsub('%.ring$', '') .. "."
local Collectible = require(cwd .. "collectible")
local Ring = Collectible:extend()
function Ring:new(world, x, y, z)
Ring.super.new(self, world, x, y, z+6, 16, 10, 16)
self:setSprite("ring", 0, 0)
end
function Ring:getPicked(player)
player:setRing(1, true)
player:setScore(10, true)
self:destroy()
end
return Ring

View file

@ -16,7 +16,13 @@ function Parent:draw()
self.box:draw(drawx, drawy, drawz)
else
local x, y = math.floor(drawx), math.floor(drawy - drawz - self.d + (self.h/2))
self:drawSprite(x, y)
if (math.floor(drawz) < -2) and (self.world.maptype == "shoot") then
core.screen:setScissor(0, 0, 424, 58+drawy/2)
self:drawSprite(x, y)
core.screen:resetScissor()
else
self:drawSprite(x, y)
end
end
self:drawEnd()
end

View file

@ -5,15 +5,22 @@ local Player = Parent:extend()
local Frame = require("game.modules.gui.frame")
local Statusbar = require("game.modules.gui.status")
local Weapons = require(cwd .. "player.weapons")
function Player:new(world, x, y, z, id)
Player.super.new(self, world, "player", x, y, 0, 16, 12, 24, true)
Player.super.new(self, world, "player", x, y, 0, 16, 16, 24, false)
self:setGravity(480*2)
self:init(id)
self.frame = Frame()
self.weapons = Weapons(self)
self.action = "normal"
self.rings = 0
self.score = 0
end
function Player:init(id)
@ -22,31 +29,46 @@ function Player:init(id)
self:setSprite(self.charName, 8, 10)
self:cloneSprite()
self.statusbar = Statusbar(self, "speed", 50)
self.statusbar:setWeapon(2)
end
function Player:updateStart(dt)
self.xfrc, self.yfrc = 480*3, 480*3
self:basicMovements()
if self.keys["A"].isPressed and (self.onGround) then
self.zsp = 280*1.33
end
if self.keys["B"].isPressed then
self.weapons:shoot(self.x, self.y+1, self.z+8, 1)
end
end
function Player:basicMovements()
if self.keys["up"].isDown then
self.ysp = -160
end
if self.keys["down"].isDown then
self.ysp = 160
end
if self.keys["left"].isDown then
self.xsp = -160
end
if self.keys["right"].isDown then
self.xsp = 160
if (self.world.autorun == true) then
self.xsp = 160
else
if self.keys["left"].isDown then
self.xsp = -160
end
if self.keys["right"].isDown then
self.xsp = 160
end
end
if self.keys["A"].isPressed and (self.onGround) then
self.zsp = 280*1.33
end
end
if self.keys["B"].isPressed and (self.onGround) then
-- Nothing for the moment
function Player:collisionResponse(collision)
if collision.other.type == "collectible" then
collision.other.owner:getPicked(self)
end
end
@ -104,4 +126,19 @@ function Player:drawHUD(id)
self.statusbar:draw(8, 12)
end
function Player:setRing(value, isRelative)
if (isRelative == false) then
self.rings = 0
end
self.rings = self.rings + value
self.statusbar.rings = self.rings
end
function Player:setScore(value, isRelative)
if (isRelative == false) then
self.score = 0
end
self.score = self.score + value
end
return Player

View file

@ -0,0 +1,25 @@
local WeaponManager = Object:extend()
local weaponList = require("datas.gamedata.weapons")
function WeaponManager:new(player)
self.player = player
self:switch(1)
end
function WeaponManager:switch(newWeapon)
if (weaponList[newWeapon] ~= nil) then
self.currentWeapon = newWeapon;
self.player.statusbar:setWeapon(self.currentWeapon);
end
end
function WeaponManager:shoot(x, y, z, dir)
weaponData = weaponList[self.currentWeapon]
for i,coord in ipairs(weaponData.launch) do
self.player.obj.Weapon(self.player.world, x + coord[1], y + coord[2], z + coord[3], dir, weaponData)
end
end
return WeaponManager

View file

@ -0,0 +1,33 @@
local Parent = require "game.modules.world.actors.parent"
local WeaponShot = Parent:extend()
function WeaponShot:new(world, x, y, z, direction, data)
WeaponShot.super.new(self, world, "shot", x, y, z, 16, 8, 16, false)
self:setSprite("ringweapon", 0, 0)
self.direction = direction
self.data = data
self.zsp = self.data.zspeed
self.xsp = self.data.xspeed * direction
self.xfrc, self.yfrc = 0, 0
if (self.zsp ~= 0) then
self:setGravity(480*2)
end
end
function WeaponShot:updateStart(dt)
if (self.xsp == 0) then
self:destroy()
end
end
function WeaponShot:draw()
love.graphics.setColor(self.data.color[1], self.data.color[2], self.data.color[3], 1)
WeaponShot.super.draw(self)
love.graphics.setColor(self.data.color[1], self.data.color[2], self.data.color[3], 0.6)
local x, y = self.x + self.y/2 + 8, self.y - self.z - 3
local angle = utils.math.pointDirection(0, 0, self.xsp, self.zsp * -1)
self.scene.assets.sprites["ringtoss"]:drawAnimation(x, y, angle)
love.graphics.setColor(1, 1, 1, 1)
end
return WeaponShot

View file

@ -6,18 +6,130 @@ local TESTZONE = "forest"
local zoneDatas = require "datas.gamedata.maps.shoot.zones"
local Chunk = require "game.modules.world.maps.tools.chunk"
function ShootMap:new(world, maptype, mapname)
ShootMap.super.new(self, world)
self:setPadding(0, 0, 0, 0)
self.textureId = zoneDatas[mapname].tiles
self.background = zoneDatas[mapname].background
self:generateTextures(self.textureId, self.background)
self:getLevelData(mapname)
self:generateTextures(self.datas.tiles, self.datas.background)
self.layout = {}
self.chunklist = {}
self.width = 0
end
function ShootMap:updateWidth()
self.size = #self.layout * 8
self.width = self.size * 31
end
function ShootMap:getLevelData(mapname)
local file = file or "testlevel.test1"
local level = require("datas.gamedata.maps.shoot." .. file)
self.zone = level.datas.zone
local currentZone_datas = zoneDatas[self.zone]
local bypass_data = level.datas.bypass_data
self.datas = {}
if (level.datas.bypass_zone) then
self.datas.tiles = bypass_data.tiles or currentZone_datas.tiles
self.datas.background = bypass_data.background or currentZone_datas.background
else
self.datas = currentZone_datas
end
self.datas.layout = level.layout
self.datas.parts = level.parts
end
function ShootMap:loadCollisions()
self:loadLayout();
local w, h = self:getDimensions()
self.world:newCollision("floor", 0, 0, -16, w, h, 16)
--self.world:newCollision("floor", 0, 0, -16, w, h, 16)
for i, chunkname in ipairs(self.layout) do
self.chunklist[chunkname]:spawnGrounds((i-1)*31*8)
self.chunklist[chunkname]:spawnObjects((i-1)*31*8)
end
local CHUNKSIZE = TILESIZE*8
self.world:newCollision("fakefloor", -CHUNKSIZE, 0, -48, self.width+CHUNKSIZE*2, 200, 48)
end
function ShootMap:loadLayout()
self.layout = {}
-- [ShootMap].datas.layout est un tableau composée d'une série de tableau,
-- chacuns en deux partie : le premier (part[1]) contient le nom du fichier
-- où se trouve des partie de niveau, et la seconde partie (part[2]) une liste
-- d'identifiant de partie de niveau à rajouter.
-- Ce format permet de simplifier l'écriture de layout, si on a besoin de
-- plusieur partie de niveau se trouvant dans le même fichier.
for i, partContainer in ipairs(self.datas.layout) do
for j, part in ipairs(partContainer[2]) do
self:addPart(partContainer[1], part)
end
end
end
function ShootMap:addPart(source, partId)
local source = source or "self"
local partdata = {}
-- On recupère les données de chunks
-- Si le nom est "self", cela veut dire que fichier est le même que celui ou
-- se trouve le layout, qui est forcément le fichier du niveau. Cela veut dire
-- qu'il faut utiliser les parties de niveau du niveau actuel, localisée dans
-- self.controller.parts
if (source == "self") or (source == "") then
partdata = self.datas.parts
else
-- Si c'est un autre nom, on charge dans "partdata" la liste des partie de niveau
-- du fichier qu'on réfère.
local chunkfile = require("datas.gamedata.maps.shoot.chunks." .. source)
partdata = chunkfile.parts
end
local chunklist = partdata[partId]
-- chunklist fonctionne de la même manière que partlist.
-- chaque entrée dans la liste (chunkContainer) contient deux partie :
-- chunkContainer[1]: l'identifiant du fichier où se trouve le chunk voulu
-- chunkContainer[2]: la liste de chunks voulu. chaque entrée dedans est
-- un nombre correspondant à un chunk
for i, chunkContainer in ipairs(chunklist) do
for j, chunk in ipairs(chunkContainer[2]) do
self:addChunk(source, chunkContainer[1], chunk)
end
end
end
function ShootMap:addChunk(source, filename, chunkid)
local filename = filename or "self"
if (filename == "self") or (filename == "") then
filename = source
end
local chunkfile = require("datas.gamedata.maps.shoot.chunks." .. filename)
local chunkdata = chunkfile.chunks
local chunkpos = #self.layout
local chunkname = filename .. chunkid
if self.chunklist[chunkname] == nil then
self.chunklist[chunkname] = Chunk(self, chunkdata[chunkid])
end
table.insert(self.layout, chunkname)
self:updateWidth()
end
function ShootMap:getChunk(id)
return self.chunklist[self.layout[id]]
end
function ShootMap:addBlock(x, y, w, h, top, bottom)
@ -25,7 +137,7 @@ function ShootMap:addBlock(x, y, w, h, top, bottom)
end
function ShootMap:getDimensions()
return 3000, 100
return self.width, 100
end
function ShootMap:loadPlayers()
@ -78,10 +190,8 @@ function ShootMap:generateFloor(tile)
return texture
end
function ShootMap:draw()
for i=1, 10 do
--love.graphics.draw(self.texture.floor, ((i-1)*31*16), 0)
end
function ShootMap:draw(x, y, w, h)
self:drawChunks(x)
end
function ShootMap:addParallax(filename)
@ -141,5 +251,17 @@ function ShootMap:drawCliff(x, y, w, h)
end
end
function ShootMap:drawChunks(x)
local x = x or 0
local firstChunk = math.floor(x / (8*31)) - 2
for i=1, 6 do
local chunkID = firstChunk + i
local chunk = self:getChunk(chunkID)
if (chunk ~= nil) then
chunk:draw((chunkID-1) * (8*31))
end
end
end
return ShootMap

View file

@ -3,21 +3,18 @@ local TestMap = BaseMap:extend()
function TestMap:new(world)
TestMap.super.new(self, world)
self:setPadding(0, 96, 0, 0)
--self:setPadding(0, 0, 0, 0)
self.background = love.graphics.newImage("assets/backgrounds/parallax/test-back.png")
self.background = love.graphics.newImage("assets/backgrounds/dumbtestmap.png")
end
function TestMap:loadCollisions()
self.world:newCollision("wall", 0, 0, -16, 8*64, 8*32, 16)
self.world:newCollision("wall", 64*1, 32*1, 0, 64*1, 32*3, 48)
self.world:newCollision("wall", 64*4, 32*1, 0, 64*3, 32*1, 48)
self.world:newCollision("wall", 64*6, 32*4, 0, 64*1, 32*3, 48)
self.world:newCollision("wall", 64*1, 32*6, 0, 64*3, 32*1, 48)
local w, h = self:getDimensions()
self.world:newCollision("floor", 0, 0, -16, w, h, 16)
end
function TestMap:getDimensions()
return 8*64, 8*32
return self.background:getDimensions()
end
function TestMap:loadPlayers()
@ -30,19 +27,20 @@ end
function TestMap:draw()
-- Empty Placeholder function
love.graphics.draw(self.background, 0, 0)
end
function TestMap:drawParallax(x, y, w, h)
local imax, jmax = (w/32)+1, (h/32)+1
local x, y = x or 0, y or 0
local x = math.floor(x/4) % 32
local y = math.floor((y+96)/6) % 32
for i=0, math.ceil(imax) do
for j=0, math.ceil(jmax) do
love.graphics.draw(self.background, (i-1)*32-x, (j-1)*32-y)
end
end
-- local imax, jmax = (w/32)+1, (h/32)+1
-- local x, y = x or 0, y or 0
-- local x = math.floor(x/4) % 32
-- local y = math.floor((y+96)/6) % 32
--
-- for i=0, math.ceil(imax) do
-- for j=0, math.ceil(jmax) do
-- love.graphics.draw(self.background, (i-1)*32-x, (j-1)*32-y)
-- end
-- end
end
return TestMap

View file

@ -0,0 +1,133 @@
local Chunk = Object:extend()
local ChunkTerrain = require "game.modules.world.maps.tools.chunkterrain"
function Chunk:new(map, data)
self.map = map
self.data = data
self.grounds = {}
self.areGroundsPrepared = false
end
function Chunk:getFakeData()
local fakedata = {}
local emptyline = {00, 00, 00, 00, 00, 00, 00, 00}
fakedata.objects = {emptyline, emptyline, emptyline, emptyline, emptyline}
fakedata.terrain = {emptyline, emptyline, emptyline, emptyline, emptyline}
fakedata.grind = {emptyline, emptyline, emptyline, emptyline, emptyline}
return fakedata, false
end
function Chunk:update(dt)
end
function Chunk:spawnGrounds(x)
if (self.areGroundsPrepared == false) then
self:prepareGround()
end
self:generateGround(x)
end
function Chunk:prepareGround()
for i=1, 5 do
for j=1, 8 do
if (self.data.terrain[i][j] ~= 3) and (self:haveNoGround(j, i)) then
self:calculateGround(j, i)
--self.map.world:newCollision("floor", x+(j-1)*31, (i-1)*20, -48, 31, 20, 48)
end
end
end
self.areGroundsPrepared = true
end
function Chunk:generateGround(basex)
for i, ground in ipairs(self.grounds) do
local x, y = ground.x, ground.y
local w, h = ground.w, ground.h
self.map.world:newCollision("invisible", basex+(x-1)*31, (y-1)*20, -48, 31*w, 20*h, 48)
end
end
function Chunk:haveNoGround(x, y)
for i, ground in ipairs(self.grounds) do
if ground:isInside(x, y) then
return false
end
end
return true
end
function Chunk:addGround(x, y, w, h)
table.insert(self.grounds,ChunkTerrain(x, y, w, h))
end
function Chunk:calculateGround(x, y)
local groundHeight = 1
local groundWidth = 1
local maxHeight = 5-y
local maxWidth = 8-x
-- Creation de la première ligne
local lineEmpty = true
for i=0, maxWidth do
if self:testTerrain(x + i, y) and (lineEmpty) then
groundWidth = i + 1
else
lineEmpty = false
end
end
-- Pour optimiser, on commence à la seconde ligne cette boucle
for i=1, maxHeight do
lineEmpty = true
for j=0, (groundWidth-1) do
if self:testTerrain(x + j, y + i) == false then
lineEmpty = false
end
end
if (lineEmpty) then
groundHeight = i + 1
else
break
end
end
self:addGround(x, y, groundWidth, groundHeight)
end
function Chunk:testTerrain(x, y)
return (self.data.terrain[y][x] ~= 3) and (self:haveNoGround(x, y))
end
function Chunk:spawnObjects(x)
for i=1, 5 do
for j=1, 8 do
local id = self.data.objects[i][j]
if (id ~= 0) then
self.map.world:newObjFromIndex(id, x+(j-1)*31+12, (i-1)*20, 0)
end
end
end
end
function Chunk:draw(x)
for i=1, 5 do
for j=1, 8 do
if (self.data.terrain[i][j] ~= 0) then
local tiley = (i-1)*20
local tilex = x + (j-1)*31 + (i-1)*10
local tileid = self.data.terrain[i][j]
self:drawTile(tilex, tiley, tileid)
end
end
end
end
function Chunk:drawTile(x, y, type)
self.map.world.scene.assets.tileset["sptiles"]:drawTile(type, x, y)
end
return Chunk

View file

@ -0,0 +1,14 @@
local ChunkTerrain = Object:extend()
function ChunkTerrain:new(x, y, w, h)
self.x = x
self.y = y
self.w = w
self.h = h
end
function ChunkTerrain:isInside(x, y)
return ((x >= self.x) and (x < self.x+self.w) and (y >= self.y) and (y < self.y+self.h))
end
return ChunkTerrain

View file

@ -10,6 +10,7 @@ function ParentWorld:new(scene, maptype, mapname)
ParentWorld.super.new(self, scene, "game.modules.world.actors", mappath, maptype)
self.mapname = mapname
self.autorun = false
end
function ParentWorld:createMapController()
@ -21,6 +22,10 @@ function ParentWorld:loadMapObjects()
self:addInvisibleWalls()
end
function ParentWorld:newObjFromIndex(id, x, y, z)
self.obj.index[id](self, x, y, z)
end
function ParentWorld:addInvisibleWalls()
local w, h = self:getDimensions()
print(w, h)
@ -52,6 +57,13 @@ function ParentWorld:draw(dt)
end
end
function ParentWorld:drawMap(i)
local x, y, w, h = self.cameras:getViewCoordinate(i)
if (self.map ~= nil) then
self.map:draw(x, y, w, h)
end
end
function ParentWorld:drawParallax(i)
local x, y, w, h = self.cameras:getViewCoordinate(i)
if (self.map ~= nil) and (self.maptype ~= "sti") then

View file

@ -8,6 +8,7 @@ function ShootWorld:new(scene, mapname)
ShootWorld.super.new(self, scene, "shoot", mapname)
self.mapname = mapname
self.autorun = true
end
function ShootWorld:getViewCenter(x, y)

View file

@ -29,13 +29,13 @@ local ShootWorld = require "game.modules.world.shoot"
local BattleWorld = require "game.modules.world.battle"
function MovePlayer:new()
MovePlayer.super.new(self, {"sonic"})
MovePlayer.super.new(self, {"shoot", "test", "battle"}, "testmissions", {"sonic"})
end
function MovePlayer:initWorld()
--ShootWorld(self, "coast")
ShootWorld(self, "testlevel.test1")
--BattleWorld(self, "ebeach")
TestWorld(self)
--TestWorld(self)
end
return MovePlayer