From f7abfc4902424c5961abd7e78f54eb98d612f947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Pelletier?= Date: Sun, 8 Sep 2024 20:37:07 -0400 Subject: [PATCH] commit initial --- .dockerignore | 5 + .gitignore | 9 + Dockerfile | 24 +++ app/controllers/AsteroidGameController.scala | 11 ++ app/controllers/HomeController.scala | 24 +++ app/views/game.scala.html | 6 + app/views/index.scala.html | 5 + app/views/main.scala.html | 25 +++ build-local.sh | 1 + build.sbt | 16 ++ conf/application.conf | 1 + conf/logback.xml | 50 +++++ conf/routes | 11 ++ project/build.properties | 1 + project/plugins.sbt | 1 + public/images/cookie.png | Bin 0 -> 14680 bytes public/images/favicon.png | Bin 0 -> 687 bytes public/images/monster.png | Bin 0 -> 20019 bytes public/javascripts/game.js | 189 +++++++++++++++++++ public/javascripts/main.js | 0 public/stylesheets/main.css | 0 run-docker.sh | 8 + test/controllers/HomeControllerSpec.scala | 45 +++++ 23 files changed, 432 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 app/controllers/AsteroidGameController.scala create mode 100644 app/controllers/HomeController.scala create mode 100644 app/views/game.scala.html create mode 100644 app/views/index.scala.html create mode 100644 app/views/main.scala.html create mode 100644 build-local.sh create mode 100644 build.sbt create mode 100644 conf/application.conf create mode 100644 conf/logback.xml create mode 100644 conf/routes create mode 100644 project/build.properties create mode 100644 project/plugins.sbt create mode 100644 public/images/cookie.png create mode 100644 public/images/favicon.png create mode 100644 public/images/monster.png create mode 100644 public/javascripts/game.js create mode 100644 public/javascripts/main.js create mode 100644 public/stylesheets/main.css create mode 100644 run-docker.sh create mode 100644 test/controllers/HomeControllerSpec.scala diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ead37ac --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +target/ +.git/ +.idea/ +*.class +*.log \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dce7303 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +logs +target +/.bsp +/.idea +/.idea_modules +/.classpath +/.project +/.settings +/RUNNING_PID diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..36acd85 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +# Use the official OpenJDK base image +FROM openjdk:11 + +# Install sbt +RUN echo "deb https://repo.scala-sbt.org/scalasbt/debian all main" | tee /etc/apt/sources.list.d/sbt.list +RUN echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | tee /etc/apt/sources.list.d/sbt_old.list +RUN curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | apt-key add +RUN apt-get update +RUN apt-get install sbt + +# Set the working directory in the container +WORKDIR /app + +# Copy the project files into the container +COPY . /app + +# Run sbt clean and compile +RUN sbt clean compile + +# Expose the port the app runs on +EXPOSE 9000 + +# Command to run the application +CMD ["sbt", "run"] \ No newline at end of file diff --git a/app/controllers/AsteroidGameController.scala b/app/controllers/AsteroidGameController.scala new file mode 100644 index 0000000..689f6bd --- /dev/null +++ b/app/controllers/AsteroidGameController.scala @@ -0,0 +1,11 @@ +package controllers + +import javax.inject._ +import play.api.mvc._ + +@Singleton +class AsteroidGameController @Inject()(val controllerComponents: ControllerComponents) extends BaseController { + def game(): Action[AnyContent] = Action { implicit request: Request[AnyContent] => + Ok(views.html.game()) + } +} \ No newline at end of file diff --git a/app/controllers/HomeController.scala b/app/controllers/HomeController.scala new file mode 100644 index 0000000..0408acf --- /dev/null +++ b/app/controllers/HomeController.scala @@ -0,0 +1,24 @@ +package controllers + +import javax.inject._ +import play.api._ +import play.api.mvc._ + +/** + * This controller creates an `Action` to handle HTTP requests to the + * application's home page. + */ +@Singleton +class HomeController @Inject()(val controllerComponents: ControllerComponents) extends BaseController { + + /** + * Create an Action to render an HTML page. + * + * The configuration in the `routes` file means that this method + * will be called when the application receives a `GET` request with + * a path of `/`. + */ + def index(): Action[AnyContent] = Action { implicit request: Request[AnyContent] => + Ok(views.html.index()) + } +} diff --git a/app/views/game.scala.html b/app/views/game.scala.html new file mode 100644 index 0000000..cf90f3a --- /dev/null +++ b/app/views/game.scala.html @@ -0,0 +1,6 @@ +@() + +@main("Asteroid Cookies Game") { + + +} \ No newline at end of file diff --git a/app/views/index.scala.html b/app/views/index.scala.html new file mode 100644 index 0000000..68d37fb --- /dev/null +++ b/app/views/index.scala.html @@ -0,0 +1,5 @@ +@() + +@main("Welcome to Play") { +

