r/learnjavascript

[AskJS] javascript game dev

Anyone can help me to start learning JS to game dev?,i have 13 years older,and i like the programation,i want make games,for funny and make games seriously,i use chatgpt but i dont want use him,i want learn and use my brain,PLEASE IF ANYONE WANT HELP ME SEND ME DM.

reddit.com
u/pixel-bro — 4 hours ago
▲ 0 r/learnjavascript+1 crossposts

could someone please lead me to the right direction with my JS here?

I have been struggling to find out why my JS weather widget will not update the image strip to the correct icon. I have this :

<script>
fetch('https://api.open-meteo.com/v1/forecast?latitude=39.082222&longitude=-77.482222&daily=temperature_2m_max,temperature_2m_min&hourly=temperature_2m&timezone=auto&current_weather=true&forecast_days=1')

.then(response => response.json())

.then(data => {

console.log(data);

const weather = data.current_weather;

const daily = data.daily;

const targetLat = 39.082222;

const targetLon = -77.482222;

console.log('Low (F):', daily.temperature_2m_min[0]);

console.log('High (F):', daily.temperature_2m_max[0]);

console.log('Low (F):', Math.round(daily.temperature_2m_min[0] * 9/5 + 32));

console.log('High (F):', Math.round(daily.temperature_2m_max[0] * 9/5 + 32));

const targetCity = 'Lansdowne, VA';

const currentTemp = Math.round(weather.temperature * 9/5 + 32);

const iconCode = weather.weathercode;

// FIX: If currentTemp is much higher than the morning low, we adjust the displayed low

// to reflect the expected upcoming night low instead of the passed morning cold.

let lowF = Math.round(daily.temperature_2m_min[0] * 9/5 + 32);

console.log('Low (F):', lowF);

const lowTemp = lowF;

const highTemp = Math.round(daily.temperature_2m_max[0] * 9/5 + 32);

const weatherDiv = document.getElementById('weather');

console.log('Weather widget loaded completely.');

console.log('Icon code:', iconCode);

});

const weatherDiv = document.getElementById('weather');

const img = new Image();

img.src = 'https://i.ibb.co/WptyQH9y/image-strip-weather.jpg';

img.onload = () => console.log('Image loaded!');

img.onerror = () => console.log('Image error!');

function weatherCodeToIconURL(code) {

console.log('wttr code:', code, typeof code);

// FIXED: Translation map connecting Open-Meteo codes directly to your image strip positions

const openMeteoToSprite = {

0: "01d", // Sunny / Clear Sky -> First Icon

1: "02d", // Mainly Clear -> Second Icon

2: "02d", // Partly Cloudy -> Second Icon

3: "03d", // Overcast -> Third Icon (Your default)

45: "50d", // Fog -> Fog/Mist Icon

48: "50d", // Depositing Rime Fog -> Fog/Mist Icon

51: "09d", // Drizzle -> Light Rain Icon

53: "09d",

55: "09d",

61: "09d", // Slight Rain -> 4th/5th Rain Cloud Icon

63: "10d", // Moderate Rain -> Heavier Rain Icon

65: "10d", // Heavy Rain

71: "13d", // Snow Fall -> Snow Cloud Icon

73: "13d",

75: "13d",

80: "09d", // Rain Showers

81: "10d",

82: "10d",

95: "11d", // Thunderstorm -> Lightning/Storm Icon

96: "11d",

99: "11d"

};

// 1. ADD THIS SPECIFIC LINE BACK RIGHT HERE:

const spriteKey = openMeteoToSprite[code] || '03d';

// FIXED: Crisp percentage shifts that line up flawlessly when the image is scaled to cover the box

const positions = {

"01d": "0px 0px", // Sun

"01n": "0px 0px",

"02d": "-120px 0px", // Sun/Cloud

"02n": "-120px 0px",

"03d": "-240px 0px", // Cloud

"03n": "-240px 0px",

"09d": "-360px 0px", // Rain

"09n": "-360px 0px",

"10d": "-480px 0px", // Rain variation

"10n": "-480px 0px",

"11d": "-600px 0px", // Thunderstorm

"11n": "-600px 0px",

"13d": "-720px 0px", // Snow

"13n": "-720px 0px",

"50d": "-720px 0px",

"50n": "-720px 0px"

};

// CRITICAL CHANGE: We wrap the final variable so it fits your string perfectly

const pos = positions[spriteKey];

if (pos) {

// FIXED: Added transform: scale(2.5) to magnify the icon to a clear, readable size

return \<div style="display: inline-block; width: 3em; height: 3em; background: url('https://i.ibb.co/WptyQH9y/image-strip-weather.jpg') no-repeat center; background-position: ' + pos + '; background-size: auto; transform: scale(1.5); vertical-align: middle;"></div>`;`

}

// ADD THESE THREE LINES RIGHT HERE BELOW IT:

return 'Unknown code';

}

