adblock check

⌜ łĠÖȒ_02022010 ⌟

IGOR2221
14 часов
HAPPYMOD
IGOR2221
22 часа
Подкрутил иконку к игре, н а так у меня пока не многовато приложений в HENCORE OS (Потому что я клонирую проги из SHINKOR OS а это геморойно немного )
IGOR2221
1 день
IGOR2221
1 день
<!DOCTYPE html>
<!-- saved from url=(0066)file:///C:/Users/Lenovo/Desktop/Игры/0999.html -->
<html lang=«ru»><head><meta http-equiv=«Content-Type» content=«text/html; charset=UTF-8»>

<title>M-Studio — Игры</title>
<style>
* {
box-sizing: border-box;
}

body {
background: radial-gradient(1200px 600px at 50% -10%, #1c1c24 0%, #0d0d0f 60%, #0a0a0b 100%);
font-family: 'Segoe UI', Arial, sans-serif;
margin: 0;
padding: 0;
color: #e6e6e6;
min-height: 100vh;
}

.container {
max-width: 960px;
margin: auto;
padding: 20px;
}

header {
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
padding-bottom: 20px;
margin-bottom: 30px;
text-align: center;
}

h1 {
font-size: 34px;
text-transform: uppercase;
letter-spacing: 4px;
margin: 0;
color: #ffffff;
text-shadow: 0 0 24px rgba(120, 140, 255, 0.45);
}

.subtitle {
font-size: 16px;
color: #8a8a9a;
margin-top: 8px;
font-style: italic;
}

.social-links {
margin-top: 16px;
}

.social-links a {
display: inline-block;
margin: 0 6px;
text-decoration: none;
color: #dcdce6;
border: 1px solid rgba(255, 255, 255, 0.15);
padding: 8px 20px;
background: rgba(255, 255, 255, 0.05);
border-radius: 24px;
backdrop-filter: blur(6px);
transition: all 0.25s ease;
}

.social-links a:hover {
background: rgba(120, 140, 255, 0.18);
border-color: rgba(120, 140, 255, 0.6);
box-shadow: 0 0 16px rgba(120, 140, 255, 0.35);
transform: translateY(-2px);
}

.games-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 22px;
}

.game-card {
border: 1px solid rgba(255, 255, 255, 0.1);
background: linear-gradient(160deg, rgba(255, 255, 255, 0.07) 0%, rgba(255, 255, 255, 0.02) 100%);
border-radius: 18px;
padding: 24px 16px;
text-align: center;
transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}

.game-card:hover {
transform: translateY(-4px);
border-color: rgba(120, 140, 255, 0.45);
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.55);
}

.game-title {
font-weight: bold;
font-size: 19px;
margin-bottom: 8px;
color: #ffffff;
letter-spacing: 0.5px;
}

.game-card p {
color: #9a9aa8;
font-size: 14px;
margin: 0 0 6px;
}

