summaryrefslogtreecommitdiff
path: root/resources/js
diff options
context:
space:
mode:
authorFbenas <philbeansburton@gmail.com>2020-09-20 22:08:03 +0100
committerFbenas <philbeansburton@gmail.com>2020-09-20 22:08:03 +0100
commit9be73c2d0f21a539bc46974139e8c36c12845ca0 (patch)
tree3442d2254797983e7e0294c9aee00e90aa643109 /resources/js
Initial commit
Diffstat (limited to 'resources/js')
-rw-r--r--resources/js/app.js13
-rw-r--r--resources/js/bootstrap.js28
-rw-r--r--resources/js/component.js80
-rw-r--r--resources/js/gameArea.js20
-rw-r--r--resources/js/scene.js70
5 files changed, 211 insertions, 0 deletions
diff --git a/resources/js/app.js b/resources/js/app.js
new file mode 100644
index 0000000..103a32f
--- /dev/null
+++ b/resources/js/app.js
@@ -0,0 +1,13 @@
+let scene = new Scene(2, 500);
+
+function stop() {
+ scene.stop();
+}
+
+function start() {
+ scene.start();
+}
+
+function reset() {
+ scene.reset();
+}
diff --git a/resources/js/bootstrap.js b/resources/js/bootstrap.js
new file mode 100644
index 0000000..6922577
--- /dev/null
+++ b/resources/js/bootstrap.js
@@ -0,0 +1,28 @@
+window._ = require('lodash');
+
+/**
+ * We'll load the axios HTTP library which allows us to easily issue requests
+ * to our Laravel back-end. This library automatically handles sending the
+ * CSRF token as a header based on the value of the "XSRF" token cookie.
+ */
+
+window.axios = require('axios');
+
+window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
+
+/**
+ * Echo exposes an expressive API for subscribing to channels and listening
+ * for events that are broadcast by Laravel. Echo and event broadcasting
+ * allows your team to easily build robust real-time web applications.
+ */
+
+// import Echo from 'laravel-echo';
+
+// window.Pusher = require('pusher-js');
+
+// window.Echo = new Echo({
+// broadcaster: 'pusher',
+// key: process.env.MIX_PUSHER_APP_KEY,
+// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
+// forceTLS: true
+// });
diff --git a/resources/js/component.js b/resources/js/component.js
new file mode 100644
index 0000000..6d74e93
--- /dev/null
+++ b/resources/js/component.js
@@ -0,0 +1,80 @@
+class Component {
+
+ constructor(radius, color, x, y, direction) {
+ this.perceptionDistance = 20;
+ this.turnStepAmount = 5;
+ this.collisionTurnStepAmount = 20;
+ this.stepAmount = 1;
+ this.radius = radius;
+ this.x = x;
+ this.y = y;
+ this.direction = direction;
+ this.color = color;
+ }
+
+ move(context) {
+ this.direction += Math.random() * (2 * this.turnStepAmount) - this.turnStepAmount
+ var localDirection = this.direction;
+ // first we need to work out if we detect any walls
+ var perceptionVector = this.detectionPoint(this.x, this.y, this.perceptionDistance, localDirection);
+
+ while (perceptionVector.x < 0 || perceptionVector.y < 0 || perceptionVector.x > context.canvas.width || perceptionVector.y > context.canvas.height) {
+ localDirection += Math.random() * (2 * this.collisionTurnStepAmount) - this.collisionTurnStepAmount
+ perceptionVector = this.detectionPoint(this.x, this.y, this.perceptionDistance, localDirection);
+ }
+
+ // Here we should now have a new vector that's not clipping
+ this.direction = localDirection;
+ var vector = this.detectionPoint(this.x, this.y, this.stepAmount, this.direction);
+
+
+ this.x = vector.x;
+ this.y = vector.y;
+ this.update(context);
+ }
+
+ update(context) {
+ context.beginPath();
+ context.fillStyle = "blue";
+ context.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
+ context.stroke();
+
+ context.restore();
+ context.beginPath();
+ this.lineToAngle(context, this.x, this.y, this.perceptionDistance, this.direction);
+ context.lineWidth = 1;
+ // context.stroke();
+
+ context.restore();
+ }
+
+ lineToAngle(context, x1, y1, length, angle) {
+
+ angle *= Math.PI / 180;
+
+ var x2 = x1 + length * Math.cos(angle),
+ y2 = y1 + length * Math.sin(angle);
+
+ context.moveTo(x1, y1);
+ context.lineTo(x2, y2);
+
+ return {
+ x: x2,
+ y: y2
+ };
+ }
+
+ detectionPoint(x1, y1, length, angle) {
+
+ angle *= Math.PI / 180;
+
+ var x2 = x1 + length * Math.cos(angle),
+ y2 = y1 + length * Math.sin(angle);
+
+ return {
+ x: x2,
+ y: y2
+ };
+ }
+
+}
diff --git a/resources/js/gameArea.js b/resources/js/gameArea.js
new file mode 100644
index 0000000..a39b0e8
--- /dev/null
+++ b/resources/js/gameArea.js
@@ -0,0 +1,20 @@
+class GameArea {
+
+ constructor(canvas_width, canvas_height) {
+ this.canvas = document.createElement("canvas");
+ this.canvas_width = canvas_width;
+ this.canvas_height = canvas_height;
+ }
+
+ init() {
+ this.canvas.width = this.canvas_width;
+ this.canvas.height = this.canvas_height;
+ this.context = this.canvas.getContext("2d");
+ document.getElementById('container').appendChild(this.canvas);
+ }
+
+ clear() {
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ }
+
+}
diff --git a/resources/js/scene.js b/resources/js/scene.js
new file mode 100644
index 0000000..194a77b
--- /dev/null
+++ b/resources/js/scene.js
@@ -0,0 +1,70 @@
+class Scene {
+
+ constructor(component_size, no_of_components) {
+ this.component_size = component_size;
+ this.no_of_components = no_of_components;
+ this.components = new Array;
+ this.gameArea = {};
+ this.initGameArea();
+ this.initComponents();
+ this.started = false;
+ }
+
+ initComponents() {
+ for (let i = 0; i < this.no_of_components; i++) {
+ let new_component = new Component(
+ this.component_size,
+ "black",
+ Math.random() * this.gameArea.canvas.width,
+ Math.random() * this.gameArea.canvas.height,
+ Math.random() * 360
+ );
+ this.components.push(new_component);
+ }
+ }
+
+ initGameArea() {
+ this.gameArea = new GameArea(600, 600);
+ this.gameArea.init()
+ }
+
+ start() {
+ if (this.started) {
+ return;
+ }
+
+ // Kinda annoying, setInterval is a piece of shite and is always run from global scope
+ // Therefore "this.update" will be undefined unless we bind it
+ const updateMe = this.update.bind(this);
+ this.interval = setInterval(updateMe, 5);
+ this.started = true;
+ }
+
+ update() {
+ this.gameArea.clear();
+ for (let i = 0; i < this.no_of_components; i++) {
+ this.components[i].move(this.gameArea.context);
+ }
+ }
+
+ stop() {
+ if (!this.started) {
+ return;
+ }
+
+ clearInterval(this.interval);
+ this.interval = null;
+ this.started = false;
+ }
+
+ reset() {
+ if (this.started) {
+ this.stop();
+ }
+ this.components = new Array;
+ this.initComponents();
+ this.gameArea.clear();
+ this.started = false;
+ }
+
+}