async function getWeather(lat, lon, city) {

var targetCity = city || 'Lansdowne';

var targetLat = lat || 39.082222;

var targetLon = lon || -77.482222;

var base = 'https://api.open-meteo.com/v1/forecast';

var query = '?latitude=' + targetLat + '&amp;longitude=' + targetLon + '&amp;daily=temperature_2m_max,temperature_2m_min&amp;current=weather_code&amp;timezone=auto&amp;current_weather=true&amp;forecast_days=2';

var url = base + query;

try {

var response = await fetch(url);

if (!response.ok) throw new Error('Status: ' + response.status);

var data = await response.json();

console.log('Min:', data.daily.temperature_2m_min[0]);

console.log('Max:', data.daily.temperature_2m_max[0]);

// Extract current conditions

var currentTemp = Math.round(data.current_weather.temperature * 9/5 + 32);

console.log('currentTemp:', currentTemp);

var iconCode = data.current_weather.weathercode;

// Initialize search tracking counters

var trueHigh = -Infinity;

var trueLow = Infinity;

if (data.daily.temperature_2m_min[0] &lt; trueLow) {

trueLow = data.daily.temperature_2m_min[0];

}

if (data.daily.temperature_2m_max[0] &gt; trueHigh) {

trueHigh = data.daily.temperature_2m_max[0];

}

// Convert raw Celsius trackers into Fahrenheit

var finalHigh = Math.round(data.daily.temperature_2m_max[0] * 9/5 + 32);

var finalLow = Math.round(data.daily.temperature_2m_min[1] * 9/5 + 32);

// FIXED: Directly assign lowTemp and highTemp to use your final calculations

var lowTemp = finalLow;

var highTemp = finalHigh;

weatherDiv.innerHTML = '&lt;p style="font-size: 16px; color: #fff; text-align: center; margin: 0 0 8px 0;"&gt;' + targetCity + '&lt;/p&gt;' + '&lt;div style="position: relative; text-align: center; margin-bottom: 8px;"&gt;' + weatherCodeToIconURL(iconCode) + '&lt;span style="position: absolute; top: 60%; left: 57%; transform: translate(-50%, -50%); font-size: 24px; font-weight: bold; color: #fff; filter: drop-shadow(-3px 0 2px #000);"&gt;' + currentTemp + '°F&lt;/span&gt;' + '&lt;/div&gt;' + '&lt;div style="display: flex; justify-content: space-between; width: 154px; margin: 0 auto;"&gt;' + '&lt;p style="font-size: 14px; color: #87CEEB; margin: 0;"&gt;Low: ' + lowTemp + '°F&lt;/p&gt;' + '&lt;p style="font-size: 14px; color: #FFA07A; margin: 0;"&gt;High: ' + highTemp + '°F&lt;/p&gt;' + '&lt;/div&gt;';

console.log('Weather widget loaded completely. Low Temp:', lowTemp);

// --- NOTE ---

// If you have lines that update 'weatherDiv.innerHTML', ensure they are right here!

} catch (error) {

console.error('Weather widget error:', error);

}

}