.play-btn {
display: inline-block;
margin-top: 10px;
padding: 10px 24px;
background: linear-gradient(135deg, #3ddc84, #1faa5a);
color: #ffffff;
text-decoration: none;
border-radius: 10px;
font-weight: bold;
transition: all 0.25s ease;
}

.play-btn:hover {
box-shadow: 0 0 18px rgba(61, 220, 132, 0.45);
transform: translateY(-2px);
}

.download-btn {
display: inline-block;
margin-top: 10px;
padding: 10px 24px;
background: linear-gradient(135deg, #ff7043, #e64a19);
color: #ffffff;
text-decoration: none;
border-radius: 10px;
font-weight: bold;
transition: all 0.25s ease;
}

.download-btn:hover {
box-shadow: 0 0 18px rgba(255, 112, 67, 0.45);
transform: translateY(-2px);
}

footer {
margin-top: 36px;
border-top: 1px solid rgba(255, 255, 255, 0.08);
padding-top: 16px;
font-size: 13px;
color: #6a6a78;
text-align: center;
}
</style>

</head>
<body>
<div class=«container»>
<header>
<h1 style=«color:#f0f0f0»>M-Studio</h1>
<p class=«subtitle»>Наш сайт тут!</p>
<div class=«social-links»>
<a class=«canal333» href=«web.telegram.org/k/#@M209studio»>Telegram</a>
<a class=«canal333» href=«vk.ru/im/channels/-240709384?entrypoint=channel&tab=all»>VK</a>
</div>
</header>

<section class=«games-grid»>
<!-- Кликер -->
<div class=«game-card»>
<div class=«game-title»>M-Clicker</div>
<p>Кликер в браузере</p>
<a href=«play.unity.com/ru/user/9dacca9a-b93f-41fa-813d-e3bcbfc03d3d» class=«play-btn» target="_blank">Играть</a>
</div>

<!-- Танчики -->
<div class=«game-card»>
<div class=«game-title»>Tank Brawl</div>
<p>Танковые сражения онлайн</p>
<a href=«vid209.github.io/Tank-Brawl/» class=«play-btn» target="_blank">Играть</a>
</div>

<!-- Змейка -->
<div class=«game-card»>
<div class=«game-title»>Змейка</div>
<p>Классическая змейка для ПК</p>
<a href=«drive.google.com/file/d/1tSiTzl4d2FcMw7dnRFQSm88eKmQVpbzB/view?usp=drive_link» class=«download-btn» download="">Скачать EXE</a>
</div>
</section>

<footer>
© 2026 M-Studio.
</footer>
</div>

</body></html>
IGOR2221
1 день
Ну а я его как приложения в новую ос интегрировал, думаю делать релиз HENCORE OS Portable в 1 ноября
IGOR2221
1 день
А ты же не против если я твою игру добавлю в свою ос HENCORE OS Portable (Находится на стадии разработки и ещё не бла выложена в интернет)
IGOR2221
1 день
<!DOCTYPE html>
<html lang=«ru»>
<head>
<meta charset=«UTF-8»>
<meta name=«viewport» content=«width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no»>
<title>TANK BRAWL</title>
<style>
* { user-select: none; -webkit-tap-highlight-color: transparent; box-sizing: border-box; }
body {
margin: 0;
min-height: 100vh;
background: #0a0a0a;
display: flex;
justify-content: center;
align-items: center;
font-family: 'Courier New', monospace;
touch-action: none;
overflow: hidden;
filter: grayscale(1) contrast(1.05);
filter: grayscale(1) contrast(1.05);
width: 100%;
height: 100%;
position: fixed;
}
.menu {
background: #141414;
border: 1px solid #333333;
border-radius: 18px;
padding: 18px;
max-width: 480px;
width: 92%;
text-align: center;
max-height: 95vh;
overflow-y: auto;
}
.menu h1 { font-size: 1.5rem; color: #f2f2f2; margin: 0 0 10px; letter-spacing: 2px; }
.menu h2 { font-size: 0.9rem; color: #8f8f8f; margin: 12px 0 5px; text-transform: uppercase; letter-spacing: 1px; }
.mode-btn {
background: #1f1f1f;
border: none;
padding: 11px;
border-radius: 40px;
font-weight: bold;
font-size: 0.9rem;
cursor: pointer;
color: #eaeaea;
font-family: monospace;
width: 100%;
margin: 4px 0;
touch-action: manipulation;
}
.mode-btn:hover { border-color: #6a6a6a; }
.mode-btn:active { transform: scale(0.97); }
.mode-btn.bots { background: #222222; }
.mode-btn.ctf { background: #262626; }
.mode-btn.pvp { background: #2a2a2a; }
.mode-btn.online { background: #2e2e2e; }
.mode-btn.selected { background: #f2f2f2; color: #0a0a0a; border-color: #ffffff; box-shadow: 0 0 12px rgba(255,255,255,0.35); }
.map-btn {
background: #1f1f1f;
border: 1px solid #3a3a3a;
border-radius: 30px;
padding: 8px;
font-weight: bold;
font-size: 0.75rem;
cursor: pointer;
color: #cfcfcf;
font-family: monospace;
width: 48%;
margin: 3px 1%;
touch-action: manipulation;
display: inline-block;
}
.map-btn.selected { background: #f2f2f2; color: #0a0a0a; border-color: #ffffff; }
.players-btn {
background: #1f1f1f;
border: 1px solid #3a3a3a;
border-radius: 30px;
padding: 8px;
font-weight: bold;
font-size: 0.8rem;
cursor: pointer;
color: #cfcfcf;
font-family: monospace;
width: 30%;
margin: 3px 1%;
touch-action: manipulation;
display: inline-block;
}
.players-btn.selected { background: #f2f2f2; color: #0a0a0a; border-color: #ffffff; }
.network-panel {
background: #101010;
border-radius: 20px;
padding: 12px;
margin-top: 8px;
}
.network-panel input {
background: #1a1a1a;
border: 2px solid #4a4a4a;
padding: 9px;
border-radius: 30px;
font-family: monospace;
color: #eaeaea;
font-size: 0.85rem;
width: 100%;
margin: 4px 0;
text-align: center;
}
.status-text {
color: #8f8f8f;
font-size: 0.7rem;
margin-top: 6px;
text-align: center;
}
.game-container {
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
height: 100vh;
padding: 4px;
touch-action: none;
}
.info {
display: flex;
justify-content: space-between;
width: 100%;
max-width: 800px;
padding: 6px 14px;
background: rgba(20,20,20,0.85);
border-radius: 30px;
color: #eaeaea;
font-weight: bold;
font-size: 0.75rem;
margin-bottom: 4px;
flex-shrink: 0;
}
canvas {
box-shadow: 0 0 0 2px #333333, 0 20px 50px rgba(0,0,0,0.8);
border-radius: 14px;
width: 100%;
height: auto;
max-width: 800px;
touch-action: none;
background: #1a1a1a;
flex-shrink: 0;
}
.touch-controls {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
max-width: 800px;
padding: 8px 12px;
margin-top: 6px;
flex-shrink: 0;
gap: 20px;
}
/* ========= КРЕСТОВИНА ========= */
.joystick {
position: relative;
width: 170px;
height: 170px;
touch-action: none;
}
.joystick-base {
position: absolute;
top: 0; left: 0;
width: 170px;
height: 170px;
background: radial-gradient(circle, #1f1f1f, #0f0f0f);
border: 3px solid #4a4a4a;
border-radius: 50%;
box-shadow: inset 0 0 15px #000, 0 3px 0 #000000;
}
.joystick-cross {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
pointer-events: none;
}
.joystick-cross::before {
content: '';
position: absolute;
top: 50%; left: 15%;
width: 70%; height: 4px;
background: #3a3a3a;
transform: translateY(-50%);
border-radius: 2px;
}
.joystick-cross::after {
content: '';
position: absolute;
left: 50%; top: 15%;
width: 4px; height: 70%;
background: #3a3a3a;
transform: translateX(-50%);
border-radius: 2px;
}
.joystick-knob {
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 65px;
height: 65px;
background: radial-gradient(circle, #e8e8e8, #7a7a7a);
border: 2px solid #ffffff;
border-radius: 50%;
box-shadow: 0 4px 8px rgba(0,0,0,0.6);
transition: 0.05s linear;
pointer-events: none;
}
.joystick-arrow {
position: absolute;
color: #eaeaea;
font-size: 1rem;
font-weight: bold;
pointer-events: none;
text-shadow: 0 0 3px black;
}
.joystick-arrow.up { top: 6px; left: 50%; transform: translateX(-50%); }
.joystick-arrow.down { bottom: 6px; left: 50%; transform: translateX(-50%); }
.joystick-arrow.left { left: 6px; top: 50%; transform: translateY(-50%); }
.joystick-arrow.right { right: 6px; top: 50%; transform: translateY(-50%); }

.action-buttons {
display: flex;
flex-direction: column;
gap: 8px;
align-items: center;
}
.fire-btn {
background: #1f1f1f;
border: 3px solid #f2f2f2;
border-radius: 50%;
width: 90px;
height: 90px;
font-size: 2.4rem;
color: white;
display: flex;
align-items: center;
justify-content: center;
touch-action: none;
cursor: pointer;
box-shadow: 0 4px 0 #000000;
}
.fire-btn:active { transform: scale(0.92); box-shadow: 0 1px 0 #000000; }
.small-btn {
background: #222222;
border: 1px solid #4a4a4a;
border-radius: 30px;
padding: 6px 14px;
color: #eaeaea;
font-size: 0.7rem;
font-weight: bold;
touch-action: none;
cursor: pointer;
font-family: monospace;
width: 90px;
}
.small-btn:active { transform: scale(0.95); }
.back-btn {
background: #262626;
border: 2px solid #4a4a4a;
border-radius: 30px;
padding: 6px 14px;
color: #eaeaea;
font-size: 0.7rem;
font-weight: bold;
touch-action: none;
cursor: pointer;
font-family: monospace;
width: 90px;
}
.back-btn:active { transform: scale(0.95); }
@media (min-width: 860px) {
.touch-controls { display: none; }
}
@media (max-width: 550px) {
.joystick { width: 140px; height: 140px; }
.joystick-base { width: 140px; height: 140px; }
.joystick-knob { width: 55px; height: 55px; }
.fire-btn { width: 75px; height: 75px; font-size: 2rem; }
.small-btn, .back-btn { width: 75px; font-size: 0.6rem; padding: 4px 8px; }
.info { font-size: 0.6rem; padding: 4px 10px; }
}
@media (max-width: 400px) {
.joystick { width: 120px; height: 120px; }
.joystick-base { width: 120px; height: 120px; }
.joystick-knob { width: 45px; height: 45px; }
.fire-btn { width: 65px; height: 65px; font-size: 1.6rem; }
.small-btn, .back-btn { width: 65px; font-size: 0.5rem; }
.info { font-size: 0.5rem; padding: 3px 8px; }
.touch-controls { padding: 4px 8px; gap: 10px; }
}
.hidden { display: none !important; }
</style>
</head>
<body>
<div id=«menu» class=«menu»>
<h1> TANK BRAWL </h1>

<h2>🎮 Способ игры:</h2>
<button class=«mode-btn bots» id=«btnOffline» onclick=«selectSource('offline', this)»>🎮 ОФЛАЙН (на 1 ПК)</button>
<button class=«mode-btn online» id=«btnOnline» onclick=«selectSource('online', this)»>🌐 ПО СЕТИ (Hamachi)</button>

<div id=«offlineModes» style=«display:none;»>
<h2>🎯 Офлайн режим:</h2>
<button class=«mode-btn bots» data-mode=«bots» onclick=«selectMode('bots', this)»>🎮 ПРОТИВ БОТОВ</button>
<button class=«mode-btn ctf» data-mode=«ctf» onclick=«selectMode('ctf', this)»>🏁 ЗАХВАТ ФЛАГА</button>
<button class=«mode-btn pvp» data-mode=«pvp» onclick=«selectMode('pvp', this)»>⚔️ PVP 2 ИГРОКА</button>
</div>

<div id=«onlineModes» style=«display:none;»>
<h2>🎯 Сетевой режим:</h2>
<button class=«mode-btn bots» data-mode=«bots» onclick=«selectMode('bots', this)»>🌐 ПРОТИВ БОТОВ</button>
<button class=«mode-btn ctf» data-mode=«ctf» onclick=«selectMode('ctf', this)»>🌐 ЗАХВАТ ФЛАГА</button>
<button class=«mode-btn pvp» data-mode=«pvp» onclick=«selectMode('pvp', this)»>🌐 PVP (все против всех)</button>

<h2>👥 Игроков:</h2>
<div>
<button class=«players-btn» data-players=«2» onclick=«selectPlayers(2, this)»>2</button>
<button class=«players-btn» data-players=«4» onclick=«selectPlayers(4, this)»>4</button>
<button class=«players-btn» data-players=«8» onclick=«selectPlayers(8, this)»>8</button>
</div>

<div id=«networkPanel» class=«network-panel»>
<input type=«text» id=«serverIp» placeholder=«Hamachi-IP (25.x.x.x)» value=«25.0.0.1»>
<input type=«text» id=«serverPort» placeholder=«Порт» value=«8080»>
<div id=«netStatus» class=«status-text»>Введи Hamachi-IP сервера</div>
</div>
</div>

<h2>🗺️ Карта:</h2>
<div>
<button class=«map-btn» data-map=«1» onclick=«selectMap(1, this)»>🗺️ Классика</button>
<button class=«map-btn» data-map=«2» onclick=«selectMap(2, this)»>🗺️ Battle City</button>
<button class=«map-btn» data-map=«3» onclick=«selectMap(3, this)»>🗺️ Лабиринт</button>
<button class=«map-btn» data-map=«4» onclick=«selectMap(4, this)»>🗺️ Крепость</button>
</div>

<button id=«startBtn» class=«mode-btn online» style=«margin-top:12px; font-size:1rem;» onclick=«startSelectedMode()»>▶ НАЧАТЬ ИГРУ</button>
</div>

<div id=«game» class=«game-container hidden»>
<div class=«info»>
<span>❤️ <span id=«healthValue»>3</span></span>
<span>⭐ <span id=«scoreValue»>0</span></span>
<span id=«modeLabel»>🎮 РЕЖИМ</span>
<span id=«mapLabel»>🗺️ Классика</span>
<span id=«playersLabel»>👥 1</span>
</div>
<canvas id=«canvas» width=«800» height=«600»></canvas>

<div class=«touch-controls» id=«touchControls»>
<!-- КРЕСТОВИНА (джойстик) -->
<div class=«joystick» id=«joystick»>
<div class=«joystick-base»></div>
<div class=«joystick-cross»></div>
<div class=«joystick-arrow up»>▲</div>
<div class=«joystick-arrow down»>▼</div>
<div class=«joystick-arrow left»>◀</div>
<div class=«joystick-arrow right»>▶</div>
<div class=«joystick-knob» id=«joystickKnob»></div>
</div>
<div class=«action-buttons»>
<button class=«fire-btn» id=«btnFire»>💥</button>
<button class=«small-btn» id=«btnRestart»>🔄 R</button>
<button class=«back-btn» id=«backBtn»>🏠 МЕНЮ</button>
</div>
</div>
<div id=«onlineStatus» class=«status-text» style=«margin-top:4px;color:#8f8f8f;»></div>
</div>

<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var currentMode = null;
var gameSource = null;
var gameRunning = false;
var gameOver = false;
var score = 0;
var bricks = [];
var ws = null;
var myId = null;
var players = new Map();
var lastSend = 0;
var currentMap = 1;
var maxPlayers = 2;

var selectedSource = null;
var selectedMode = null;
var selectedMap = 1;
var selectedPlayers = 2;

var p1 = { x: 380, y: 520, w: 40, h: 40, dir: 0, health: 3 };
var p1Bullet = { active: false, x: 0, y: 0, speedX: 0, speedY: 0 };
var p1Delay = 0;

var p2 = null;
var p2Bullet = { active: false, x: 0, y: 0, speedX: 0, speedY: 0 };
var p2Delay = 0;

var enemies = [];
var enemyBullets = []; // пули ботов — теперь реально существуют
var flag = { x: 700, y: 80, w: 28, h: 28, captured: false, carrier: null };

var keys = { left: false, right: false, up: false, down: false, fire: false };
var keysP2 = { left: false, right: false, up: false, down: false, fire: false };

var MAPS = {
1: { name: 'Классика', build: function() {
var arr = [];
for (var i = 0; i < 20; i++) { arr.push({ x: i * 42, y: 0, w: 38, h: 38 }); arr.push({ x: i * 42, y: 562, w: 38, h: 38 }); }
for (var i = 0; i < 15; i++) { arr.push({ x: 0, y: i * 42, w: 38, h: 38 }); arr.push({ x: 762, y: i * 42, w: 38, h: 38 }); }
for (var i = 3; i < 18; i += 4) for (var j = 4; j < 10; j += 2) arr.push({ x: i * 42, y: j * 42, w: 38, h: 38 });
return arr;
}},
2: { name: 'Battle City', build: function() {
var arr = [];
for (var i = 0; i < 20; i++) { arr.push({ x: i * 42, y: 0, w: 38, h: 38 }); arr.push({ x: i * 42, y: 562, w: 38, h: 38 }); }
for (var i = 0; i < 15; i++) { arr.push({ x: 0, y: i * 42, w: 38, h: 38 }); arr.push({ x: 762, y: i * 42, w: 38, h: 38 }); }
for (var i = 6; i <= 13; i++) { arr.push({ x: i * 42, y: 6 * 42, w: 38, h: 38 }); arr.push({ x: i * 42, y: 8 * 42, w: 38, h: 38 }); }
for (var j = 3; j <= 6; j++) { arr.push({ x: 9 * 42, y: j * 42, w: 38, h: 38 }); arr.push({ x: 10 * 42, y: j * 42, w: 38, h: 38 }); }
for (var j = 8; j <= 11; j++) { arr.push({ x: 9 * 42, y: j * 42, w: 38, h: 38 }); arr.push({ x: 10 * 42, y: j * 42, w: 38, h: 38 }); }
arr.push({ x: 3*42, y: 3*42, w: 38, h: 38 }); arr.push({ x: 16*42, y: 3*42, w: 38, h: 38 });
arr.push({ x: 3*42, y: 11*42, w: 38, h: 38 }); arr.push({ x: 16*42, y: 11*42, w: 38, h: 38 });
return arr;
}},
3: { name: 'Лабиринт', build: function() {
var arr = [];
for (var i = 0; i < 20; i++) { arr.push({ x: i * 42, y: 0, w: 38, h: 38 }); arr.push({ x: i * 42, y: 562, w: 38, h: 38 }); }
for (var i = 0; i < 15; i++) { arr.push({ x: 0, y: i * 42, w: 38, h: 38 }); arr.push({ x: 762, y: i * 42, w: 38, h: 38 }); }
for (var j = 2; j <= 6; j++) { arr.push({ x: 4 * 42, y: j * 42, w: 38, h: 38 }); arr.push({ x: 15 * 42, y: j * 42, w: 38, h: 38 }); }
for (var j = 8; j <= 12; j++) { arr.push({ x: 4 * 42, y: j * 42, w: 38, h: 38 }); arr.push({ x: 15 * 42, y: j * 42, w: 38, h: 38 }); }
for (var i = 7; i <= 12; i++) { arr.push({ x: i * 42, y: 4 * 42, w: 38, h: 38 }); arr.push({ x: i * 42, y: 10 * 42, w: 38, h: 38 }); }
return arr;
}},
4: { name: 'Крепость', build: function() {
var arr = [];
for (var i = 0; i < 20; i++) { arr.push({ x: i * 42, y: 0, w: 38, h: 38 }); arr.push({ x: i * 42, y: 562, w: 38, h: 38 }); }
for (var i = 0; i < 15; i++) { arr.push({ x: 0, y: i * 42, w: 38, h: 38 }); arr.push({ x: 762, y: i * 42, w: 38, h: 38 }); }
for (var i = 8; i <= 11; i++) { arr.push({ x: i * 42, y: 5 * 42, w: 38, h: 38 }); arr.push({ x: i * 42, y: 10 * 42, w: 38, h: 38 }); }
for (var j = 6; j <= 9; j++) { arr.push({ x: 8 * 42, y: j * 42, w: 38, h: 38 }); arr.push({ x: 11 * 42, y: j * 42, w: 38, h: 38 }); }
for (var i = 2; i <= 4; i++) for (var j = 2; j <= 4; j++) {
arr.push({ x: i * 42, y: j * 42, w: 38, h: 38 }); arr.push({ x: (17 — i) * 42, y: j * 42, w: 38, h: 38 });
arr.push({ x: i * 42, y: (13 — j) * 42, w: 38, h: 38 }); arr.push({ x: (17 — i) * 42, y: (13 — j) * 42, w: 38, h: 38 });
}
return arr;
}}
};

function buildBricks() { return MAPS[currentMap].build(); }

function collide(r1, r2) {
return !(r2.x > r1.x + r1.w || r2.x + r2.w < r1.x || r2.y > r1.y + r1.h || r2.y + r2.h < r1.y);
}

function updateUI() {
document.getElementById('healthValue').innerText = p1.health;
document.getElementById('scoreValue').innerText = score;
document.getElementById('mapLabel').innerText = '🗺️ ' + MAPS[currentMap].name;
document.getElementById('playersLabel').innerText = '👥 ' + (players.size + 1) + '/' + maxPlayers;
}

function restart() {
gameOver = false;
score = 0;
p1 = { x: 380, y: 520, w: 40, h: 40, dir: 0, health: 3 };
p1Bullet = { active: false, x: 0, y: 0, speedX: 0, speedY: 0 };
p1Delay = 0;
bricks = buildBricks();
flag = { x: 700, y: 80, w: 28, h: 28, captured: false, carrier: null };
enemies = [];
enemyBullets = [];

if (currentMode === 'pvp' && gameSource === 'offline') {
p2 = { x: 380, y: 80, w: 40, h: 40, dir: 1, health: 3 };
p2Bullet = { active: false, x: 0, y: 0, speedX: 0, speedY: 0 };
p2Delay = 0;
} else if (currentMode === 'bots' || currentMode === 'ctf') {
for (var i = 0; i < 3; i++) {
enemies.push({ x: 100 + i * 250, y: 80, w: 40, h: 40, dir: 1, moveTimer: 0, shootTimer: Math.floor(Math.random() * 50) });
}
}
updateUI();
}

function moveTank(tank, dx, dy, newDir) {
var newX = tank.x + dx, newY = tank.y + dy;
if (newX < 2) newX = 2;
if (newX > 758) newX = 758;
if (newY < 2) newY = 2;
if (newY > 558) newY = 558;
var oldX = tank.x, oldY = tank.y;
tank.x = newX; tank.y = newY; tank.dir = newDir;
for (var i = 0; i < bricks.length; i++) {
if (collide({x: tank.x, y: tank.y, w: 40, h: 40}, bricks[i])) { tank.x = oldX; tank.y = oldY; break; }
}
}

function shoot(tank, bullet, isP1) {
if (bullet.active) return;
if (isP1 && p1Delay > 0) return;
if (!isP1 && p2Delay > 0) return;
if (isP1) p1Delay = 15; else p2Delay = 15;
bullet.active = true;
if (tank.dir === 0) { bullet.x = tank.x + 16; bullet.y = tank.y; bullet.speedX = 0; bullet.speedY = -8; }
else if (tank.dir === 1) { bullet.x = tank.x + 16; bullet.y = tank.y + 40; bullet.speedX = 0; bullet.speedY = 8; }
else if (tank.dir === 2) { bullet.x = tank.x; bullet.y = tank.y + 16; bullet.speedX = -8; bullet.speedY = 0; }
else { bullet.x = tank.x + 40; bullet.y = tank.y + 16; bullet.speedX = 8; bullet.speedY = 0; }
if (ws && ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify({ type: 'shoot', bullet: bullet, dir: tank.dir }));
}

function updateBullet(bullet, isP1Bullet) {
if (!bullet.active) return;
bullet.x += bullet.speedX; bullet.y += bullet.speedY;
if (bullet.x < -50 || bullet.x > 850 || bullet.y < -50 || bullet.y > 650) { bullet.active = false; return; }
var bulletRect = { x: bullet.x, y: bullet.y, w: 8, h: 8 };
for (var i = 0; i < bricks.length; i++) {
if (collide(bulletRect, bricks[i])) { bricks.splice(i, 1); bullet.active = false; if (isP1Bullet) { score += 10; updateUI(); } return; }
}
if (currentMode === 'pvp' && gameSource === 'offline' && p2 && collide(bulletRect, {x: p2.x, y: p2.y, w: 40, h: 40})) {
p2.health--; bullet.active = false;
if (isP1Bullet) { score += 50; updateUI(); }
if (p2.health <= 0) { score += 200; updateUI(); gameOver = true; }
return;
}
for (var entry of players) {
var id = entry[0], player = entry[1];
if (collide(bulletRect, {x: player.x, y: player.y, w: 40, h: 40})) {
player.health--; bullet.active = false;
if (isP1Bullet) { score += 50; updateUI(); }
if (ws && ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify({ type: 'damage', targetId: id, health: player.health }));
if (player.health <= 0) { players.delete(id); score += 200; updateUI(); }
return;
}
}
for (var i = 0; i < enemies.length; i++) {
if (collide(bulletRect, {x: enemies[i].x, y: enemies[i].y, w: 40, h: 40})) {
enemies.splice(i, 1); bullet.active = false;
if (isP1Bullet) { score += 100; updateUI(); } return;
}
}
}

// ========= БОТЫ: стреляют И УБИВАЮТ =========
function updateEnemies() {
for (var i = 0; i < enemies.length; i++) {
var e = enemies[i];
e.moveTimer++; e.shootTimer++;
if (e.moveTimer > 50) { e.moveTimer = 0; e.dir = Math.floor(Math.random() * 4); }
var oldX = e.x, oldY = e.y;
if (e.dir === 0) e.y -= 2; if (e.dir === 1) e.y += 2;
if (e.dir === 2) e.x -= 2; if (e.dir === 3) e.x += 2;
if (e.x < 2) e.x = 2; if (e.x > 758) e.x = 758;
if (e.y < 2) e.y = 2; if (e.y > 400) e.y = 400;
for (var k = 0; k < bricks.length; k++) {
if (collide({x: e.x, y: e.y, w: 40, h: 40}, bricks[k])) { e.x = oldX; e.y = oldY; break; }
}
// Боты стреляют
if (e.shootTimer > 45) {
e.shootTimer = 0;
var eb = { x: 0, y: 0, w: 8, h: 8, speedX: 0, speedY: 0 };
if (e.dir === 0) { eb.x = e.x+16; eb.y = e.y; eb.speedX = 0; eb.speedY = -6; }
else if (e.dir === 1) { eb.x = e.x+16; eb.y = e.y+40; eb.speedX = 0; eb.speedY = 6; }
else if (e.dir === 2) { eb.x = e.x; eb.y = e.y+16; eb.speedX = -6; eb.speedY = 0; }
else { eb.x = e.x+40; eb.y = e.y+16; eb.speedX = 6; eb.speedY = 0; }
enemyBullets.push(eb);
}
}
// Респавн врагов
if (enemies.length === 0 && !gameOver && (currentMode === 'bots' || currentMode === 'ctf')) {
for (var i = 0; i < 3; i++) {
enemies.push({ x: 100 + i * 250, y: 80, w: 40, h: 40, dir: 1, moveTimer: 0, shootTimer: Math.floor(Math.random() * 50) });
}
}
}

// ========= ПУЛИ БОТОВ ЛЕТЯТ И УБИВАЮТ =========
function updateEnemyBullets() {
for (var i = 0; i < enemyBullets.length; i++) {
var eb = enemyBullets[i];
eb.x += eb.speedX;
eb.y += eb.speedY;
if (eb.x < -50 || eb.x > 850 || eb.y < -50 || eb.y > 650) {
enemyBullets.splice(i, 1); i--; continue;
}
var bulletRect = { x: eb.x, y: eb.y, w: 8, h: 8 };

// УБИВАЕТ ИГРОКА
if (collide(bulletRect, {x: p1.x, y: p1.y, w: 40, h: 40})) {
p1.health--;
updateUI();
enemyBullets.splice(i, 1);
i--;
if (p1.health <= 0) gameOver = true;
continue;
}

// Убивает P2 в офлайн PVP
if (currentMode === 'pvp' && gameSource === 'offline' && p2 && collide(bulletRect, {x: p2.x, y: p2.y, w: 40, h: 40})) {
p2.health--;
enemyBullets.splice(i, 1);
i--;
if (p2.health <= 0) gameOver = true;
continue;
}

// Ломает стены
for (var j = 0; j < bricks.length; j++) {
if (collide(bulletRect, bricks[j])) {
bricks.splice(j, 1);
enemyBullets.splice(i, 1);
i--;
break;
}
}
}
}

function updateCTF() {
if (currentMode !== 'ctf') return;
var flagRect = { x: flag.x, y: flag.y, w: flag.w, h: flag.h };
var tankRect = { x: p1.x, y: p1.y, w: 40, h: 40 };
if (!flag.captured && collide(tankRect, flagRect)) {
flag.captured = true; flag.carrier = 'player';
score += 150; updateUI();
}
if (flag.captured && flag.carrier === 'player') {
var baseRect = { x: 50, y: 520, w: 30, h: 30 };
if (collide(tankRect, baseRect)) {
score += 500; updateUI();
flag.captured = false; flag.carrier = null;
flag.x = 700; flag.y = 80;
} else { flag.x = p1.x + 6; flag.y = p1.y + 6; }
}
}

function sendPosition() {
if (ws && ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: 'pos', x: p1.x, y: p1.y, dir: p1.dir, health: p1.health }));
}
}

function updateGame() {
if (gameOver || p1.health <= 0) { if (p1.health <= 0) gameOver = true; return; }

if (keys.left) moveTank(p1, -4, 0, 2);
if (keys.right) moveTank(p1, 4, 0, 3);
if (keys.up) moveTank(p1, 0, -4, 0);
if (keys.down) moveTank(p1, 0, 4, 1);

if (p1Delay > 0) p1Delay--;
if (keys.fire && !p1Bullet.active && p1Delay === 0) shoot(p1, p1Bullet, true);
updateBullet(p1Bullet, true);

if (currentMode === 'pvp' && gameSource === 'offline' && p2) {
if (keysP2.left) moveTank(p2, -4, 0, 2);
if (keysP2.right) moveTank(p2, 4, 0, 3);
if (keysP2.up) moveTank(p2, 0, -4, 0);
if (keysP2.down) moveTank(p2, 0, 4, 1);
if (p2Delay > 0) p2Delay--;
if (keysP2.fire && !p2Bullet.active && p2Delay === 0) shoot(p2, p2Bullet, false);
updateBullet(p2Bullet, false);
}

if (currentMode === 'bots' || currentMode === 'ctf') {
updateEnemies();
updateEnemyBullets();
}

if (currentMode === 'ctf') updateCTF();

if (gameSource === 'online' && ws && ws.readyState === WebSocket.OPEN) {
var now = Date.now();
if (now — lastSend > 50) { sendPosition(); lastSend = now; }
}
}

function draw() {
ctx.clearRect(0, 0, 800, 600);
ctx.fillStyle = '#1a1a1a'; ctx.fillRect(0, 0, 800, 600);
for (var i = 0; i < bricks.length; i++) {
var b = bricks[i];
ctx.fillStyle = '#8a8a8a'; ctx.fillRect(b.x, b.y, b.w, b.h);
ctx.fillStyle = '#b5b5b5'; ctx.fillRect(b.x+2, b.y+2, b.w-4, 5);
}
if (currentMode === 'ctf') {
if (!flag.captured || flag.carrier !== 'player') {
ctx.fillStyle = '#e0e0e0'; ctx.fillRect(flag.x, flag.y, flag.w, flag.h);
ctx.fillStyle = '#ffffff'; ctx.font = 'bold 20px monospace'; ctx.fillText('🏁', flag.x+5, flag.y+22);
}
ctx.fillStyle = '#4a4a4a'; ctx.fillRect(50, 520, 30, 30);
ctx.fillStyle = '#ffffff'; ctx.fillText('🏠', 57, 542);
}
var colorIndex = 0;
var colors = ['#e8e8e8', '#9a9a9a', '#b5b5b5', '#6a6a6a', '#ffffff', '#c4c4c4', '#7d7d7d', '#4f4f4f'];
for (var entry of players) {
var player = entry[1];
ctx.fillStyle = colors[colorIndex % colors.length];
ctx.fillRect(player.x, player.y, 40, 40);
ctx.fillStyle = '#ffffff';
var ex = player.x + 20, ey = player.y + 20;
if (player.dir === 0) ctx.fillRect(ex-3, player.y-6, 6, 10);
else if (player.dir === 1) ctx.fillRect(ex-3, player.y+36, 6, 10);
else if (player.dir === 2) ctx.fillRect(player.x-6, ey-3, 10, 6);
else ctx.fillRect(player.x+36, ey-3, 10, 6);
ctx.fillStyle = '#ffffff'; ctx.font = '11px monospace';
ctx.fillText('❤️'+player.health, player.x+3, player.y-5);
colorIndex++;
}
ctx.fillStyle = '#e8e8e8'; ctx.fillRect(p1.x, p1.y, 40, 40);
ctx.fillStyle = '#ffffff';
var cx = p1.x + 20, cy = p1.y + 20;
if (p1.dir === 0) ctx.fillRect(cx-4, p1.y-8, 8, 12);
else if (p1.dir === 1) ctx.fillRect(cx-4, p1.y+32, 8, 12);
else if (p1.dir === 2) ctx.fillRect(p1.x-8, cy-4, 12, 8);
else ctx.fillRect(p1.x+32, cy-4, 12, 8);

if (currentMode === 'pvp' && gameSource === 'offline' && p2) {
ctx.fillStyle = '#5a5a5a'; ctx.fillRect(p2.x, p2.y, 40, 40);
ctx.fillStyle = '#ffffff';
var ex = p2.x + 20, ey = p2.y + 20;
if (p2.dir === 0) ctx.fillRect(ex-3, p2.y-6, 6, 10);
else if (p2.dir === 1) ctx.fillRect(ex-3, p2.y+36, 6, 10);
else if (p2.dir === 2) ctx.fillRect(p2.x-6, ey-3, 10, 6);
else ctx.fillRect(p2.x+36, ey-3, 10, 6);
ctx.fillStyle = '#ffffff'; ctx.font = '11px monospace';
ctx.fillText('❤️'+p2.health, p2.x+3, p2.y-5);
}

for (var i = 0; i < enemies.length; i++) {
var e = enemies[i];
ctx.fillStyle = '#3a3a3a'; ctx.fillRect(e.x, e.y, 40, 40);
ctx.fillStyle = '#666666';
var ex = e.x + 20, ey = e.y + 20;
if (e.dir === 0) ctx.fillRect(ex-3, e.y-6, 6, 10);
else if (e.dir === 1) ctx.fillRect(ex-3, e.y+36, 6, 10);
else if (e.dir === 2) ctx.fillRect(e.x-6, ey-3, 10, 6);
else ctx.fillRect(e.x+36, ey-3, 10, 6);
}

if (p1Bullet.active) { ctx.fillStyle = '#ffffff'; ctx.fillRect(p1Bullet.x, p1Bullet.y, 8, 8); }
if (currentMode === 'pvp' && gameSource === 'offline' && p2Bullet.active) { ctx.fillStyle = '#b5b5b5'; ctx.fillRect(p2Bullet.x, p2Bullet.y, 8, 8); }

// Пули ботов — красные
for (var i = 0; i < enemyBullets.length; i++) {
var eb = enemyBullets[i];
ctx.fillStyle = '#7a7a7a';
ctx.fillRect(eb.x, eb.y, 8, 8);
}

if (gameOver || p1.health <= 0) {
ctx.font = 'bold 36px monospace'; ctx.fillStyle = '#f2f2f2'; ctx.fillText('GAME OVER', 280, 280);
ctx.font = '14px monospace'; ctx.fillStyle = '#9a9a9a'; ctx.fillText('R — рестарт', 340, 340);
}
}

// ========= ВЫБОР =========
window.selectSource = function(source, btn) {
selectedSource = source; gameSource = source;
var allBtns = document.querySelectorAll('.mode-btn');
for (var i = 0; i < allBtns.length; i++) allBtns[i].classList.remove('selected');
btn.classList.add('selected');
document.getElementById('offlineModes').style.display = source === 'offline'? 'block': 'none';
document.getElementById('onlineModes').style.display = source === 'online'? 'block': 'none';
};

window.selectMode = function(mode, btn) {
selectedMode = mode;
var container = (selectedSource === 'offline')? 'offlineModes': 'onlineModes';
var allBtns = document.getElementById(container).querySelectorAll('.mode-btn');
for (var i = 0; i < allBtns.length; i++) allBtns[i].classList.remove('selected');
btn.classList.add('selected');
};

window.selectMap = function(mapNum, btn) {
selectedMap = mapNum; currentMap = mapNum;
var allBtns = document.querySelectorAll('.map-btn');
for (var i = 0; i < allBtns.length; i++) allBtns[i].classList.remove('selected');
btn.classList.add('selected');
};

window.selectPlayers = function(num, btn) {
selectedPlayers = num; maxPlayers = num;
var allBtns = document.querySelectorAll('.players-btn');
for (var i = 0; i < allBtns.length; i++) allBtns[i].classList.remove('selected');
btn.classList.add('selected');
};

window.startSelectedMode = function() {
if (!selectedSource) { alert('Выбери способ!'); return; }
if (!selectedMode) { alert('Выбери режим!'); return; }

if (selectedSource === 'online') {
var ip = document.getElementById('serverIp').value;
var port = document.getElementById('serverPort').value;
connectToServer(ip, port);
} else {
currentMode = selectedMode;
currentMap = selectedMap;
gameSource = 'offline';
maxPlayers = 1;
gameRunning = true;
var modeText = '';
if (selectedMode === 'bots') modeText = '🎮 БОТЫ';
if (selectedMode === 'ctf') modeText = '🏁 ФЛАГ';
if (selectedMode === 'pvp') modeText = '⚔️ PVP';
document.getElementById('modeLabel').innerText = modeText;
restart();
document.getElementById('menu').classList.add('hidden');
document.getElementById('game').classList.remove('hidden');
}
};

function connectToServer(ip, port) {
var url = 'ws://' + ip + ':' + port;
document.getElementById('netStatus').innerText = '🔄 Подключение...';
try { ws = new WebSocket(url); } catch(e) { document.getElementById('netStatus').innerText = '❌ Ошибка!'; return; }
ws.onopen = function() {
document.getElementById('netStatus').innerText = '✅ Подключено!';
currentMode = selectedMode;
gameSource = 'online';
currentMap = selectedMap;
maxPlayers = selectedPlayers;
gameRunning = true;
var modeText = '';
if (selectedMode === 'bots') modeText = '🌐 БОТЫ';
if (selectedMode === 'ctf') modeText = '🌐 ФЛАГ';
if (selectedMode === 'pvp') modeText = '🌐 PVP';
document.getElementById('modeLabel').innerText = modeText;
restart();
document.getElementById('menu').classList.add('hidden');
document.getElementById('game').classList.remove('hidden');
};
ws.onmessage = function(event) {
try {
var data = JSON.parse(event.data);
if (data.type === 'id') { myId = data.id; document.getElementById('onlineStatus').innerText = '🎮 ID: ' + myId; }
if (data.type === 'pos' && data.playerId !== myId) {
if (!players.has(data.playerId)) {
players.set(data.playerId, { x: data.x, y: data.y, dir: data.dir, health: data.health });
} else {
var p = players.get(data.playerId);
p.x = data.x; p.y = data.y; p.dir = data.dir; p.health = data.health;
}
document.getElementById('onlineStatus').innerText = '👥 Игроков: ' + (players.size + 1) + '/' + maxPlayers;
updateUI();
}
if (data.type === 'damage' && data.targetId === myId) {
p1.health = data.health; updateUI();
if (p1.health <= 0) gameOver = true;
}
if (data.type === 'disconnect') { players.delete(data.playerId); updateUI(); }
} catch(e) {}
};
ws.onerror = function() { document.getElementById('netStatus').innerText = '❌ Ошибка!'; };
ws.onclose = function() { if (gameRunning) { setTimeout(exitToMenu, 2000); } };
}

function exitToMenu() {
gameRunning = false;
if (ws) { ws.close(); ws = null; }
players.clear();
document.getElementById('menu').classList.remove('hidden');
document.getElementById('game').classList.add('hidden');
}

document.addEventListener('keydown', function(e) {
if (!gameRunning) return;
if (e.key === 'ArrowLeft') keys.left = true;
if (e.key === 'ArrowRight') keys.right = true;
if (e.key === 'ArrowUp') keys.up = true;
if (e.key === 'ArrowDown') keys.down = true;
if (e.key === ' ') { keys.fire = true; e.preventDefault(); }
if (currentMode === 'pvp' && gameSource === 'offline') {
if (e.key === 'a') keysP2.left = true;
if (e.key === 'd') keysP2.right = true;
if (e.key === 'w') keysP2.up = true;
if (e.key === 's') keysP2.down = true;
if (e.key === 'x') { keysP2.fire = true; e.preventDefault(); }
}
if (e.key === 'r' || e.key === 'R') restart();
if (e.key === 'Escape') exitToMenu();
});

document.addEventListener('keyup', function(e) {
if (e.key === 'ArrowLeft') keys.left = false;
if (e.key === 'ArrowRight') keys.right = false;
if (e.key === 'ArrowUp') keys.up = false;
if (e.key === 'ArrowDown') keys.down = false;
if (e.key === ' ') { keys.fire = false; }
if (currentMode === 'pvp' && gameSource === 'offline') {
if (e.key === 'a') keysP2.left = false;
if (e.key === 'd') keysP2.right = false;
if (e.key === 'w') keysP2.up = false;
if (e.key === 's') keysP2.down = false;
if (e.key === 'x') { keysP2.fire = false; }
}
});

// ========= ДЖОЙСТИК (КРЕСТОВИНА) =========
function setupJoystick() {
var joystick = document.getElementById('joystick');
var knob = document.getElementById('joystickKnob');
var active = false;
var touchId = null;

function handleStart(e) {
e.preventDefault();
active = true;
if (e.changedTouches) touchId = e.changedTouches[0].identifier;
handleMove(e);
}

function handleMove(e) {
if (!active) return;
e.preventDefault();

var touch = null;
if (e.changedTouches && touchId !== null) {
for (var i = 0; i < e.changedTouches.length; i++) {
if (e.changedTouches[i].identifier === touchId) {
touch = e.changedTouches[i];
break;
}
}
} else if (e.touches && e.touches.length > 0) {
touch = e.touches[0];
} else if (e.clientX !== undefined) {
touch = e;
}

if (!touch) return;

var rect = joystick.getBoundingClientRect();
var centerX = rect.left + rect.width / 2;
var centerY = rect.top + rect.height / 2;
var dx = touch.clientX — centerX;
var dy = touch.clientY — centerY;

var maxDist = rect.width / 2 — 15;
var dist = Math.sqrt(dx*dx + dy*dy);

if (dist > maxDist) {
dx = dx / dist * maxDist;
dy = dy / dist * maxDist;
}

knob.style.transform = 'translate(calc(-50% + ' + dx + 'px), calc(-50% + ' + dy + 'px))';

// Определяем направление (4 направления, как крестовина)
var threshold = maxDist * 0.3;

// Сброс всех
keys.left = false;
keys.right = false;
keys.up = false;
keys.down = false;

// Приоритет — более сильное отклонение
if (Math.abs(dx) > Math.abs(dy)) {
if (dx > threshold) keys.right = true;
else if (dx < -threshold) keys.left = true;
} else {
if (dy > threshold) keys.down = true;
else if (dy < -threshold) keys.up = true;
}
}

function handleEnd(e) {
e.preventDefault();
active = false;
touchId = null;
knob.style.transform = 'translate(-50%, -50%)';
keys.left = false;
keys.right = false;
keys.up = false;
keys.down = false;
}

joystick.addEventListener('touchstart', handleStart, { passive: false });
joystick.addEventListener('touchmove', handleMove, { passive: false });
joystick.addEventListener('touchend', handleEnd, { passive: false });
joystick.addEventListener('touchcancel', handleEnd, { passive: false });

joystick.addEventListener('mousedown', handleStart);
joystick.addEventListener('mousemove', function(e) { if (active) handleMove(e); });
joystick.addEventListener('mouseup', handleEnd);
joystick.addEventListener('mouseleave', handleEnd);
}

function setupButtons() {
var btnFire = document.getElementById('btnFire');
var btnRestart = document.getElementById('btnRestart');
var backBtn = document.getElementById('backBtn');

btnFire.addEventListener('touchstart', function(e) { e.preventDefault(); keys.fire = true; }, { passive: false });
btnFire.addEventListener('touchend', function(e) { e.preventDefault(); keys.fire = false; }, { passive: false });
btnFire.addEventListener('touchcancel', function(e) { e.preventDefault(); keys.fire = false; }, { passive: false });
btnFire.addEventListener('mousedown', function(e) { e.preventDefault(); keys.fire = true; });
btnFire.addEventListener('mouseup', function(e) { e.preventDefault(); keys.fire = false; });
btnFire.addEventListener('mouseleave', function(e) { e.preventDefault(); keys.fire = false; });

btnRestart.addEventListener('click', function(e) { e.preventDefault(); restart(); });
btnRestart.addEventListener('touchstart', function(e) { e.preventDefault(); restart(); }, { passive: false });

backBtn.addEventListener('click', function(e) { e.preventDefault(); exitToMenu(); });
backBtn.addEventListener('touchstart', function(e) { e.preventDefault(); exitToMenu(); }, { passive: false });
}

setupJoystick();
setupButtons();

function gameLoop() {
if (gameRunning) { updateGame(); draw(); }
requestAnimationFrame(gameLoop);
}
gameLoop();
</script>
</body>
</html>
IGOR2221
2 дня
Умно, но люди всё ровно пока что лучше чем ИИ в определённых сферах деетельности
IGOR2221
2 дня
Нет, у меня просто крыша поехала и я решил вторую браузерную ос сделать, ну вон тебе скрин этой hencore os
IGOR2221
2 дня
Ну а что тебе не нравится?
IGOR2221
3 дня
🤨
IGOR2221
3 дня
я доработал только CSS стили так что твой сайт и так не будет перегружается, нагрузка будет в 2-3 раза меньше чем сайт трешбокса, ну а стили страницы меняет только CSS а JS это такой язык программирования, но а на скрине то как именно я доработал твой сайт
IGOR2221
3 дня
я твой сайт vid209.github.io/M-STUDIO-website/ в порядок привел чтобы выглядел получше, ну а так у меня тоже есть свой сайт igor02022010.github.io/SOPS/
IGOR2221
3 дня


<!DOCTYPE html>
<!-- saved from url=(0066)file:///C:/Users/Lenovo/Desktop/Игры/0999.html -->
<html lang=«ru»><head><meta http-equiv=«Content-Type» content=«text/html; charset=UTF-8»>

<title>M-Studio — Игры</title>
<style>
* {
box-sizing: border-box;
}

body {
background: radial-gradient(1200px 600px at 50% -10%, #1c1c24 0%, #0d0d0f 60%, #0a0a0b 100%);
font-family: 'Segoe UI', Arial, sans-serif;
margin: 0;
padding: 0;
color: #e6e6e6;
min-height: 100vh;
}

.container {
max-width: 960px;
margin: auto;
padding: 20px;
}

header {
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
padding-bottom: 20px;
margin-bottom: 30px;
text-align: center;
}

h1 {
font-size: 34px;
text-transform: uppercase;
letter-spacing: 4px;
margin: 0;
color: #ffffff;
text-shadow: 0 0 24px rgba(120, 140, 255, 0.45);
}

.subtitle {
font-size: 16px;
color: #8a8a9a;
margin-top: 8px;
font-style: italic;
}

.social-links {
margin-top: 16px;
}

.social-links a {
display: inline-block;
margin: 0 6px;
text-decoration: none;
color: #dcdce6;
border: 1px solid rgba(255, 255, 255, 0.15);
padding: 8px 20px;
background: rgba(255, 255, 255, 0.05);
border-radius: 24px;
backdrop-filter: blur(6px);
transition: all 0.25s ease;
}

.social-links a:hover {
background: rgba(120, 140, 255, 0.18);
border-color: rgba(120, 140, 255, 0.6);
box-shadow: 0 0 16px rgba(120, 140, 255, 0.35);
transform: translateY(-2px);
}

.games-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 22px;
}

.game-card {
border: 1px solid rgba(255, 255, 255, 0.1);
background: linear-gradient(160deg, rgba(255, 255, 255, 0.07) 0%, rgba(255, 255, 255, 0.02) 100%);
border-radius: 18px;
padding: 24px 16px;
text-align: center;
transition: transform 0.25s ease, border-color 0.25s ease, box-shadow 0.25s ease;
}

.game-card:hover {
transform: translateY(-4px);
border-color: rgba(120, 140, 255, 0.45);
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.55);
}

.game-title {
font-weight: bold;
font-size: 19px;
margin-bottom: 8px;
color: #ffffff;
letter-spacing: 0.5px;
}

.game-card p {
color: #9a9aa8;
font-size: 14px;
margin: 0 0 6px;
}

.play-btn {
display: inline-block;
margin-top: 10px;
padding: 10px 24px;
background: linear-gradient(135deg, #3ddc84, #1faa5a);
color: #ffffff;
text-decoration: none;
border-radius: 10px;
font-weight: bold;
transition: all 0.25s ease;
}

.play-btn:hover {
box-shadow: 0 0 18px rgba(61, 220, 132, 0.45);
transform: translateY(-2px);
}

.download-btn {
display: inline-block;
margin-top: 10px;
padding: 10px 24px;
background: linear-gradient(135deg, #ff7043, #e64a19);
color: #ffffff;
text-decoration: none;
border-radius: 10px;
font-weight: bold;
transition: all 0.25s ease;
}

.download-btn:hover {
box-shadow: 0 0 18px rgba(255, 112, 67, 0.45);
transform: translateY(-2px);
}

footer {
margin-top: 36px;
border-top: 1px solid rgba(255, 255, 255, 0.08);
padding-top: 16px;
font-size: 13px;
color: #6a6a78;
text-align: center;
}
</style>

</head>
<body>
<div class=«container»>
<header>
<h1 style=«color:#f0f0f0»>M-Studio</h1>
<p class=«subtitle»>Наш сайт тут!</p>
<div class=«social-links»>
<a class=«canal333» href=«web.telegram.org/k/#@M209studio»>Telegram</a>
<a class=«canal333» href=«vk.ru/im/channels/-240709384?entrypoint=channel&tab=all»>VK</a>
</div>
</header>

<section class=«games-grid»>
<!-- Кликер -->
<div class=«game-card»>
<div class=«game-title»>M-Clicker</div>
<p>Кликер в браузере</p>
<a href=«play.unity.com/ru/user/9dacca9a-b93f-41fa-813d-e3bcbfc03d3d» class=«play-btn» target="_blank">Играть</a>
</div>

<!-- Танчики -->
<div class=«game-card»>
<div class=«game-title»>Tank Brawl</div>
<p>Танковые сражения онлайн</p>
<a href=«vid209.github.io/Tank-Brawl/» class=«play-btn» target="_blank">Играть</a>
</div>

<!-- Змейка -->
<div class=«game-card»>
<div class=«game-title»>Змейка</div>
<p>Классическая змейка для ПК</p>
<a href=«drive.google.com/file/d/1tSiTzl4d2FcMw7dnRFQSm88eKmQVpbzB/view?usp=drive_link» class=«download-btn» download="">Скачать EXE</a>
</div>
</section>

<footer>
© 2026 M-Studio.
</footer>
</div>

</body></html>
IGOR2221
3 дня

<!DOCTYPE html>



M-Studio — Игры






M-Studio

Наш сайт тут!








M-Clicker

Кликер в браузере


Играть




Tank Brawl

Танковые сражения онлайн


Играть




Змейка

Классическая змейка для ПК


Скачать EXE




© 2026 M-Studio.




IGOR2221
3 дня
Салам и спасибо)
IGOR2221
5 дней
То что этот айфон ломается это и так очевидно (Потому что есть подвижные части) поэтому лучше покупать нескладные смартон по военому стандарту качества
IGOR2221
5 дней
Ну так в этом и плюс, то что чел купивший смартфон не знает о том что там БУ деталь из за которой стоимость смартфона низкая и пользуется им с довольной мордой
IGOR2221
1 неделя
Ну так мне интересно потому что этим заниматься (А началось всё ещё в 2024 году)
IGOR2221
1 неделя
Ну или БУ смартфон с рук покупать ещё как вариант, но в магазинах же не кто не пишет что внутри ну и к тому же это ставят именно в бюджетники так что всё норм
IGOR2221
1 неделя
Ну так это все ровно бюджетники так что на них и используют такое
IGOR2221
2 недели

IGOR2221
2 недели
Ну так она была разработана давненько а вин11 она новее, НО грузит железо ПК сильнее чем десятка и менее отлаженная (Т.к он свежее десятки а значит багов больше, но о по внешности 11 выигрывает всеровно)
IGOR2221
2 недели
А тебе какая разница до того какое мне дело?