Welcome to Play!

+} diff --git a/app/views/main.scala.html b/app/views/main.scala.html new file mode 100644 index 0000000..808a8b8 --- /dev/null +++ b/app/views/main.scala.html @@ -0,0 +1,25 @@ +@* + * This template is called from the `index` template. This template + * handles the rendering of the page header and body tags. It takes + * two arguments, a `String` for the title of the page and an `Html` + * object to insert into the body of the page. + *@ +@(title: String)(content: Html) + + + + + @* Here's where we render the page title `String`. *@ + @title + + + + + + @* And here's where we render the `Html` object containing + * the page content. *@ + @content + + + + diff --git a/build-local.sh b/build-local.sh new file mode 100644 index 0000000..96887b3 --- /dev/null +++ b/build-local.sh @@ -0,0 +1 @@ +docker build -t asteroid-cookies . \ No newline at end of file diff --git a/build.sbt b/build.sbt new file mode 100644 index 0000000..65a04d9 --- /dev/null +++ b/build.sbt @@ -0,0 +1,16 @@ +name := """asteroid-cookies""" + +version := "1.0-SNAPSHOT" + +lazy val root = (project in file(".")).enablePlugins(PlayScala) + +scalaVersion := "2.13.14" + +libraryDependencies += guice +libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "7.0.0" % Test + +// Adds additional packages into Twirl +//TwirlKeys.templateImports += "com.example.controllers._" + +// Adds additional packages into conf/routes +// play.sbt.routes.RoutesKeys.routesImport += "com.example.binders._" diff --git a/conf/application.conf b/conf/application.conf new file mode 100644 index 0000000..cb94680 --- /dev/null +++ b/conf/application.conf @@ -0,0 +1 @@ +# https://www.playframework.com/documentation/latest/Configuration diff --git a/conf/logback.xml b/conf/logback.xml new file mode 100644 index 0000000..55879ea --- /dev/null +++ b/conf/logback.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + ${application.home:-.}/logs/application.log + + UTF-8 + %d{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) %cyan(%logger{36}) %magenta(%X{pekkoSource}) %msg%n + + + + + + + + UTF-8 + %d{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) %cyan(%logger{36}) %magenta(%X{pekkoSource}) %msg%n + + + + + + + + + + + + + + + + + + + + diff --git a/conf/routes b/conf/routes new file mode 100644 index 0000000..fda0215 --- /dev/null +++ b/conf/routes @@ -0,0 +1,11 @@ +# Routes +# This file defines all application routes (Higher priority routes first) +# https://www.playframework.com/documentation/latest/ScalaRouting +# ~~~~ + +# An example controller showing a sample home page +GET / controllers.HomeController.index() + +# Map static resources from the /public folder to the /assets URL path +GET /assets/*file controllers.Assets.versioned(path="/public", file: Asset) +GET /game controllers.AsteroidGameController.game() diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 0000000..ee4c672 --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=1.10.1 diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 0000000..19161b9 --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.5") diff --git a/public/images/cookie.png b/public/images/cookie.png new file mode 100644 index 0000000000000000000000000000000000000000..b919f35f16f3dacb0f7eec3e0a230005043b5520 GIT binary patch literal 14680 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 literal 0 HcmV?d00001 diff --git a/public/images/favicon.png b/public/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c7d92d2ae47434d9a61c90bc205e099b673b9dd5 GIT binary patch literal 687 zcmV;g0#N;lP)ezT{T_ZJ?}AL z5NC{NW(ESID=>(O3&Eg8 zmA9J&6c`h4_f6L;=bU>_H8aNG`kfvCj9zomNt)?O;rzWqZs0LEt%1WB218%1fo9uB zsW^yhBR7C(mqN%GEK9&msg0~ zWY?#bf4q8G-~2KttQZ($odJvy&_-~f?9*ThK@fwR$U^1)p*8=_+^3BXx0$i1BC8XC zr21u6D5nVK&^!dOAw&|1E;qC3uFNj3*Jj#&%Oje@0D-nhfmM*o%^5f}-pxQ07(95H z3|LoV>V19w#rLgmRmtVy9!T3M3FUE3><0T8&b3yEsWcLW`0(=1+qsqc(k(ymBLK0h zK!6(6$7MX~M`-QA2$wk7n(7hhkJ}4Rwi-Vd(_ZFX1Yk7TXuB0IJYpo@kLb2G8m)E{ z`9v=!hi}fOytKckfN^C@6+Z*+MVI9-W_p@_3yyR#UYc0FTpD}i#k>c!wYCS)4v@E$ zchZCo=zV@)`v^$;V18ixdjFMY#q^2$wEX%{f(XD8POnsn$bpbClpC@hPxjzyO>pY|*pF3UU2tYcCN?rUk{Sskej70Mmu9vPwMYhO1m{AxAt(zqDT|0jP7FaX=6 V`?~}E4H^Id002ovPDHLkV1hC)G==~G literal 0 HcmV?d00001 diff --git a/public/images/monster.png b/public/images/monster.png new file mode 100644 index 0000000000000000000000000000000000000000..8f400ae0e54e89f3c52809b5a14fcef7b62e7c80 GIT binary patch literal 20019 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