function fetchLocationAndWeather() {

// FIXED: Replaced slow browser popups with a silent, instant IP location lookup

fetch('https://ip-api.com')

.then(response =&gt; response.json())

.then(data =&gt; {

// Sends the visitor's dynamic coordinates and city name directly to your weather builder

getWeather(data.lat, data.lon, data.city);

})

.catch(error =&gt; {

console.error('Location error, falling back to Lansdowne:', error);

// Safety fallback: if the IP service fails, default to Lansdowne so the widget doesn't break

getWeather(39.082222, -77.482222, 'Lansdowne');

});

}

// FIXED: Added back the missing '/data/reverse-geocode-client?latitude=' string block

// RUN IT IMMEDIATELY

weatherDiv.innerHTML = 'Loading weather... 🌤️';

setTimeout(function() {

fetchLocationAndWeather();

}, 100);

// SET THE INTERVAL to repeat every minute

setInterval(fetchLocationAndWeather, 60000);
&lt;/script&gt;

And here is the CSS :

#weather {

display: flex;

flex-direction: column;

font: normal 12px Helvetica, Arial, sans-serif;

color: #fff;

}

And the HTML :

&lt;div id="weather" style="display: flex; flex-direction: column; font: normal 12px Helvetica, Arial, sans-serif; color: #fff; "&gt;&lt;/div&gt;

I really don't know what to do at this point... I'd appreciate any feedback, corrections, ....etc.

u/Accomplished-Rain-52 — 10 hours ago

I want to know why this happen in js is there any specific reason or just author choice

I have recently started learning js & i noticed there's always many way's to do something in js
Like to create a variable in js we can use 3 keywords

  1. Var 2. Const 3. Let
    Similarly to create or define a function there are several methods
  2. Declare function by using function keyword
  3. Function expresss
    3.Arrow function

I know js is just built in less then month so it has many flaws due to this but why publish then first resolve these issue then go public

I may be wrong in few things here so apologies firstly

reddit.com
u/Ok_Egg_6647 — 14 hours ago

Looking for a good YouTube video for Promises

Hey,
I study with Claude, but sometimes I need illustrations to help me understand better the concepts.

I would like to understand Promises better, can you guys recommend me a video from YouTube about Promises and how they work? with the container, micro/macrotask etc.

Thanks!

reddit.com
u/Fabulous_Variety_256 — 23 hours ago

title.textContent = "Help !";

OK, alors je suis en troisième, je fais un peu de programmation JavaScript (connaissances de base), et j'ai un problème avec le code d'un petit jeu pour navigateur (page HTML).

J'essaie de créer un système de succès, et j'ai presque réussi ; j'ai juste un problème avec getElementById et HTMLObject.id = “...”.

Dans un extrait de code, je fais ceci : (exécuté une seule fois au lancement du programme)

for (var i = 0; i < achievements.length; i++){

let text = document.createTextNode("???");

achievementsD.appendChild(text);

text.id = achievements[i].name;

achievementsD.innerHTML += "<br><br>";

}

Pour information, au début, j'ai «let achievementsD = document.getElementById(‘achievementsD’);» et dans le HTML &lt;div id="achievementsD"&gt; &lt;!-- Implemented with Javascript !--&gt; &lt;/div&gt;. (Tout est correct, j'ai vérifié.)

Mais plus loin dans le code, dans une fonction qui s'exécute toutes les 1/30e de seconde (vérifiée, fonctionnelle), j'ai ceci :

for (var i = 0; i < achievements.length; i++){

if ((achievements[i].check)() && !(achievements[i].owned)){

achievements[i].owned = true;

document.getElementById(achievements[i].name).innerHTML = achievements[i].name; //Avertissement : le code ne fonctionne pas ici, voir ci-dessous.

//Notifications ? (Non ajouté pour le moment)

}

}

Notez que achievement[i] est défini comme [name (“Ten points !!!”), check (function v() {return points &gt;= 10}), text (“Make ten points”), owned (false), once (not used now, never mind)]; (entre parenthèses = détails, pas dans le code).

Le problème ? Lorsque j’essaie d’obtenir la complétion à 10 points (l’exemple fourni), j’obtiens l’erreur « Uncaught TypeError: can’t access property ‘innerHTML’, document.getElementById(...) is null » sur la ligne que j’ai marquée. Cela signifie que document.getElementById ne trouve pas l’objet HTML créé dans le premier extrait de code… Comment puis-je résoudre ce problème ?

