2
votes

I'm very, very new to learning HTML, CSS, and JS. I'm attempting to write my first page that my 'main.js' file imports a function from my 'utils.js' file to use in my 'index.html' file. My browser is google chrome Version 85.0.4183.121 (Official Build) (64-bit), and I'm running on a os of Windows 10.

The tutorial I'm trying to learn from is: (on youtube.com)
"JavaScript Modules with Import/Export Syntax (ES6) - JavaScript Tutorial"
channel is:
"dcode"
url:
https://youtu.be/s9kNndJLOjg

Below is a representation of all I've done following along.

My folder/file tree looks like below: (on Desktop)

HTML_folder-
            |-js_folder-
            |           |-main.js
            |           |-utils.js
            |
            |-index.html

My index.html document looks like below:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=10.0">
  <title>Chrome Dino Replica</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    canvas {
      display: block;
    }
  </style>
</head>
<body>
  <canvas id="game" width="640" height="400"></canvas>
  <script type="module" src="./js_folder/main.js"></script>
</body>
</html>

My main.js document looks like below:

import {double} from './utils.js';

console.log(double(5));

const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');

// Variables
let score;
let scoreText;
let highscore;
let highscoreText;
let player;
let gravity;
let obstacles = [];
let gameSpeed;
let keys = {};

// Event Listeners
document.addEventListener('keydown', function (evt) {
  keys[evt.code] = true;
});
document.addEventListener('keyup', function (evt) {
  keys[evt.code] = false;
});

class Player {
  constructor (x, y, w, h, c) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.c = c;

    this.dy = 0;
    this.jumpForce = 15;
    this.originalHeight = h;
    this.grounded = false;
    this.jumpTimer = 0;
  }

  Animate () {
    // Jump
    if (keys['Space'] || keys['KeyW']) {
      this.Jump();
    } else {
      this.jumpTimer = 0;
    }

    if (keys['ShiftLeft'] || keys['KeyS']) {
      this.h = this.originalHeight / 2;
    } else {
      this.h = this.originalHeight;
    }

    this.y += this.dy;

    // Gravity
    if (this.y + this.h < canvas.height) {
      this.dy += gravity;
      this.grounded = false;
    } else {
      this.dy = 0;
      this.grounded = true;
      this.y = canvas.height - this.h;
    }

    this.Draw();
  }

  Jump () {
    if (this.grounded && this.jumpTimer == 0) {
      this.jumpTimer = 1;
      this.dy = -this.jumpForce;
    } else if (this.jumpTimer > 0 && this.jumpTimer < 15) {
      this.jumpTimer++;
      this.dy = -this.jumpForce - (this.jumpTimer / 50);
    }
  }

  Draw () {
    ctx.beginPath();
    ctx.fillStyle = this.c;
    ctx.fillRect(this.x, this.y, this.w, this.h);
    ctx.closePath();
  }
}

class Obstacle {
  constructor (x, y, w, h, c) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.c = c;

    this.dx = -gameSpeed;
  }

  Update () {
    this.x += this.dx;
    this.Draw();
    this.dx = -gameSpeed;
  }

  Draw () {
    ctx.beginPath();
    ctx.fillStyle = this.c;
    ctx.fillRect(this.x, this.y, this.w, this.h);
    ctx.closePath();
  }
}

class Text {
  constructor (t, x, y, a, c, s) {
    this.t = t;
    this.x = x;
    this.y = y;
    this.a = a;
    this.c = c;
    this.s = s;
  }

  Draw () {
    ctx.beginPath();
    ctx.fillStyle = this.c;
    ctx.font = this.s + "px sans-serif";
    ctx.textAlign = this.a;
    ctx.fillText(this.t, this.x, this.y);
    ctx.closePath();
  }
}

// Game Functions
function SpawnObstacle () {
  let size = RandomIntInRange(20, 70);
  let type = RandomIntInRange(0, 1);
  let obstacle = new Obstacle(canvas.width + size, canvas.height - size, size, size, '#2484E4');

  if (type == 1) {
    obstacle.y -= player.originalHeight - 10;
  }
  obstacles.push(obstacle);
}


function RandomIntInRange (min, max) {
  return Math.round(Math.random() * (max - min) + min);
}

function Start () {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;

  ctx.font = "20px sans-serif";

  gameSpeed = 3;
  gravity = 1;

  score = 0;
  highscore = 0;
  if (localStorage.getItem('highscore')) {
    highscore = localStorage.getItem('highscore');
  }

  player = new Player(25, 0, 50, 50, '#FF5858');

  scoreText = new Text("Score: " + score, 25, 25, "left", "#212121", "20");
  highscoreText = new Text("Highscore: " + highscore, canvas.width - 25, 25, "right", "#212121", "20");

  requestAnimationFrame(Update);
}

let initialSpawnTimer = 200;
let spawnTimer = initialSpawnTimer;
function Update () {
  requestAnimationFrame(Update);
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  spawnTimer--;
  if (spawnTimer <= 0) {
    SpawnObstacle();
    console.log(obstacles);
    spawnTimer = initialSpawnTimer - gameSpeed * 8;
    
    if (spawnTimer < 60) {
      spawnTimer = 60;
    }
  }

  // Spawn Enemies
  for (let i = 0; i < obstacles.length; i++) {
    let o = obstacles[i];

    if (o.x + o.w < 0) {
      obstacles.splice(i, 1);
    }

    if (
      player.x < o.x + o.w &&
      player.x + player.w > o.x &&
      player.y < o.y + o.h &&
      player.y + player.h > o.y
    ) {
      obstacles = [];
      score = 0;
      spawnTimer = initialSpawnTimer;
      gameSpeed = 3;
      window.localStorage.setItem('highscore', highscore);
    }

    o.Update();
  }

  player.Animate();

  score++;
  scoreText.t = "Score: " + score;
  scoreText.Draw();

  if (score > highscore) {
    highscore = score;
    highscoreText.t = "Highscore: " + highscore;
  }
  
  highscoreText.Draw();

  gameSpeed += 0.003;
}

Start();

My utils.js document looks like below:

export function double (n) {
    return n * 2;
}

The errors that return in console:

Error 1:
Access to script at 'file:///C:/Users..../HTML/js_folder/main.js' from 
origin 'null' has been blocked by CORS policy: Cross origin requests 
are only supported for protocol schemes: http, data, chrome,
 chrome-extension, chrome-untrusted, https.                                                  index.html:1

Error 2:
Failed to load resource: net::ERR_FAILED                                                        main.js:1

If I remove (lines below) from 'main.js', it works..

import {double} from './utils.js';

console.log(double(5));

However, that doesn't pull in my 'utlis.js' file and I don't know the (how, what or why) I cannot load in a js module I have made for my document.

"I've tried...
google searching error
  |-- run cmd command 'chrome.exe --allow-running-insecure-content' with the 'index.html' file
  |-- look at multiple 'stackoverflow.com' & 'superuser.com' search queries of this problem and tried the
  |   solutions
  |-- watched a lot of 'youtube.com' on how to use import/export js files

rewriting the string to locate the folder multiple times"

I am very stumped.. And I don't understand the problem chrome seems to have with this, so please explain on the why of it all and how to correct it. I'd greatly appreciate it, thank you for your time.

1

1 Answers

0
votes

This ES6 module stuff doesn't work with local html and Javascript files loaded directly from your own machine's file system with the file:// protocol. Read this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules

You must use a local web server to develop code using this kind of export/import module methodology. Because cybercreeps.

There's a simple web server add on for the Chrome browser here https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=en

Or you can use, on Windows, the built in IIS web server. There are plenty of tutorials about setting that up for development.