qB_sm@_fcgCr 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

=zi@;268Sp-Fm2j6Khp{a$=gBHT34ueO3 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 literal 0 HcmV?d00001 diff --git a/public/javascripts/game.js b/public/javascripts/game.js new file mode 100644 index 0000000..0947563 --- /dev/null +++ b/public/javascripts/game.js @@ -0,0 +1,189 @@ +document.addEventListener('DOMContentLoaded', () => { + const canvas = document.getElementById('gameCanvas'); + const ctx = canvas.getContext('2d'); + + let score = 0; + let gameOver = false; + + class Cookie { + constructor(x, y, size) { + this.x = x; + this.y = y; + this.size = size; + this.speed = Math.random() * 0.5 + 0.2; // Reduced speed range + this.angle = Math.random() * Math.PI * 2; + this.image = new Image(); + this.image.src = '/assets/images/cookie.png'; + } + + update() { + this.x += Math.cos(this.angle) * this.speed; + this.y += Math.sin(this.angle) * this.speed; + + if (this.x < 0) this.x = canvas.width; + if (this.x > canvas.width) this.x = 0; + if (this.y < 0) this.y = canvas.height; + if (this.y > canvas.height) this.y = 0; + } + + draw() { + ctx.drawImage(this.image, this.x - this.size / 2, this.y - this.size / 2, this.size, this.size); + } + } + + class Ship { + constructor() { + this.x = canvas.width / 2; + this.y = canvas.height / 2; + this.angle = 0; + this.size = 40; + this.image = new Image(); + this.image.src = '/assets/images/monster.png'; + this.speed = 0; + this.rotationSpeed = 0.2; // Increased rotation speed + } + + update() { + this.x += Math.cos(this.angle) * this.speed; + this.y += Math.sin(this.angle) * this.speed; + + if (this.x < 0) this.x = canvas.width; + if (this.x > canvas.width) this.x = 0; + if (this.y < 0) this.y = canvas.height; + if (this.y > canvas.height) this.y = 0; + + this.speed *= 0.98; // Add friction + } + + draw() { + ctx.save(); + ctx.translate(this.x, this.y); + ctx.rotate(this.angle); + ctx.drawImage(this.image, -this.size / 2, -this.size / 2, this.size, this.size); + ctx.restore(); + } + + rotate(direction) { + this.angle += this.rotationSpeed * direction; + } + } + + class Bullet { + constructor(x, y, angle) { + this.x = x; + this.y = y; + this.angle = angle; + this.speed = 5; + this.size = 5; + } + + update() { + this.x += Math.cos(this.angle) * this.speed; + this.y += Math.sin(this.angle) * this.speed; + } + + draw() { + ctx.fillStyle = 'yellow'; + ctx.beginPath(); + ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); + ctx.fill(); + } + } + + const cookies = []; + const ship = new Ship(); + const bullets = []; + + function spawnCookies() { + if (cookies.length < 10) { + cookies.push(new Cookie(Math.random() * canvas.width, Math.random() * canvas.height, 30)); + } + } + + function checkCollisions() { + // Ship-Cookie collision + cookies.forEach((cookie, cookieIndex) => { + const dx = ship.x - cookie.x; + const dy = ship.y - cookie.y; + const distance = Math.sqrt(dx * dx + dy * dy); + + if (distance < ship.size / 2 + cookie.size / 2) { + gameOver = true; + } + + // Bullet-Cookie collision + bullets.forEach((bullet, bulletIndex) => { + const bulletDx = bullet.x - cookie.x; + const bulletDy = bullet.y - cookie.y; + const bulletDistance = Math.sqrt(bulletDx * bulletDx + bulletDy * bulletDy); + + if (bulletDistance < bullet.size + cookie.size / 2) { + cookies.splice(cookieIndex, 1); + bullets.splice(bulletIndex, 1); + score += 10; + } + }); + }); + } + + function gameLoop() { + // Set the background to black + ctx.fillStyle = 'black'; + ctx.fillRect(0, 0, canvas.width, canvas.height); + + if (gameOver) { + ctx.fillStyle = 'white'; + ctx.font = '48px Arial'; + ctx.fillText('Game Over', canvas.width / 2 - 100, canvas.height / 2); + ctx.font = '24px Arial'; + ctx.fillText(`Score: ${score}`, canvas.width / 2 - 50, canvas.height / 2 + 40); + return; + } + + ship.update(); + ship.draw(); + + cookies.forEach((cookie, index) => { + cookie.update(); + cookie.draw(); + }); + + bullets.forEach((bullet, index) => { + bullet.update(); + bullet.draw(); + + if (bullet.x < 0 || bullet.x > canvas.width || bullet.y < 0 || bullet.y > canvas.height) { + bullets.splice(index, 1); + } + }); + + spawnCookies(); + checkCollisions(); + + // Draw score + ctx.fillStyle = 'white'; + ctx.font = '24px Arial'; + ctx.fillText(`Score: ${score}`, 10, 30); + + requestAnimationFrame(gameLoop); + } + + document.addEventListener('keydown', (event) => { + switch(event.key) { + case 'ArrowLeft': + ship.rotate(-1); // Rotate counterclockwise + break; + case 'ArrowRight': + ship.rotate(1); // Rotate clockwise + break; + case 'ArrowUp': + ship.speed = 5; + break; + case ' ': + bullets.push(new Bullet(ship.x, ship.y, ship.angle)); + break; + } + }); + + gameLoop(); +}); \ No newline at end of file diff --git a/public/javascripts/main.js b/public/javascripts/main.js new file mode 100644 index 0000000..e69de29 diff --git a/public/stylesheets/main.css b/public/stylesheets/main.css new file mode 100644 index 0000000..e69de29 diff --git a/run-docker.sh b/run-docker.sh new file mode 100644 index 0000000..aaca376 --- /dev/null +++ b/run-docker.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Stop and remove existing container with the same name +docker stop "$(docker ps -aq --filter "name=asteroid-cookies")" +docker rm "$(docker ps -aq --filter "name=asteroid-cookies")" + +# Run the container with the specified tag and name +docker run -p 9000:9000 --name asteroid-cookies asteroid-cookies \ No newline at end of file diff --git a/test/controllers/HomeControllerSpec.scala b/test/controllers/HomeControllerSpec.scala new file mode 100644 index 0000000..9794755 --- /dev/null +++ b/test/controllers/HomeControllerSpec.scala @@ -0,0 +1,45 @@ +package controllers + +import org.scalatestplus.play._ +import org.scalatestplus.play.guice._ +import play.api.test._ +import play.api.test.Helpers._ + +/** + * Add your spec here. + * You can mock out a whole application including requests, plugins etc. + * + * For more information, see https://www.playframework.com/documentation/latest/ScalaTestingWithScalaTest + */ +class HomeControllerSpec extends PlaySpec with GuiceOneAppPerTest with Injecting { + + "HomeController GET" should { + + "render the index page from a new instance of controller" in { + val controller = new HomeController(stubControllerComponents()) + val home = controller.index().apply(FakeRequest(GET, "/")) + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + contentAsString(home) must include ("Welcome to Play") + } + + "render the index page from the application" in { + val controller = inject[HomeController] + val home = controller.index().apply(FakeRequest(GET, "/")) + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + contentAsString(home) must include ("Welcome to Play") + } + + "render the index page from the router" in { + val request = FakeRequest(GET, "/") + val home = route(app, request).get + + status(home) mustBe OK + contentType(home) mustBe Some("text/html") + contentAsString(home) must include ("Welcome to Play") + } + } +}