Si ce message n’est pas approprié ici, veuillez me le faire savoir et m’indiquer où je peux le poster à la place.

Merci ! 😄

reddit.com
u/VlentGamer — 1 day ago

What javascript course is good without a subscription (paid/free)

I don’t mind a paid course I’m just not looking for another subscription. Just want to find a way to learn java script and practice without an ongoing payment.

reddit.com
u/FreeWanderer823 — 2 days ago

How would you refactor this? Node.js-express app - controller with 36 factory function calls of the same five factory functions

Hi, I am still learning how to become a developer, and in my node.js express application, I have a controller that exports functions that are created using factory functions.

The factory functions are as follows in this module:

const asyncHandler = require('../utils/asyncHandler');
const AppError = require('../utils/AppError');


exports.getData = (Model) =&gt;
  asyncHandler(async (req, res, next) =&gt; {
    const document = await Model.findAll();
    res.status(200).json({
      status: 'success',
      results: document.length,
      data: {
        document,
      },
    });
  });


exports.createData = (Model) =&gt;
  asyncHandler(async (req, res, next) =&gt; {
    const document = await Model.create(
      req.body,
      //object?
    );


    res.status(201).json({
      status: 'success',
      message: 'entry added successfully',
      data: {
        document,
      },
    });
  });


exports.deleteData = (Model) =&gt;
  asyncHandler(async (req, res, next) =&gt; {
    await Model.destroy({
      truncate: true,
    });


    res.status(204).json({
      status: 'success',
      data: null,
    });
  });


exports.updateData = (Model) =&gt;
  asyncHandler(async (req, res, next) =&gt; {
    const document = await Model.update(req.body, {
      where: { id: req.params.id },
    });


    if (document[0] === 0) {
      return next(new AppError('No document with that ID found.', 404));
    }


    res.status(200).json({
      status: 'success',
      data: { document },
    });
  });


exports.getSingle = (Model) =&gt;
  asyncHandler(async (req, res, next) =&gt; {
    const document = await Model.findOne({
      where: { id: req.params.id },
    });


    if (document[0] === 0) {
      return next(new AppError('No document with that ID found.', 404));
    }


    res.status(200).json({
      status: 'success',
      data: { document },
    });
  });

then, in my controller module:

const factory = require('./factory');
const Master = require('../models/masterModel');
// a whole bunch of models are imported

exports.getModel = factory.getData(Model);
exports.createModel = factory.createData(Model);
exports.deleteModel = factory.deleteData(Model);
exports.updateModel = factory.updateData(Model);
exports.getSingleModel = factory.getSingle(Model);

// another 30 of the same thing, for each model that I import at the top of the file... 

How would I refactor this? It is incredibly repetitive and I'm pretty sure this would be unacceptable in a professional environment.

Thanks in advance! :)

reddit.com
u/uyvhtvuyg — 1 day ago

Trouble with .addEventListener

having trouble figuring out what I am doing wrong in this snippet

const email = document.getElementById('email');
const confirm_email = document.getElementById('confirm_email');
const submit = document.getElementById('submit');
const ok = document.getElementById('ok');
const alert_box = document.getElementById('alert_box');

submit.addEventListener('click', function(){
    if (email !== confirm_email) {
        alert_box.style.display = 'flex';
        event.preventDefault()
    }
});

I thought it would function as it would grab my inputs from my form after I clicked my submit button and if the email and confirm_email didn't match it would change my display state but it will change the display state even if it does match.

--SOLVED--

submit.addEventListener('click', function(){
    email_val = email.value;
    confirm_email_val = confirm_email.value;
    console.log(email_val);
    console.log(confirm_email_val);
    if (email_val !== confirm_email_val) {
        alert_box.style.display = 'flex';
        event.preventDefault()        
    }
});

i know camel case is prefered for javascript and Java but I've done more work with python and camel case on variables looks icky to me.

reddit.com
u/MK_Ultra_LSWA — 2 days ago

console.log("Help me")

I really want to start using js, I have a little python experience from middle and highschool and I would love to start making my own games and passion projects, also would not be opposed to a future career in the field

