alexrsworld 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/games.json CHANGED
@@ -1419,8 +1419,8 @@
1419
1419
 
1420
1420
 
1421
1421
  {
1422
- "title": "Ultimate Custom Night",
1423
- "img": "https://raw.githubusercontent.com/dskjfoisjfsjio/dskjfoisjfsjio.github.io/main/assets/game%20images/ucn.jpg",
1422
+ "title": "FNAF: Ultimate Custom Night",
1423
+ "img": "https://raw.githubusercontent.com/dskjfoisjfsjio/Standalone-games/main/assets/ultimatecustomnight.webp",
1424
1424
  "description": "Ultimate Custom Night is a horror game where you are able to customize how the night plays out.",
1425
1425
  "path": "Games/standalone/ultimatecustomnight.html",
1426
1426
  "category": "Challenging",
@@ -2338,6 +2338,33 @@
2338
2338
  "iframe": true
2339
2339
  },
2340
2340
 
2341
+ {
2342
+ "title": "Donkey Kong Country",
2343
+ "img": "https://raw.githubusercontent.com/dskjfoisjfsjio/Standalone-games/main/assets/donkeykongcountry.jpg",
2344
+ "description": "Join Donkey Kong and Diddy Kong on a jungle adventure in this classic platformer.",
2345
+ "path": "Games/emulated/SNES/donkeykongcountry.html",
2346
+ "category": "Adventure",
2347
+ "iframe": true
2348
+ },
2349
+
2350
+ {
2351
+ "title": "Donkey Kong Country 2",
2352
+ "img": "https://raw.githubusercontent.com/dskjfoisjfsjio/Standalone-games/main/assets/donkeykongcountry2.jpg",
2353
+ "description": "Join Diddy Kong and Dixie Kong on a new adventure to rescue Donkey Kong in this classic platformer sequel.",
2354
+ "path": "Games/emulated/SNES/donkeykongcountry2.html",
2355
+ "category": "Adventure",
2356
+ "iframe": true
2357
+ },
2358
+
2359
+ {
2360
+ "title": "Donkey Kong Country 3",
2361
+ "img": "https://raw.githubusercontent.com/dskjfoisjfsjio/Standalone-games/main/assets/donkeykongcountry3.webp",
2362
+ "description": "Join Dixie Kong and Kiddy Kong on a new adventure to rescue Donkey Kong and Diddy Kong!",
2363
+ "path": "Games/emulated/SNES/donkeykongcountry3.html",
2364
+ "category": "Adventure",
2365
+ "iframe": true
2366
+ },
2367
+
2341
2368
  {
2342
2369
  "title": "Soundboard",
2343
2370
  "img": "https://raw.githubusercontent.com/dskjfoisjfsjio/dskjfoisjfsjio.github.io/main/assets/game%20images/soundboard.png",
package/index.html CHANGED
@@ -4,6 +4,7 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Alexr's World</title>
7
+ <link rel="icon" href="new logo.png">
7
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
8
9
  <style>
9
10
 
@@ -817,6 +818,15 @@ body.theme-red .game-modal > div:first-child { background: #3a0000 !important; c
817
818
  .tab-btn { display: inline-block; font-size: 0.95rem; }
818
819
  .library-overlay .lib-header, .otherOverlay .lib-header { padding-left: 10px; padding-right: 10px; }
819
820
  }
821
+
822
+ .lib-card.dragging {
823
+ opacity: 0.4;
824
+ transform: scale(0.95);
825
+ }
826
+ .lib-card.drag-over {
827
+ outline: 3px solid var(--ps-light-blue);
828
+ }
829
+
820
830
  </style>
821
831
  </head>
822
832
  <body>
@@ -824,7 +834,7 @@ body.theme-red .game-modal > div:first-child { background: #3a0000 !important; c
824
834
 
825
835
  <div class="top-bar">
826
836
  <div class="site-title-group">
827
- <div class="site-title"><img src="/new logo.png" alt="Alexr's World Logo"> Alexr's World</div>
837
+ <div class="site-title"><img src="new logo.png" alt="Alexr's World Logo"> Alexr's World</div>
828
838
  </div>
829
839
 
830
840
  <div class="nav-hint" id="navHint">Navigate with &larr;&rarr; Arrow Keys or Mouse</div>
@@ -894,7 +904,10 @@ body.theme-red .game-modal > div:first-child { background: #3a0000 !important; c
894
904
  </div>
895
905
 
896
906
  <div id="other_changelog">
897
- <p>12-14-25: Beta release</p>
907
+ <p>12-14-25 Beta V1: Beta release</p>
908
+ <p>12-15-25 Beta V2: Bug Fixes and implemented pokemon games and more!</p>
909
+ <p>12-17-25: Beta V3: More bug fixes and implement FNAF 4 Halloween and Ultimate Custom Night</p>
910
+ <p>12-18-25: V1.0: RELEASE! You can now drag and drop cards on menu. Added Donkey Kong Country 1-3.</p>
898
911
  </div>
899
912
 
900
913
  <div id="other_proxy" style="display:none;">
@@ -975,6 +988,9 @@ body.theme-red .game-modal > div:first-child { background: #3a0000 !important; c
975
988
  </div>
976
989
 
977
990
  <script>
991
+
992
+ let draggedLibTitle = null;
993
+
978
994
  const carousel = document.getElementById('carousel');
979
995
  const infoArea = document.getElementById('infoArea');
980
996
  const libOverlay = document.getElementById('libraryOverlay');
@@ -1237,71 +1253,74 @@ body.theme-red .game-modal > div:first-child { background: #3a0000 !important; c
1237
1253
  }
1238
1254
 
1239
1255
 
1240
- async function loadGames() {
1241
- loadFavorites();
1256
+ async function loadGames() {
1257
+ loadFavorites();
1242
1258
 
1243
-
1244
- localStorage.removeItem('alexrGames_allGamesData');
1245
-
1246
-
1247
- try {
1248
- const response = await fetch('https://raw.githubusercontent.com/dskjfoisjfsjio/alexrsworld/main/games.json');
1249
- if (!response.ok) {
1250
- throw new Error(`HTTP error! status: ${response.status}`);
1251
- }
1252
- const data = await response.json();
1253
-
1254
-
1255
- allGamesData = Array.isArray(data) ? data : data.allGamesData || [];
1259
+ localStorage.removeItem('alexrGames_allGamesData');
1260
+
1261
+ try {
1262
+ const response = await fetch('https://raw.githubusercontent.com/dskjfoisjfsjio/alexrsworld/main/games.json?t=' + Date.now());
1263
+ if (!response.ok) {
1264
+ throw new Error(`HTTP error! status: ${response.status}`);
1265
+ }
1266
+ const data = await response.json();
1267
+
1268
+ allGamesData = Array.isArray(data) ? data : data.allGamesData || [];
1256
1269
 
1257
- if (allGamesData.length === 0) {
1258
- console.warn('games.json was empty or incorrectly formatted.');
1259
- }
1270
+ allGamesData.sort((a, b) => {
1271
+ return a.title.localeCompare(b.title, undefined, {
1272
+ numeric: true,
1273
+ sensitivity: 'base'
1274
+ });
1275
+ });
1260
1276
 
1261
- try {
1262
- const savedCustom = JSON.parse(localStorage.getItem('alexrGames_customOrder') || '[]');
1263
- if (Array.isArray(savedCustom) && savedCustom.length) {
1264
- const map = new Map(allGamesData.map(g => [g.title, g]));
1265
- const reordered = [];
1266
- savedCustom.forEach(title => {
1267
- if (map.has(title)) {
1268
- reordered.push(map.get(title));
1269
- map.delete(title);
1270
- }
1271
- });
1272
- for (const g of allGamesData) {
1273
- if (map.has(g.title)) reordered.push(g);
1274
- }
1275
- allGamesData = reordered;
1276
- } else {
1277
- const savedRecent = JSON.parse(localStorage.getItem('alexrGames_recent') || '[]');
1278
- if (Array.isArray(savedRecent) && savedRecent.length) {
1279
- const map = new Map(allGamesData.map(g => [g.title, g]));
1280
- const reordered = [];
1281
- savedRecent.forEach(title => {
1282
- if (map.has(title)) {
1283
- reordered.push(map.get(title));
1284
- map.delete(title);
1285
- }
1286
- });
1287
- for (const g of allGamesData) {
1288
- if (map.has(g.title)) reordered.push(g);
1289
- }
1290
- allGamesData = reordered;
1277
+ if (allGamesData.length === 0) {
1278
+ console.warn('games.json was empty or incorrectly formatted.');
1279
+ }
1280
+
1281
+ try {
1282
+ const savedCustom = JSON.parse(localStorage.getItem('alexrGames_customOrder') || '[]');
1283
+ if (Array.isArray(savedCustom) && savedCustom.length) {
1284
+ const map = new Map(allGamesData.map(g => [g.title, g]));
1285
+ const reordered = [];
1286
+ savedCustom.forEach(title => {
1287
+ if (map.has(title)) {
1288
+ reordered.push(map.get(title));
1289
+ map.delete(title);
1290
+ }
1291
+ });
1292
+ for (const g of allGamesData) {
1293
+ if (map.has(g.title)) reordered.push(g);
1294
+ }
1295
+ allGamesData = reordered;
1296
+ } else {
1297
+ const savedRecent = JSON.parse(localStorage.getItem('alexrGames_recent') || '[]');
1298
+ if (Array.isArray(savedRecent) && savedRecent.length) {
1299
+ const map = new Map(allGamesData.map(g => [g.title, g]));
1300
+ const reordered = [];
1301
+ savedRecent.forEach(title => {
1302
+ if (map.has(title)) {
1303
+ reordered.push(map.get(title));
1304
+ map.delete(title);
1291
1305
  }
1306
+ });
1307
+ for (const g of allGamesData) {
1308
+ if (map.has(g.title)) reordered.push(g);
1292
1309
  }
1293
- } catch (e) {
1294
- console.warn('Failed to apply saved ordering:', e);
1310
+ allGamesData = reordered;
1295
1311
  }
1296
-
1297
- } catch(e) {
1298
- console.error("Failed to fetch games.json. Please ensure the file exists and is valid JSON.", e);
1299
- allGamesData = [];
1300
1312
  }
1301
-
1302
- buildLists();
1313
+ } catch (e) {
1314
+ console.warn('Failed to apply saved ordering:', e);
1303
1315
  }
1304
1316
 
1317
+ } catch(e) {
1318
+ console.error("Failed to fetch games.json. Please ensure the file exists and is valid JSON.", e);
1319
+ allGamesData = [];
1320
+ }
1321
+
1322
+ buildLists();
1323
+ }
1305
1324
  function buildLists() {
1306
1325
  const firstSix = allGamesData.slice(0, 6);
1307
1326
 
@@ -1517,79 +1536,120 @@ body.theme-red .game-modal > div:first-child { background: #3a0000 !important; c
1517
1536
  renderOverlayGrid();
1518
1537
  }
1519
1538
 
1520
- function renderOverlayGrid() {
1521
- libGrid.innerHTML = '';
1522
- let gamesToShow = [];
1539
+ function renderOverlayGrid() {
1540
+ libGrid.innerHTML = '';
1541
+ let gamesToShow = [];
1523
1542
 
1524
- if (currentOverlayMode === 'library') {
1525
- libraryTitle.textContent = 'All Games';
1526
- gamesToShow = allGamesData;
1527
-
1528
-
1529
- const searchTerm = libSearchInput.value.toLowerCase().trim();
1530
-
1531
- gamesToShow = gamesToShow.filter(game => {
1532
- const matchesSearch = !searchTerm || game.title.toLowerCase().includes(searchTerm);
1533
- const matchesCategory = currentCategoryFilter === 'All' || game.category === currentCategoryFilter;
1534
- return matchesSearch && matchesCategory;
1535
- });
1543
+ if (currentOverlayMode === 'library') {
1544
+ libraryTitle.textContent = 'All Games';
1545
+ gamesToShow = allGamesData;
1546
+
1547
+ const searchTerm = libSearchInput.value.toLowerCase().trim();
1548
+
1549
+ gamesToShow = gamesToShow.filter(game => {
1550
+ const matchesSearch = !searchTerm || game.title.toLowerCase().includes(searchTerm);
1551
+ const matchesCategory = currentCategoryFilter === 'All' || game.category === currentCategoryFilter;
1552
+ return matchesSearch && matchesCategory;
1553
+ });
1536
1554
 
1537
- } else {
1538
- libraryTitle.textContent = 'Your Favorites';
1539
- gamesToShow = allGamesData.filter(g => favoritesSet.has(g.title));
1540
-
1541
- const searchTerm = libSearchInput.value.toLowerCase().trim();
1542
- gamesToShow = gamesToShow.filter(game => {
1543
- const matchesSearch = !searchTerm || game.title.toLowerCase().includes(searchTerm);
1544
- const matchesCategory = currentCategoryFilter === 'All' || game.category === currentCategoryFilter;
1545
- return matchesSearch && matchesCategory;
1546
- });
1547
- }
1555
+ } else {
1556
+ libraryTitle.textContent = 'Your Favorites';
1557
+ gamesToShow = allGamesData.filter(g => favoritesSet.has(g.title));
1558
+
1559
+ const searchTerm = libSearchInput.value.toLowerCase().trim();
1560
+ gamesToShow = gamesToShow.filter(game => {
1561
+ const matchesSearch = !searchTerm || game.title.toLowerCase().includes(searchTerm);
1562
+ const matchesCategory = currentCategoryFilter === 'All' || game.category === currentCategoryFilter;
1563
+ return matchesSearch && matchesCategory;
1564
+ });
1565
+ }
1548
1566
 
1549
- gamesToShow.forEach((game) => {
1550
- const card = document.createElement('div');
1551
- card.className = 'lib-card';
1552
- card.innerHTML = `
1553
- <img src="${game.img || ''}" onerror="this.style.display='none'">
1554
- <button class="lib-fav-btn" aria-label="${favoritesSet.has(game.title) ? 'Unfavorite' : 'Favorite'}">
1555
- <i class="${favoritesSet.has(game.title) ? 'fas' : 'far'} fa-heart"></i>
1556
- </button>
1557
- <div class="lib-card-title">${game.title}</div>
1558
- `;
1559
-
1560
- const favBtn = card.querySelector('.lib-fav-btn');
1561
- if (favBtn) {
1562
- if (favoritesSet.has(game.title)) favBtn.classList.add('favorited');
1563
- favBtn.addEventListener('click', (e) => {
1564
- e.stopPropagation();
1565
- if (favoritesSet.has(game.title)) {
1566
- favoritesSet.delete(game.title);
1567
- favBtn.classList.remove('favorited');
1568
- const icon = favBtn.querySelector('i'); if (icon) icon.className = 'far fa-heart';
1569
- favBtn.setAttribute('aria-label','Favorite');
1570
- } else {
1571
- favoritesSet.add(game.title);
1572
- favBtn.classList.add('favorited');
1573
- const icon = favBtn.querySelector('i'); if (icon) icon.className = 'fas fa-heart';
1574
- favBtn.setAttribute('aria-label','Unfavorite');
1575
- }
1576
- saveFavorites();
1577
- playSound('select');
1567
+ gamesToShow.forEach((game) => {
1568
+ const card = document.createElement('div');
1569
+ card.draggable = true;
1578
1570
 
1579
- if (currentOverlayMode === 'favorites') renderOverlayGrid();
1580
- try { updateFavoriteTile(displayList[selectedIndex]); } catch(e) {}
1581
- });
1571
+ card.addEventListener('dragstart', () => {
1572
+ draggedLibTitle = game.title;
1573
+ card.classList.add('dragging');
1574
+ playSound('hover');
1575
+ });
1576
+
1577
+ card.addEventListener('dragend', () => {
1578
+ draggedLibTitle = null;
1579
+ card.classList.remove('dragging');
1580
+ document.querySelectorAll('.lib-card').forEach(c => c.classList.remove('drag-over'));
1581
+ });
1582
+
1583
+ card.addEventListener('dragover', (e) => {
1584
+ e.preventDefault();
1585
+ card.classList.add('drag-over');
1586
+ });
1587
+
1588
+ card.addEventListener('dragleave', () => {
1589
+ card.classList.remove('drag-over');
1590
+ });
1591
+
1592
+ card.addEventListener('drop', (e) => {
1593
+ e.preventDefault();
1594
+ card.classList.remove('drag-over');
1595
+
1596
+ if (!draggedLibTitle || draggedLibTitle === game.title) return;
1597
+
1598
+ const fromIndex = allGamesData.findIndex(g => g.title === draggedLibTitle);
1599
+ const toIndex = allGamesData.findIndex(g => g.title === game.title);
1600
+
1601
+ if (fromIndex === -1 || toIndex === -1) return;
1602
+
1603
+ const [moved] = allGamesData.splice(fromIndex, 1);
1604
+ allGamesData.splice(toIndex, 0, moved);
1605
+
1606
+ playSound('select');
1607
+ saveGameOrder();
1608
+ renderOverlayGrid();
1609
+ });
1610
+
1611
+ card.className = 'lib-card';
1612
+ card.innerHTML = `
1613
+ <img src="${game.img || ''}" onerror="this.style.display='none'">
1614
+ <button class="lib-fav-btn" aria-label="${favoritesSet.has(game.title) ? 'Unfavorite' : 'Favorite'}">
1615
+ <i class="${favoritesSet.has(game.title) ? 'fas' : 'far'} fa-heart"></i>
1616
+ </button>
1617
+ <div class="lib-card-title">${game.title}</div>
1618
+ `;
1619
+
1620
+ const favBtn = card.querySelector('.lib-fav-btn');
1621
+ if (favBtn) {
1622
+ if (favoritesSet.has(game.title)) favBtn.classList.add('favorited');
1623
+ favBtn.addEventListener('click', (e) => {
1624
+ e.stopPropagation();
1625
+ if (favoritesSet.has(game.title)) {
1626
+ favoritesSet.delete(game.title);
1627
+ favBtn.classList.remove('favorited');
1628
+ const icon = favBtn.querySelector('i'); if (icon) icon.className = 'far fa-heart';
1629
+ favBtn.setAttribute('aria-label','Favorite');
1630
+ } else {
1631
+ favoritesSet.add(game.title);
1632
+ favBtn.classList.add('favorited');
1633
+ const icon = favBtn.querySelector('i'); if (icon) icon.className = 'fas fa-heart';
1634
+ favBtn.setAttribute('aria-label','Unfavorite');
1582
1635
  }
1636
+ saveFavorites();
1637
+ playSound('select');
1583
1638
 
1584
- card.onclick = () => {
1585
- playSound('select');
1586
- toggleOverlay(false);
1587
- launchGame(game);
1588
- };
1589
- libGrid.appendChild(card);
1639
+ if (currentOverlayMode === 'favorites') renderOverlayGrid();
1640
+ try { updateFavoriteTile(displayList[selectedIndex]); } catch(e) {}
1590
1641
  });
1591
1642
  }
1592
1643
 
1644
+ card.onclick = () => {
1645
+ playSound('select');
1646
+ toggleOverlay(false);
1647
+ launchGame(game);
1648
+ };
1649
+ libGrid.appendChild(card);
1650
+ });
1651
+ }
1652
+
1593
1653
  function updateSelection(index) {
1594
1654
  if(isLibraryOpen || isOtherOpen || document.querySelector('.game-modal')) return;
1595
1655
  if(index < 0) index = 0;
@@ -2207,7 +2267,7 @@ body.theme-red .game-modal > div:first-child { background: #3a0000 !important; c
2207
2267
 
2208
2268
  if (delta > 0) {
2209
2269
  updateSelection(Math.min(displayList.length - 1, selectedIndex + 1));
2210
- } else {
2270
+ } else {a
2211
2271
  updateSelection(Math.max(0, selectedIndex - 1));
2212
2272
  }
2213
2273
 
@@ -2296,6 +2356,15 @@ body.theme-red {
2296
2356
  linear-gradient(135deg, #3a0000, #7a0000) !important;
2297
2357
  --ps-light-blue: #ff4d4d !important;
2298
2358
  }
2359
+
2360
+ .lib-card.dragging {
2361
+ opacity: 0.4;
2362
+ transform: scale(0.95);
2363
+ }
2364
+ .lib-card.drag-over {
2365
+ outline: 3px solid var(--ps-light-blue);
2366
+ }
2367
+
2299
2368
  </style>
2300
2369
 
2301
2370
  </body>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "alexrsworld",
3
- "version": "1.0.0",
4
- "description": "This is in beta. Not everything is final or perfect yet. Expect some glitches and bugs here and there.",
3
+ "version": "1.0.1",
4
+ "description": "Released! Will improve overtime.",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"