From 111115bfdca858ef1f5614bd40b28b707d6c372d Mon Sep 17 00:00:00 2001 From: Eliastik <26941242+Eliastik@users.noreply.github.com> Date: Fri, 31 Jan 2020 23:07:29 +0100 Subject: [PATCH] Version 1.5 --- README.md | 25 +++++++++++++++----- assets/css/main.css | 2 +- assets/js/main.js | 35 ++++++++++++++++------------ assets/js/src/constants.js | 4 ++-- assets/js/src/gameUI.js | 6 ++++- assets/js/src/notificationMessage.js | 18 +++++++++----- assets/locales/engine.js | 2 +- assets/locales/init.js | 2 +- assets/locales/menu.js | 6 +++-- index.html | 10 ++++++-- package.json | 2 +- service-worker.js | 29 ++++++++++++++++++----- 12 files changed, 97 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index f74d593..3306f94 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Game written in pure JavaScript and object oriented. ## About this game -* Version: 1.4.2 +* Version: 1.5 * Made in France by Eliastik - [eliastiksofts.com](http://eliastiksofts.com) - Contact : [eliastiksofts.com/contact](http://eliastiksofts.com/contact) * License: GNU GPLv3 (see LICENCE.txt file) @@ -27,6 +27,12 @@ Game written in pure JavaScript and object oriented. ## Changelog +* Version 1.5 (1/31/2020) : + - Performance improvement (multi-threading); + - Fixed speed management: the game is smoother; + - Major changes in the architecture of the game code (MVC, other changes); + - Bug fixes and other adjustments. + * Version 1.4.2 (10/7/2019) : - Added a labyrinth mode: it's now possible to generate mazes. The goal is to find the path to the apple through the maze. Levels of this type are also possible (to download later). - Bug fixes and other adjustments. @@ -115,7 +121,7 @@ Jeu programmé en JavaScript pur et en orienté objet. ## À propos du jeu -* Version du jeu : 1.4.2 +* Version du jeu : 1.5 * Made in France by Eliastik - [eliastiksofts.com](http://eliastiksofts.com) - Contact : [eliastiksofts.com/contact](http://eliastiksofts.com/contact) * Licence : GNU GPLv3 (voir le fichier LICENCE.txt) @@ -130,6 +136,12 @@ Jeu programmé en JavaScript pur et en orienté objet. ## Journal des changements +* Version 1.5 (31/01/2020) : + - Amélioration des performances (multi-threading) ; + - Correction de la gestion de la vitesse : le jeu est plus fluide ; + - Grands changements dans l'architecture du code du jeu (MVC, autres changements) ; + - Corrections de bugs et autres ajustements. + * Version 1.4.2 (07/10/2019) : - Ajout d'un mode labyrinthe : il est désormais possible de générer des labyrinthes. Le but est de trouver le chemin vers la pomme à travers le labyrinthe. Des niveaux de ce type sont également possibles (à télécharger ultérieurement). - Corrections de bugs et autres ajustements. @@ -211,11 +223,10 @@ Jeu programmé en JavaScript pur et en orienté objet. ### À faire (ou idées) : +* Jeu multi-joueur en ligne (création d'un programme serveur avec socket.io) * Améliorer l'IA pour l'empêcher de se bloquer -> plus long chemin si bloqué * Bonus dans le mode niveaux (pièces obtenues en fonction du score/temps (1.75 fois ce qui est demandé dans l'objectif) permettant d'acheter des bonus (passer dernier niveau ou activer le mode assistant IA)) * (Afficher difficulté niveaux) -* (?) Nouveau type niveau avec le contrôle de plusieurs Snake joueurs (prit correctement en compte par le jeu) -* (Architecture client-serveur) ### Fait : @@ -226,6 +237,8 @@ Jeu programmé en JavaScript pur et en orienté objet. * hue-rotate ne fonctionne pas sur Microsoft Edge et Safari -> pas de changement de couleur des Snake possible (workaround trouvé avec le Snake pointé par la flèche + détection et texte différent) * Animations * Labyrinthes +* Multithreading +* MVC (architecture client-serveur) ### Problèmes : @@ -233,7 +246,7 @@ Jeu programmé en JavaScript pur et en orienté objet. ## Déclaration de licence -Copyright (C) 2019 Eliastik (eliastiksofts.com) +Copyright (C) 2019-2020 Eliastik (eliastiksofts.com) Ce programme est un logiciel libre ; vous pouvez le redistribuer ou le modifier suivant les termes de la GNU General Public License telle que publiée par la Free Software Foundation ; soit la version 3 de la licence, soit (à votre gré) toute version ultérieure. @@ -243,7 +256,7 @@ Vous devez avoir reçu une copie de la GNU General Public License en même temps ---- -Copyright (C) 2019 Eliastik (eliastiksofts.com) +Copyright (C) 2019-2020 Eliastik (eliastiksofts.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. diff --git a/assets/css/main.css b/assets/css/main.css index 92702bf..78f2804 100644 --- a/assets/css/main.css +++ b/assets/css/main.css @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Eliastik (eliastiksofts.com) + * Copyright (C) 2019-2020 Eliastik (eliastiksofts.com) * * This file is part of "SnakeIA". * diff --git a/assets/js/main.js b/assets/js/main.js index ec63032..d6492e1 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Eliastik (eliastiksofts.com) + * Copyright (C) 2019-2020 Eliastik (eliastiksofts.com) * * This file is part of "SnakeIA". * @@ -66,6 +66,7 @@ SOLO_PLAYER_DOWNLOAD_LEVELS_TO = "snakeia_solo_player_downloadedLevels"; SOLO_AI_DOWNLOAD_LEVELS_TO = "snakeia_solo_ai_downloadedLevels"; var selectedMode = SOLO_AI; +var enableAnimations = true; var showDebugInfo = false; document.getElementById("versionTxt").innerHTML = APP_VERSION; @@ -73,6 +74,10 @@ document.getElementById("appVersion").innerHTML = APP_VERSION; document.getElementById("dateTxt").innerHTML = DATE_VERSION; document.getElementById("appUpdateDate").innerHTML = DATE_VERSION; +document.getElementById("enableAnimations").onchange = function() { + enableAnimations = this.checked; +}; + // Libs String.prototype.strcmp = function(str) { return ((this == str) ? 0 : ((this > str) ? 1 : -1)); @@ -721,25 +726,25 @@ function validateSettings(returnValidation) { var grid = new Grid(widthGrid, heightGrid, generateWalls, borderWalls, mazeGrid); var snake = new Snake(RIGHT, 3, grid, PLAYER_AI, aiLevel, autoRetry); - games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed)); + games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed, null, null, null, null, !enableAnimations)); } else if(selectedMode == SOLO_PLAYER) { var grid = new Grid(widthGrid, heightGrid, generateWalls, borderWalls, mazeGrid); var snake = new Snake(RIGHT, 3, grid, playerHumanType); - games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed)); + games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed, null, null, null, null, !enableAnimations)); } else if(selectedMode == PLAYER_VS_AI) { var grid = new Grid(widthGrid, heightGrid, generateWalls, borderWalls); var snake = new Snake(RIGHT, 3, grid, playerHumanType); if(sameGrid) { var snake2 = new Snake(RIGHT, 3, grid, PLAYER_AI, aiLevel, autoRetry); - games.push(new Game(grid, [snake, snake2], speed, document.getElementById("gameContainer"), true, true, progressiveSpeed)); + games.push(new Game(grid, [snake, snake2], speed, document.getElementById("gameContainer"), true, true, progressiveSpeed, null, null, null, null, !enableAnimations)); } else { var grid2 = new Grid(widthGrid, heightGrid, generateWalls, borderWalls); var snake2 = new Snake(RIGHT, 3, grid2, PLAYER_AI, aiLevel, autoRetry); - games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, false, progressiveSpeed)); - games.push(new Game(grid2, snake2, speed, document.getElementById("gameContainer"), false, false, progressiveSpeed)); + games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, false, progressiveSpeed, null, null, null, null, !enableAnimations)); + games.push(new Game(grid2, snake2, speed, document.getElementById("gameContainer"), false, false, progressiveSpeed, null, null, null, null, !enableAnimations)); } } else if(selectedMode == AI_VS_AI) { var grid = new Grid(widthGrid, heightGrid, generateWalls, borderWalls); @@ -747,13 +752,13 @@ function validateSettings(returnValidation) { if(sameGrid) { var snake2 = new Snake(RIGHT, 3, grid, PLAYER_AI, aiLevel, autoRetry); - games.push(new Game(grid, [snake, snake2], speed, document.getElementById("gameContainer"), true, true, progressiveSpeed)); + games.push(new Game(grid, [snake, snake2], speed, document.getElementById("gameContainer"), true, true, progressiveSpeed, null, null, null, null, !enableAnimations)); } else { var grid2 = new Grid(widthGrid, heightGrid, generateWalls, borderWalls); var snake2 = new Snake(RIGHT, 3, grid2, PLAYER_AI, aiLevel, autoRetry); - games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed)); - games.push(new Game(grid2, snake2, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed)); + games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed, null, null, null, null, !enableAnimations)); + games.push(new Game(grid2, snake2, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed, null, null, null, null, !enableAnimations)); } } else if(selectedMode == BATTLE_ROYALE) { if(sameGrid) { @@ -768,20 +773,20 @@ function validateSettings(returnValidation) { snakes.push(new Snake(RIGHT, 3, grid, PLAYER_AI, aiLevel, autoRetry)); } - games.push(new Game(grid, snakes, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed)); + games.push(new Game(grid, snakes, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed, null, null, null, null, !enableAnimations)); } else { if(battleAgainstAIs) { var grid = new Grid(widthGrid, heightGrid, generateWalls, borderWalls); var snake = new Snake(RIGHT, 3, grid, playerHumanType, aiLevel, autoRetry); - games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, false, progressiveSpeed, 350, 250)); + games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, false, progressiveSpeed, 350, 250, null, null, !enableAnimations)); } for(var i = 0; i < numberIA; i++) { var grid = new Grid(widthGrid, heightGrid, generateWalls, borderWalls); var snake = new Snake(RIGHT, 3, grid, PLAYER_AI, aiLevel, autoRetry); - games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, false, progressiveSpeed, 350, 250)); + games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), true, false, progressiveSpeed, 350, 250, null, null, !enableAnimations)); } } } @@ -1106,7 +1111,7 @@ function playLevel(level, player, type) { snakes.push(new Snake(RIGHT, 3, grid, PLAYER_AI, aiLevel)); } - var playerGame = new Game(grid, snakes, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed); + var playerGame = new Game(grid, snakes, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed, null, null, null, null, !enableAnimations); games.push(playerGame); } else { if(numberIA + 1 <= 2) { @@ -1117,14 +1122,14 @@ function playLevel(level, player, type) { var height = 250; } - var playerGame = new Game(grid, playerSnake, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed, width, height); + var playerGame = new Game(grid, playerSnake, speed, document.getElementById("gameContainer"), true, true, progressiveSpeed, width, height, null, null, !enableAnimations); games.push(playerGame); for(var i = 0; i < numberIA; i++) { var grid = new Grid(widthGrid, heightGrid, generateWalls, borderWalls); var snake = new Snake(RIGHT, 3, grid, PLAYER_AI, aiLevel, false); - games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), false, false, progressiveSpeed, width, height)); + games.push(new Game(grid, snake, speed, document.getElementById("gameContainer"), false, false, progressiveSpeed, width, height, null, null, !enableAnimations)); } } diff --git a/assets/js/src/constants.js b/assets/js/src/constants.js index 90191fc..5514b30 100644 --- a/assets/js/src/constants.js +++ b/assets/js/src/constants.js @@ -53,8 +53,8 @@ var GameConstants = { IMAGE_SNAKE_SATURATION: 50, IMAGE_SNAKE_VALUE: 77, CARS_TO_PRERENDER: ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "×"], - APP_VERSION: "1.4.2", - DATE_VERSION: "10/07/2019" + APP_VERSION: "1.5", + DATE_VERSION: "01/31/2020" }, Direction: { UP: 0, diff --git a/assets/js/src/gameUI.js b/assets/js/src/gameUI.js index af8b30a..4a983cb 100755 --- a/assets/js/src/gameUI.js +++ b/assets/js/src/gameUI.js @@ -765,6 +765,10 @@ GameUI.prototype.setNotification = function(notification) { } this.notificationMessage = notification; + + if(this.notificationMessage instanceof NotificationMessage && this.disableAnimation) { + this.notificationMessage.disableAnimation = true; + } }; GameUI.prototype.setTimeToDisplay = function(time) { @@ -1315,7 +1319,7 @@ GameUI.prototype.drawSnakeInfos = function(ctx, totalWidth, caseWidth, caseHeigh var caseX = Math.floor(posX * caseWidth + ((this.canvas.width - totalWidth) / 2)); var caseY = this.headerHeight + posY * caseHeight; - if(!this.snakes[i].gameOver) { + if(!this.disableAnimation && !this.snakes[i].gameOver) { var offset = this.offsetFrame / (this.speed * GameConstants.Setting.TIME_MULTIPLIER); var offset = (offset > 1 ? 1 : offset); var offsetX = (caseWidth * offset) - caseWidth; diff --git a/assets/js/src/notificationMessage.js b/assets/js/src/notificationMessage.js index 232ae80..cdd60ab 100644 --- a/assets/js/src/notificationMessage.js +++ b/assets/js/src/notificationMessage.js @@ -21,7 +21,7 @@ if(typeof(require) !== "undefined") { var GameConstants = require("./constants"); } -function NotificationMessage(text, textColor, backgroundColor, delayBeforeClosing, animationDelay, fontSize, fontFamily, foreGround) { +function NotificationMessage(text, textColor, backgroundColor, delayBeforeClosing, animationDelay, fontSize, fontFamily, foreGround, disableAnimation) { this.text = text; this.textColor = textColor == undefined ? "rgba(255, 255, 255, 0.75)" : textColor; this.backgroundColor = backgroundColor == undefined ? "rgba(46, 204, 113, 0.5)" : backgroundColor; @@ -35,6 +35,7 @@ function NotificationMessage(text, textColor, backgroundColor, delayBeforeClosin this.init = false; this.closed = false; this.closing = false; + this.disableAnimation = disableAnimation == undefined ? false : disableAnimation; this.closeButton; } @@ -65,16 +66,18 @@ NotificationMessage.prototype.draw = function(game) { this.fontSize = this.getFontSize(ctx) * 1.25; var heightText = game.wrapTextLines(ctx, this.text, null, this.fontSize)["height"]; - var height = heightText + this.fontSize / 2; var width = canvas.width; - - var offsetY = this.animationTime / this.animationDelay; + var offsetY = 1; if(!this.closing) { this.animationTime += offsetTime; } else { - this.animationTime -= offsetTime; + if(this.disableAnimation) { + this.animationTime = -1; + } else { + this.animationTime -= offsetTime; + } } if(this.animationTime < 0) { @@ -83,7 +86,10 @@ NotificationMessage.prototype.draw = function(game) { } if(!this.closed) { - var offsetY = this.animationTime / this.animationDelay; + if(!this.disableAnimation) { + offsetY = this.animationTime / this.animationDelay; + } + var y = canvas.height - (height * (offsetY <= 1 ? offsetY : 1)); ctx.fillStyle = this.backgroundColor; diff --git a/assets/locales/engine.js b/assets/locales/engine.js index 14e26b4..a81a3a4 100644 --- a/assets/locales/engine.js +++ b/assets/locales/engine.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Eliastik (eliastiksofts.com) + * Copyright (C) 2019-2020 Eliastik (eliastiksofts.com) * * This file is part of "SnakeIA". * diff --git a/assets/locales/init.js b/assets/locales/init.js index 8ff36da..5acd71e 100644 --- a/assets/locales/init.js +++ b/assets/locales/init.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Eliastik (eliastiksofts.com) + * Copyright (C) 2019-2020 Eliastik (eliastiksofts.com) * * This file is part of "SnakeIA". * diff --git a/assets/locales/menu.js b/assets/locales/menu.js index 7805862..a8ff4f6 100644 --- a/assets/locales/menu.js +++ b/assets/locales/menu.js @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Eliastik (eliastiksofts.com) + * Copyright (C) 2019-2020 Eliastik (eliastiksofts.com) * * This file is part of "SnakeIA". * @@ -52,6 +52,7 @@ i18next.addResourceBundle("fr", "translation", { "readme": "Fichier Lisez-moi", "source": "Télécharger la source", "language": "Langue :", + "enableAnimations": "Activer les animations" }, "settings": { "title": "Paramètres de la partie :", @@ -198,7 +199,8 @@ i18next.addResourceBundle("en", "translation", { "infos": "More informations", "readme": "Readme file", "source": "Download the source", - "language": "Language:" + "language": "Language:", + "enableAnimations": "Enable the animations" }, "settings": { "title": "Game settings:", diff --git a/index.html b/index.html index 3f38501..348a2ba 100644 --- a/index.html +++ b/index.html @@ -1,5 +1,5 @@