reddit.com
u/Alone_Eagle_6974 — 3 days ago

How to Preload a Page Before Redirect to Avoid Latency

Hello, I’m working on a website and ran into a problem. I have a button that redirects to another page, but it’s not a standard link. I handle the redirect using:

window.location.href = "http://page";

I do this because I want to show an animation before the redirect, like this:

button.addEventListener("click", () =&gt; {
  anim.classList.add("animClass");
  setTimeout(() =&gt; {
    window.location.href = "http://page";
  }, 1000);
});

However, this approach isn’t very clean and has several issues. The main problem is that I can’t predict the user’s network speed, so there might be noticeable latency.

I was wondering if it’s possible to do something like this: preload the page in the background, cache it, and then when the user clicks the button, redirect them instantly. This way, there would be no delay.

reddit.com
u/Dull_Firefighter_929 — 3 days ago

Did AI effect the usage of this sub?

3 years ago, I was using this sub avidly while I was learning JS. Things changed a lot after AI. I checked recent submissions and not much posted in recent weeks.

Is this the effect of AI on learning? Do people rely on AI for learning things nowadays rather than forums?

reddit.com
u/Excellent-Lake-855 — 3 days ago

Bug fix

let overallDisplay = "0";
let currentDisplay = "0";
let resultDisplay = false;
function appendToDisplay(val){
if(currentDisplay === "0" || resultDisplay){
currentDisplay = val;
}
else{
currentDisplay += val;
}
updateCurrentDisplay();
resultDisplay = false;
}
function appendToOperator(val){
if(val === '+' &amp;&amp; currentDisplay !== "0") updateOverallDisplay(val);
else if(val === '-' &amp;&amp; currentDisplay !== "0") updateOverallDisplay(val);
else if(val === '*' &amp;&amp; currentDisplay !== "0") updateOverallDisplay(val);
else if(val === '/' &amp;&amp; currentDisplay !== "0") updateOverallDisplay(val);
}
function updateCurrentDisplay(){
let display = document.getElementById("output");
display.style.display = "block";
display.textContent = currentDisplay;
}
function updateOverallDisplay(value){
let overallDisplayArea = document.getElementById("overall");
if(overallDisplay === "0"){
overallDisplay = currentDisplay + " " + value;
}
else{
overallDisplay += currentDisplay + " " + value;
}
overallDisplayArea.textContent = overallDisplay;
currentDisplay = "0";
}
function clearOverallDisplay(){
overallDisplay = 0;
let overallDisplayArea = document.getElementById("overall");
overallDisplayArea.style.display = "none";
}
function clearCurrentDisplay(){
currentDisplay = 0;
updateCurrentDisplay();
}
function clearDisplay(){
clearOverallDisplay()
clearCurrentDisplay()
}
function updateDisplays(val){
currentDisplay = val;
updateCurrentDisplay();
//clear overall
let overallDisplayArea = document.getElementById("overall");
overallDisplayArea.style.display = "none";
}
function calculate(){
try{
const result = eval(overallDisplay + currentDisplay);
currentDisplay = "\n=" + result;
}
catch(error){
const result = "ERROR";
currentDisplay = "\n=" + result;
}
updateDisplays(currentDisplay);
resultDisplay = true;
}
document.addEventListener("keydown", (event) =&gt; {
const keyName = event.key;
if(keyName === "1") appendToDisplay('1');
else if(keyName === "2") appendToDisplay('2');
else if(keyName === "3") appendToDisplay('3');
else if(keyName === "4") appendToDisplay('4');
else if(keyName === "5") appendToDisplay('5');
else if(keyName === "6") appendToDisplay('6');
else if(keyName === "7") appendToDisplay('7');
else if(keyName === "8") appendToDisplay('8');
else if(keyName === "9") appendToDisplay('9');
else if(keyName === "0") appendToDisplay('0');
else if(keyName === "+") appendToOperator('+');
else if(keyName === "-") appendToOperator('-');
else if(keyName === "*") appendToOperator('*');
else if(keyName === "/") appendToOperator('/');
else if(keyName === "Backspace") clearDisplay();
else if(keyName === "Enter") calculate();
});

