- newWorld = {
-world = {
- Seed = 5345345,
- Layers = 2,
-
- -- This is run when the world is registered and not after,
- -- although it is possible to register materials later
++local newWorld = {
Register = function(self)
-
- -- TODO make world have global textures to speed up rendering
-
- self:registerMaterial("grass", {
- -- TODO combine both of these into 1
- texture = {
- file = "Assets/world.png",
- offset = { x = 0, y = 0 },
- size = { x = 64, y = 64 }
- },
- normal = {
- file = "Assets/world_normal.png",
- offset = { x = 0, y = 0 },
- size = { x = 64, y = 64 }
- }
+ self.unitSize = 8;
+ self:createLayer(0, {
+ texture = { file = "Assets/world/world1/layers/0/texture.png" },
+ normal = { file = "Assets/world/world1/layers/0/normal.png" },
+ hitbox = "Assets/world/world1/layers/0/hitbox.png"
});
- self:registerMaterial("dirt", {
- texture = {
- file = "Assets/world.png",
- offset = { x = 64, y = 0 },
- size = { x = 64, y = 64 }
- },
- normal = {
- file = "Assets/world_normal.png",
- offset = { x = 64, y = 0 },
- size = { x = 64, y = 64 }
- }
+ self:createLayer(1, {
+ texture = { file = "Assets/world/world1/layers/1/texture.png" },
+ normal = { file = "Assets/world/world1/layers/1/normal.png" },
+ hitbox = "Assets/world/world1/layers/1/hitbox.png"
});
- self:registerMaterial("stone", {
- texture = {
- file = "Assets/world.png",
- offset = { x = 128, y = 0 },
- size = { x = 64, y = 64 }
- },
- normal = {
- file = "Assets/world_normal.png",
- offset = { x = 128, y = 0 },
- size = { x = 64, y = 64 }
- }
+ self:createDecoLayer(7, {
+ texture = { file = "Assets/world/world1/layers/deco/forestTileBack.png" },
+ normal = { file = "Assets/world/world1/layers/deco/normal.png" },
});
- self:registerMaterial("flower", {
- texture = {
- file = "Assets/world.png",
- offset = { x = 192, y = 0 },
- size = { x = 64, y = 64 }
- },
- normal = {
- file = "Assets/world_normal.png",
- offset = { x = 192, y = 0 },
- size = { x = 64, y = 64 }
- },
- passable = true
+ self:createDecoLayer(5.5, {
+ texture = { file = "Assets/world/world1/layers/deco/forestTileMid.png" },
+ normal = { file = "Assets/world/world1/layers/deco/normal.png" },
});
- self:registerMaterial("trunk", {
- texture = {
- file = "Assets/world.png",
- offset = { x = 256, y = 0 },
- size = { x = 64, y = 64 }
- },
- normal = {
- file = "Assets/world_normal.png",
- offset = { x = 256, y = 0 },
- size = { x = 64, y = 64 }
- }
+ self:createDecoLayer(4, {
+ texture = { file = "Assets/world/world1/layers/deco/forestTileFront.png" },
+ normal = { file = "Assets/world/world1/layers/deco/normal.png" },
});
end,
-
Generate = function(self)
- math.randomseed(self.Seed)
- xsize, ysize, zsize = self:setSize(250, 128, 3)
- for Z = 0,zsize-1 do
- for X = 0,xsize-1 do
- if Z == 0 then
- YGen = math.floor(6*math.sin(X/20)) + 64
- elseif Z == 1 then
- YGen = math.floor(9*math.sin(X/20)) + 64
- else
- YGen = math.floor(15*math.sin(X/20)) + 64
- end
- YDepth = math.random(3,5)
- for Y = 0,ysize-1 do
- if Y == YGen then
- self:setData(X, Y, Z, "grass");
- elseif Y < YGen and Y > (YGen - YDepth) then
- self:setData(X, Y, Z, "dirt");
- elseif Y < YGen then
- self:setData(X, Y, Z, "stone");
- elseif Y == YGen + 1 then
- if math.random(0, 100) == 53 then
- self:setData(X, Y, Z, "flower");
- elseif math.random(0, 100) == 45 then
- self:setData(X, Y, Z, "trunk");
- end
- end
- --print(X..","..Y..","..Z);
- end
- end
- end
- --self:setData(1000, 1345, 5, "grass"); -- Test error checking
- print("Done with world gen");
end
}
/* PHYSICS */
double World::getHeight(double x, double y, double z)
{
- unsigned int X = static_cast<unsigned int>(x);
- unsigned int Z = static_cast<unsigned int>(z);
-
- double Y = 0.0;
- try {
- auto &d = data.at(Z).at(X);
- for (int yi = d.size()-1; yi >= 0; yi--) {
- if (d.at(yi) >= 0) {
- if (!registry.at(d.at(yi)).passable) {
- Y = static_cast<double>(yi);
- Y += 1;
- break;
+ (void)y;
+ double Y = 0.0f;
+ for (auto &l : solidLayers) {
+ if (z == l->drawLayer) {
+ int wx = x*unitSize;
+
+ int h = 0.0;
+ for (auto b : l->hitbox[wx]) {
+ if (b == true)
+ Y = h;
+ h++;
+ }
+ return ((Y+1)/unitSize);
+ }
+ }
+ return 0;
+}
+
+bool World::isSolid(glm::vec3 pos)
+{
+ for (auto &l : solidLayers) {
+ if (pos.z == l->drawLayer) {
+ int wx = pos.x * unitSize;
+ int wy = pos.y * unitSize;
+ if (wx < 0 || wy < 0) return true;
+
+ return l->hitbox[wx][wy];
+ }
+ }
+ return false;
+}
+
+std::vector<glm::vec3>
+World::getIntersectingPlanes(glm::vec3 origin, Physics &phys)
+{
+ std::vector<glm::vec3> planes;
+
+ glm::vec3 goal = origin;
+
+ origin.x += phys.corners[0].x;
+ origin.y += phys.corners[0].y;
+
+ goal.x += phys.corners[3].x;
+ goal.y += phys.corners[3].y;
+
+ float step = 1.0f/unitSize;
+ for (;origin.y <= goal.y; origin.y += step){
+ for (;origin.x <= goal.x; origin.x += step) {
+ if (isSolid(origin)) {
+ planes.push_back(origin);
+ }
+ }
+ }
+
+ return planes;
+}
+
+glm::vec3 World::collide(glm::vec3 &start, glm::vec3 &end, Physics &phys)
+{
+ // How far to push the entity to unintersect with the world
+ glm::vec3 push(0);
+ for (auto &l : solidLayers) {
+ if (start.z == l->drawLayer) {
+ glm::vec3 len = end-start;
+ glm::vec3 dir = glm::normalize(len);
+ float step = 1.0f/unitSize;
+
+ glm::vec3 pos = start;
+
+ for (float i = 0.0f; i < glm::length(len); i+=step, pos+=dir) {
+ // Get all colliding world spaces
+ std::vector<glm::vec3> inter = getIntersectingPlanes(pos, phys);
+
- if (i == 0.0f)
++ if (i == 0.0f) {
+ std::cout << inter.size() << std::endl;
++ if (inter.size()) {
++ p.standing = true;
++ }
++ }
+
+ // If there are no colliding world spaces, don't bother
+ if (inter.size()) {
+ if (dir.x > 0.0f) {
+ // Moving to the right
+ int closest = inter.at(0).x;
+ for (auto &p : inter) {
+ if (p.x < closest)
+ closest = p.x;
+ }
+ push.x -= abs(closest - (pos.x + phys.corners[1].x));
+
+ } else if (dir.x < 0.0f) {
+ // Moving to the left
+ int closest = inter.at(0).x;
+ for (auto &p : inter) {
+ if (p.x > closest)
+ closest = p.x;
+ }
+ push.x += abs(closest - (pos.x + phys.corners[0].x));
+ }
+
+ if (dir.y > 0.0f) {
+ // Moving upwards
+ int closest = inter.at(0).y;
+ for (auto &p : inter) {
+ if (p.y < closest)
+ closest = p.y;
+ }
+ push.y -= abs(closest - (pos.y + phys.corners[2].y));
+ } else if (dir.y < 0.0f) {
+ // Moving downwards
+ int closest = inter.at(0).y;
+ for (auto &p : inter) {
+ if (p.y > closest)
+ closest = p.y;
+ }
+ push.y += abs(closest - (pos.y + phys.corners[0].y));
+ }
+
+ if (push != glm::vec3(0.0f))
+ return pos + push;
}
}
}