Closed cooperuser closed 8 years ago
Also, in case you were wondering, this is what the new .json
file format will look like:
{
"grid": {
"0": {
"0": {
"tile": {
"position": {
"x": 0,
"y": 0
},
"color": "white",
"passable": true,
"class": "StandardTile",
"objectType": "Tile"
}
},
"1": {
"tile": {
"position": {
"x": 0,
"y": 1
},
"color": "white",
"passable": true,
"class": "StandardTile",
"objectType": "Tile"
}
},
"2": {
"tile": {
"position": {
"x": 0,
"y": 2
},
"color": "white",
"passable": true,
"class": "StandardTile",
"objectType": "Tile"
},
"block": {
"position": {
"x": 0,
"y": 2
},
"color": "white",
"passable": false,
"velocity": {
"x": 0,
"y": 0
},
"moveable": true,
"class": "StandardBlock",
"objectType": "Block"
}
}
},
"1": {
"0": {
"tile": {
"position": {
"x": 1,
"y": 0
},
"color": "white",
"passable": true,
"class": "StandardTile",
"objectType": "Tile"
}
},
"1": {
"tile": {
"position": {
"x": 1,
"y": 1
},
"color": "white",
"passable": true,
"class": "StandardTile",
"objectType": "Tile"
},
"plate": {
"position": {
"x": 1,
"y": 1
},
"color": "white",
"passable": true,
"active": false,
"class": "StandardPlate",
"objectType": "Plate"
}
},
"2": {
"tile": {
"position": {
"x": 1,
"y": 2
},
"color": "white",
"passable": true,
"class": "StandardTile",
"objectType": "Tile"
}
}
},
"2": {
"0": {
"tile": {
"position": {
"x": 2,
"y": 0
},
"color": "white",
"passable": true,
"class": "StandardTile",
"objectType": "Tile"
}
},
"1": {
"tile": {
"position": {
"x": 2,
"y": 1
},
"color": "white",
"passable": true,
"class": "StandardTile",
"objectType": "Tile"
}
},
"2": {
"tile": {
"position": {
"x": 2,
"y": 2
},
"color": "white",
"passable": true,
"class": "StandardTile",
"objectType": "Tile"
}
}
}
},
"name": "Debug",
"creators": [
"Cooper Anderson"
],
"par": 0,
"flags": [],
"size": {
"x": 3,
"y": 3
}
}
My python program is broken. But I can explain the algorithm at least, which I'm pretty sure should work. The only problem with it is that for levels that take longer than about 15 moves, the algorithm takes exponentially longer to verify (so it's a lot better for small levels). Let me read over this new format and then I'll get to explaining it.
Ah, I see. Well either way, I'm sure that we will be able to make a sustainable algorithm that does this, and me "we" I mostly mean you, because you are the one who is good at that XD
Ok I need a few things explained about this new format. What is "passable"? And "velocity"?
Why are you storing these things in the raw level file? It's not like you're going to open a level, and a block is already going to be set to have velocity, and start moving right away without you touching anything. It seems like there's a ridiculous amount of unnecessary information in this file.
And have you been checking general discussion?
I need the class
and the objectType
variables for specific reasons, and the passable
variable lets me see if the block can go on the tile, (or board
the tile as I decided to call it in code). Having the velocity
vector is nice because then I don't have to create and delete the variable each time it is created.
But I think the way you store the JSON files should be different than the way you store the raw JS classes. Because you don't need to store EVERYTHING that you need in-game in the level file (like the velocity). Or else some people might go in and screw with those values making for some VERY strange levels.
And yes, I have been looking at the General Discussion, and by recreating the game, I will make this the default.
hahaha! I just realized if the change the velocity
from {x: 0, y: 0}
to {x: 1, y: 1}
it would move diagonally. wait.. no it wont, it only moves on click, and when you click it will reset the velocity
Ok, another thing I think is weird is the "color" attribute, since not all objects have a color, it's kind of strange to include this. What I think you should do is have a sort of item ID, something like Block.Standard.Green
or Wiring.Logic.XOR
.
Unless I do:
$(".block").on("click", function() {
if (click == "up") {
block.velocity.y = -1;
}
});
instead of:
$(".block").on("click", function() {
if (click == "up") {
block.velocity = new Vector2(0, -1);
}
});
oh... that Block.Standard.Green
way of doing things looks like a good way of doing it..... shit.
Also, look at how I am currently doing the Object
code for the Block
type
class Block {
constructor(position=new Vector2(), color="white") {
this.position = position;
this.color = color;
this.passable = false;
this.velocity = new Vector2();
this.moveable = true;
this.class = this.constructor.name;
this.objectType = "Block";
}
}
Block.CheckMove = function(block, grid) {
};
Block.Move = function (block, grid) {
var isPassable = function(gridSpace) {
var passable = [];
for (var key in gridSpace) {
passable.push(gridSpace[key].passable);
}
return !passable.includes(false);
};
var pos = block.position;
var dir = block.velocity;
var dest = new Vector2(pos.x + dir.x, pos.y + dir.y);
if (!(dir.x == 0 && dir.y == 0) && typeof grid[dest.x] != "undefined" && typeof grid[dest.x][dest.y] != "undefined" && isPassable(grid[dest.x][dest.y]) && typeof grid[dest.x][dest.y].tile != "undefined") {
eval(eval(`grid[dest.x][dest.y].tile.class`)).Depart(grid, dest);
}
while (true) {
if (!(dir.x == 0 && dir.y == 0) && typeof grid[dest.x] != "undefined" && typeof grid[dest.x][dest.y] != "undefined" && isPassable(grid[dest.x][dest.y]) && typeof grid[dest.x][dest.y].tile != "undefined") {
eval(eval(`grid[dest.x][dest.y].tile.class`)).Slide(grid, dest)
eval(`delete grid[pos.x][pos.y].${block.objectType.toLowerCase()}`);
eval(`grid[dest.x][dest.y].${block.objectType.toLowerCase()} = block`);
} else {
eval(eval(`grid[dest.x][dest.y].tile.class`)).Board(grid, dest)
break;
}
pos = dest;
dest = new Vector2(pos.x + dir.x, pos.y + dir.y);
}
return grid;
};
class StandardBlock extends Block {
constructor(position=new Vector2(), color="white") {
super(position, color);
}
}
class HollowBlock extends Block {
constructor(position=new Vector2()) {
super(position);
this.class = this.constructor.name;
}
}
module.exports = {Block, StandardBlock, HollowBlock};
This way, unless I need to override the .Move()
method, I don't have to reprogram it! Because I'm using subclasses
!
In fact, I think you should use those Item IDs for everything about an item except for its position (so that would include its rotation, initial state, etc.) so something like Wiring.Logic.XOR.LeftFacing.Enabled
. Or maybe if that's too weird, just have "flags" for each block the same way you have those for the entire level. Then you would have Wiring.Logic.XOR
with flags LeftFacing
and Enabled
. The reason I don't think you should have rotation as an attribute is because all blocks have different "spins" as you could call them, for example some might have no rotational symmetry, some might have 2-way, and most (like blocks and plates) would have 4-way rotational symmetry. So for the latter, you wouldn't want to set any rotation states, the middle would only have two states, and the former would have four.
Okay, but this will already be a thing we can do,
I don't oppose your idea about all variations being a subclass, I just need to think of a way of integrating it.
Oh wait oops, the XOR gate won't have an enabled/disabled state, my bad, but memory circuits will (T flip-flops, etc.) which will correspond to their initial state when the level starts.
Here's another idea, split the level into three different "layers", and in each layer no two objects would be able to occupy the same spot. Bottom layer would be board tiles, middle layer would be plates and switches, top layer would be blocks, teleporters, and gates (not logic gates). Wires are kind of weird for this system, since they kind of need to occupy both layer 2 (so they can interact with switches) and layer 3 (so they can interact with gates), but they can't fully occupy layer 3 or else blocks wouldn't be able to pass over them.
thats why I have the passable
variable, so I can have doors, or gates as you called them, open and close
Well the state of a gate wouldn't be stored in the JSON file, because it's an output block, and upon starting the level the gate would automatically assume the state of the wire being fed into its input.
why assume though?
And I guess calling them doors is a good idea, so we don't mix them up with logic gates (even though doors isn't quite the right word for them)
what if a block starts on a plate, powering the door?
"Assume" in that context means to take the role of
If a block starts on the switch (it's a switch, not a plate), then upon starting the level the game will realize that, and start feeding power into the wire, and then power the door
See general discussion, it's pretty important
Also did you see my pull request?
I see that you added me as the Assignees
of all of the issues,
Because for a couple of minutes, my notification manager was going crazy because it only allows 3-4 on the screen at once.
oh LMFAO why did it give you a different notification for each one? I did it all at once
bad design..?
I guess. Btw it's a lot less annoying without that cursor now, but could you remove the buttons completely? I think it would make it look a lot more streamlined.
(I think you put that in the wrong thread..)
Yeah, but you never seem to see things unless I put them in the thread we're currently talking in (due to GitHub's shitty notification system), so...
I have a separate notification system that seems to work well, the only issue is the update frequency, about once every 1-2 minutes
so I usually get to them
You going to remove those buttons?
did you see the image?
on #27
I don't think you should wait until this is finished before you reorganize the filesystem, I think the filesystem is more of a priority and once you do that, you can add a preferences.json file easily
See #6
How's the overhaul going?
Good, I might not implement it tonight though, still needs a lot of thinking
How long are you planning on staying up working on the game?
today, not much. I might go take my driving test tomorrow, so I kinda need sleep
Alright, think I'm gonna hit the sack too, so I guess I'll talk to you tomorrow
K see ya then
Progress!!!:
This recreation is a big requirement because this allows us to integrate new features with ease, as apposed to the old method.
Also, @grady404, can you link your
Python
code that solves for the amount of moves necessary please? I will be integrating that into this redone version.