HTML

&lt;!DOCTYPE html&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;script src="script.js"&gt;&lt;/script&gt;
        &lt;link rel="stylesheet" href="styles.css"/&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;div class="calculator"&gt;
            &lt;div id="overall"&gt;&lt;/div&gt;
            &lt;div class="calculator__output" id="output"&gt;0&lt;/div&gt;
            &lt;div class="calculator__keys"&gt;
                &lt;button class="calculator__key calculator__key--operator" onclick="appendOperator"&gt;+&lt;/button&gt;
                &lt;button class="calculator__key calculator__key--operator"&gt;-&lt;/button&gt;
                &lt;button class="calculator__key calculator__key--operator"&gt;&amp;times;&lt;/button&gt;
                &lt;button class="calculator__key calculator__key--operator"&gt;÷&lt;/button&gt;
                &lt;button class="calculator__key" onclick="appendToDisplay('7')"&gt;7&lt;/button&gt;
                &lt;button class="calculator__key" onclick="appendToDisplay('8')"&gt;8&lt;/button&gt;
                &lt;button class="calculator__key" onclick="appendToDisplay('9')"&gt;9&lt;/button&gt;
                &lt;button class="calculator__key" onclick="appendToDisplay('4')"&gt;4&lt;/button&gt;
                &lt;button class="calculator__key" onclick="appendToDisplay('5')"&gt;5&lt;/button&gt;
                &lt;button class="calculator__key" onclick="appendToDisplay('6')"&gt;6&lt;/button&gt;
                &lt;button class="calculator__key" onclick="appendToDisplay('1')"&gt;1&lt;/button&gt;
                &lt;button class="calculator__key" onclick="appendToDisplay('2')"&gt;2&lt;/button&gt;
                &lt;button class="calculator__key" onclick="appendToDisplay('3')"&gt;3&lt;/button&gt;
                &lt;button class="calculator__key" onclick="appendToDisplay('0')"&gt;0&lt;/button&gt;
                &lt;button class="calculator__key" onclick="appendToDisplay('.')"&gt;.&lt;/button&gt;
                &lt;button class="calculator__key" onclick="clearDisplay()"&gt;AC&lt;/button&gt;
                &lt;button class="calculator__key calculator__key--enter" onclick="calculate()"&gt;=&lt;/button&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;

I'm building a calculator app but the problem occur when i try to clear() the old chunk data. Is this code look messy or is it better because this my first time using JS

reddit.com
u/Inevitable_Cellist93 — 4 days ago

I wrote an article about JavaScript iterators

I'm writing articles as a way to deepen my understanding of JS/TS and to help spread that knowledge. This one is all about iterators. I start with the snippet below and build up to custom iterators. Enjoy!

const arr = [1, 2, 3];

// `for...of` loops use iterators
for (const el of arr) {
  // do something
}

Learn more here.

reddit.com
u/no_em_dash — 4 days ago

i have 3 weeks what to learn next ? as i don't have a life outside this | i know vanilla JS ( doing D.O.M will probably complete it in a week ) i don't know frameworks yet !!

( i have 3 weeks from 5 may to 26 may )

i will have nearly good numbers of hours and i am planning to go all in i dont care about sleep or life all i want is be great , i have great iq and i can learn things fast

what should i keep as my goal ? give me delusional goal and i will try to chase it

being delusional and see what human limits can achieve .

let me know i will chase that goal with projects and understanding .

reddit.com
u/MuchYoung374 — 4 days ago

Do people still use var in JavaScript?

I usually see let and const everywhere, and I understand why they are preferred because they are block-scoped and safer.

But I also heard an opinion that var can still be useful when declaring variables inside a function, because it makes it clear that the variable belongs to the whole function scope and may be used across different blocks inside that function.

For example, let feels more natural for variables inside blocks like if, try/catch, loops, etc., while var could theoretically show that the variable is intended to be available throughout the function. Does anyone actually think about var this way, or is var basically avoided completely in modern JavaScript?

reddit.com
u/Apart-Scientist-8590 — 5 days ago