planet-wars/backend/static/script/mapbuilder.js

211 lines
37 KiB
JavaScript
Raw Normal View History

2020-03-27 09:31:56 +00:00
{
var parameters = new Array(0);
var size = 0;
const COLOURS = ["gray", "blue", "cyan", "green", "yellow", "orange", "red", "pink", "purple"];
const fields = {};
["owner", "name", "shipCount", "currentName", "currentShipCount", "mapName"].forEach(id => fields[id] = document.getElementById(id));
const capFirst = (string) => {
return string.charAt(0).toUpperCase() + string.slice(1);
}
const getRandomInt = (min, max) => {
return Math.floor(Math.random() * (max - min)) + min;
}
const generateName = () => {
var name1 = ["abandoned", "able", "absolute", "adorable", "adventurous", "academic", "acceptable", "acclaimed", "accomplished", "accurate", "aching", "acidic", "acrobatic", "active", "actual", "adept", "admirable", "admired", "adolescent", "adorable", "adored", "advanced", "afraid", "affectionate", "aged", "aggravating", "aggressive", "agile", "agitated", "agonizing", "agreeable", "ajar", "alarmed", "alarming", "alert", "alienated", "alive", "all", "altruistic", "amazing", "ambitious", "ample", "amused", "amusing", "anchored", "ancient", "angelic", "angry", "anguished", "animated", "annual", "another", "antique", "anxious", "any", "apprehensive", "appropriate", "apt", "arctic", "arid", "aromatic", "artistic", "ashamed", "assured", "astonishing", "athletic", "attached", "attentive", "attractive", "austere", "authentic", "authorized", "automatic", "avaricious", "average", "aware", "awesome", "awful", "awkward", "babyish", "bad", "back", "baggy", "bare", "barren", "basic", "beautiful", "belated", "beloved", "beneficial", "better", "best", "bewitched", "big", "big-hearted", "biodegradable", "bite-sized", "bitter", "black", "black-and-white", "bland", "blank", "blaring", "bleak", "blind", "blissful", "blond", "blue", "blushing", "bogus", "boiling", "bold", "bony", "boring", "bossy", "both", "bouncy", "bountiful", "bowed", "brave", "breakable", "brief", "bright", "brilliant", "brisk", "broken", "bronze", "brown", "bruised", "bubbly", "bulky", "bumpy", "buoyant", "burdensome", "burly", "bustling", "busy", "buttery", "buzzing", "calculating", "calm", "candid", "canine", "capital", "carefree", "careful", "careless", "caring", "cautious", "cavernous", "celebrated", "charming", "cheap", "cheerful", "cheery", "chief", "chilly", "chubby", "circular", "classic", "clean", "clear", "clear-cut", "clever", "close", "closed", "cloudy", "clueless", "clumsy", "cluttered", "coarse", "cold", "colorful", "colorless", "colossal", "comfortable", "common", "compassionate", "competent", "complete", "complex", "complicated", "composed", "concerned", "concrete", "confused", "conscious", "considerate", "constant", "content", "conventional", "cooked", "cool", "cooperative", "coordinated", "corny", "corrupt", "costly", "courageous", "courteous", "crafty", "crazy", "creamy", "creative", "creepy", "criminal", "crisp", "critical", "crooked", "crowded", "cruel", "crushing", "cuddly", "cultivated", "cultured", "cumbersome", "curly", "curvy", "cute", "cylindrical", "damaged", "damp", "dangerous", "dapper", "daring", "darling", "dark", "dazzling", "dead", "deadly", "deafening", "dear", "dearest", "decent", "decimal", "decisive", "deep", "defenseless", "defensive", "defiant", "deficient", "definite", "definitive", "delayed", "delectable", "delicious", "delightful", "delirious", "demanding", "dense", "dental", "dependable", "dependent", "descriptive", "deserted", "detailed", "determined", "devoted", "different", "difficult", "digital", "diligent", "dim", "dimpled", "dimwitted", "direct", "disastrous", "discrete", "disfigured", "disgusting", "disloyal", "dismal", "distant", "downright", "dreary", "dirty", "disguised", "dishonest", "dismal", "distant", "distinct", "distorted", "dizzy", "dopey", "doting", "double", "downright", "drab", "drafty", "dramatic", "dreary", "droopy", "dry", "dual", "dull", "dutiful", "each", "eager", "earnest", "early", "easy", "easy-going", "ecstatic", "edible", "educated", "elaborate", "elastic", "elated", "elderly", "electric", "elegant", "elementary", "elliptical", "embarrassed", "embellished", "eminent", "emotional", "empty", "enchanted", "enchanting", "energetic", "enlightened", "enormous", "enraged", "entire", "envious", "equal", "equatorial", "essential", "esteemed", "ethical", "euphoric", "even", "evergreen", "everlasting", "every", "evil", "exalted", "excellent", "exemplary", "exhausted", "excitable", "excited", "exciting", "exotic", "expensive", "experienced", "expert", "extraneous", "extroverted", "extra-large", "extra-small", "fabulous", "failing", "faint", "fair", "faithful", "fake", "false", "familiar", "famous", "
var name2 = ["people", "history", "way", "art", "world", "information", "map", "family", "government", "health", "system", "computer", "meat", "year", "thanks", "music", "person", "reading", "method", "data", "food", "understanding", "theory", "law", "bird", "literature", "problem", "software", "control", "knowledge", "power", "ability", "economics", "love", "internet", "television", "science", "library", "nature", "fact", "product", "idea", "temperature", "investment", "area", "society", "activity", "story", "industry", "media", "thing", "oven", "community", "definition", "safety", "quality", "development", "language", "management", "player", "variety", "video", "week", "security", "country", "exam", "movie", "organization", "equipment", "physics", "analysis", "policy", "series", "thought", "basis", "boyfriend", "direction", "strategy", "technology", "army", "camera", "freedom", "paper", "environment", "child", "instance", "month", "truth", "marketing", "university", "writing", "article", "department", "difference", "goal", "news", "audience", "fishing", "growth", "income", "marriage", "user", "combination", "failure", "meaning", "medicine", "philosophy", "teacher", "communication", "night", "chemistry", "disease", "disk", "energy", "nation", "road", "role", "soup", "advertising", "location", "success", "addition", "apartment", "education", "math", "moment", "painting", "politics", "attention", "decision", "event", "property", "shopping", "student", "wood", "competition", "distribution", "entertainment", "office", "population", "president", "unit", "category", "cigarette", "context", "introduction", "opportunity", "performance", "driver", "flight", "length", "magazine", "newspaper", "relationship", "teaching", "cell", "dealer", "debate", "finding", "lake", "member", "message", "phone", "scene", "appearance", "association", "concept", "customer", "death", "discussion", "housing", "inflation", "insurance", "mood", "woman", "advice", "blood", "effort", "expression", "importance", "opinion", "payment", "reality", "responsibility", "situation", "skill", "statement", "wealth", "application", "city", "county", "depth", "estate", "foundation", "grandmother", "heart", "perspective", "photo", "recipe", "studio", "topic", "collection", "depression", "imagination", "passion", "percentage", "resource", "setting", "ad", "agency", "college", "connection", "criticism", "debt", "description", "memory", "patience", "secretary", "solution", "administration", "aspect", "attitude", "director", "personality", "psychology", "recommendation", "response", "selection", "storage", "version", "alcohol", "argument", "complaint", "contract", "emphasis", "highway", "loss", "membership", "possession", "preparation", "steak", "union", "agreement", "cancer", "currency", "employment", "engineering", "entry", "interaction", "limit", "mixture", "preference", "region", "republic", "seat", "tradition", "virus", "actor", "classroom", "delivery", "device", "difficulty", "drama", "election", "engine", "football", "guidance", "hotel", "match", "owner", "priority", "protection", "suggestion", "tension", "variation", "anxiety", "atmosphere", "awareness", "bread", "climate", "comparison", "confusion", "construction", "elevator", "emotion", "employee", "employer", "guest", "height", "leadership", "mall", "manager", "operation", "recording", "respect", "sample", "transportation", "boring", "charity", "cousin", "disaster", "editor", "efficiency", "excitement", "extent", "feedback", "guitar", "homework", "leader", "mom", "outcome", "permission", "presentation", "promotion", "reflection", "refrigerator", "resolution", "revenue", "session", "singer", "tennis", "basket", "bonus", "cabinet", "childhood", "church", "clothes", "coffee", "dinner", "drawing", "hair", "hearing", "initiative", "judgment", "lab", "measurement", "mode", "mud", "orange", "poetry", "police", "possibility", "procedure", "queen", "ratio", "relation", "restaurant", "satisfaction", "sector", "signature", "significance", "song", "tooth", "town", "vehicle", "volume", "wife", "accident", "airport"
var name = capFirst(name1[getRandomInt(0, name1.length + 1)]) + ' ' + capFirst(name2[getRandomInt(0, name2.length + 1)]);
return name;
}
const constructMap = () => {
const planets = [];
for (let i in parameters) {
for (let j in parameters[i]) {
if (parameters[i][j]) {
let r_i = parseFloat(i);
let r_j = parseFloat(j);
if (r_i % 2 == 1) {
r_j += 0.5;
}
// const real_j = j % 2 == 1 ? j + 0.5 : j;
// const real_j = j % 2 == 1 ? j + 0.5 : j;
planets.push({
"name": parameters[i][j]["name"],
"ship_count": parseInt(parameters[i][j]["shipCount"]),
"owner": parameters[i][j]["colour"],
"x": r_j,
"y": r_i
});
}
}
}
return { "planets": planets };
}
const init = () => {
createGrid(20);
createColourButtons();
document.querySelector(".amountOfSquares").addEventListener(`change`, handleChangeAmountOfSquares);
document.querySelector(".confirm").addEventListener(`click`, handleConfirmButton);
document.querySelector(".clear").addEventListener(`click`, handleClearButton);
}
const handleClearButton = () => {
parameters = new Array(0);
createGrid(size);
}
const handleConfirmButton = () => {
const name = fields["mapName"].value;
if (!name) {
console.log("No name!");
return; // Errored
}
const obj = { "name": name, "map": constructMap() };
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
console.log(this);
// TODO: make response visible
};
xhr.open("POST", "/maps");
xhr.send(JSON.stringify(obj));
}
const createGrid = amount => {
size = amount;
// Extend the parameters array
parameters = parameters.slice(0, size);
parameters.push.apply(parameters, Array.from(new Array(size - parameters.length), _ => []));
for (let i in parameters) {
parameters[i] = parameters[i].slice(0, size);
parameters[i].push.apply(parameters[i], new Array(size - parameters[i].length));
}
$grid = document.querySelector(".grid");
$grid.innerHTML = "";
for (row = 0; row < amount; row++) {
$row = document.createElement('div');
$row.classList.add("row");
if (row % 2 != 0) {
$row.style.marginLeft = (50 / amount) + "%";
$row.style.marginRight = (-50 / amount) + "%";
}
$row.style.height = (100 / amount) + "%";
$row.classList.add("row_" + row);
for (col = 0; col < amount; col++) {
const square = createSquare(col, row, amount);
if (parameters[row][col]) {
// Set square as before
const colour = parameters[row][col]["colour"];
square.classList.add("planet_" + COLOURS[colour]);
}
$row.append(square);
}
$grid.append($row);
}
}
const createSquare = (col, row, amount) => {
$square = document.createElement('div');
$square.classList.add("square");
$square.classList.add("square-" + row + "-" + col);
$square.style.width = (100 / amount) + "%";
$square.addEventListener(`click`, handleSquareClick);
$square.addEventListener(`mouseover`, handleSquareHover);
return ($square);
}
const updateSquare = (element, i, j, colour, data) => {
if (!parameters[i][j]) {
parameters[i][j] = {};
}
Object.assign(parameters[i][j], data);
// Cannot shortcut with || operate, 0 is falsy
const prev_colour = parameters[i][j].hasOwnProperty("colour") ? parameters[i][j]["colour"] : -1;
if (prev_colour === colour) {
element.classList.remove("planet_" + COLOURS[colour]);
parameters[i][j] = undefined;
} else {
element.classList.remove("planet_" + prev_colour < 0 ? "" : COLOURS[parseInt(prev_colour)]);
element.classList.add("planet_" + COLOURS[colour]);
parameters[i][j]["colour"] = colour;
}
}
const handleSquareClick = e => {
document.querySelectorAll(".colourButton").forEach(colour => {
if (colour.checked) {
$name = e.currentTarget.classList[1];
const [i, j] = $name.split("-").slice(1);
const data = {
"shipCount": fields["currentShipCount"].checkValidity() ? fields["currentShipCount"].value : 0,
"name": fields["currentName"].value || generateName(),
};
updateSquare(e.currentTarget, i, j, parseInt(colour.value), data);
const event = new Event('mouseover');
e.currentTarget.dispatchEvent(event);
}
});
}
const handleSquareHover = e => {
$name = e.currentTarget.classList[1];
const [i, j] = $name.split("-").slice(1);
const obj = parameters[i][j] || {};
fields["name"].value = obj["name"] || "";
fields["shipCount"].value = obj["shipCount"] || "";
fields["owner"].value = obj.hasOwnProperty("colour") ? obj["colour"] : "";
}
const createColourButtons = () => {
const colourSecectors = [];
COLOURS.forEach((colour, i) => {
$colourButtonWrapper = document.querySelector(".colourButtonWrapper");
$button = document.createElement("input");
if (i === 0) $button.checked = true;
$button.name = "colourButton";
$button.classList.add("colourButton");
$button.type = "radio";
$button.value = i;
colourSecectors.push($button);
$checkmark = document.createElement("span");
$checkmark.classList.add("colourButtonCheckmark");
$checkmark.classList.add("colourButton_" + colour);
$container = document.createElement("label");
$container.classList.add("colourButtonContainer");
$container.append($button);
$container.append($checkmark);
$colourButtonWrapper.append($container);
})
document.addEventListener("keyup", (e) => {
var key = event.key || event.keyCode;
try {
colourSecectors[parseInt(key) - 1].checked = true;
} catch (_) {}
});
}
const handleChangeAmountOfSquares = e => {
if (e.currentTarget.checkValidity()) {
createGrid(e.currentTarget.value);
}
}
init();
}