Сам я Блендер еще не познал, поэтому чуть погуглив, нашел вполне себе неплохо делающие нейронки. Поэтому...
Возьмем образец
Сделаем 3д рисунок в Gemini
В китайской нейронке получаем модель
Страшное
Цели сделать сразу хорошо не стояло, поэтому отправил я её на печать добавив подставку. Чего и следовало ожидать, зубы и ноги частично отлетели, страшные края у крыльев и всё вот это вот. Нужно ноги с подставкой сделать отдельно, увеличить размер модельки и можно приводить в красивый вид. Но это потом, когда я с Блендером разберусь немного.
Кому надо моделька тут. Архив 30.1 Мб, сама модель 75,5 Мб. У нее овермного вершин, но упрощается это легко.
Я тут вспомнил, что в прошлом посте забыл добавить планы на будущее. Планами было: добавить врагов.
Соответственно: точки спавна, их перемещение по карте, стрельба.
Давайте посмотрим на результат.
Появился новый класс, отвечающий за поведение врагов
export class EnemyAI {
constructor(tank) {
this.tank = tank;
// Таймер смены направления
this.changeDirectionTimer = 0;
this.changeDirectionInterval = 60; // ~2 сек при 30 FPS
// Cooldown стрельбы
this.shootCooldown = 0;
this.shootInterval = 30; // ~1 сек при 30 FPS
// Флаг застревания (для смены направления при коллизии)
this.wasBlocked = false;
}
randomDirection() {
const directions = [Direction.UP, Direction.RIGHT, Direction.DOWN, Direction.LEFT];
return directions[Math.floor(Math.random() * 4)];
}
update(allTanks, gameMap, bullets) {
const tank = this.tank;
if (tank.destroyed) return;
// === 1. Логика смены направления ===
this.changeDirectionTimer++;
// Смена направления по таймеру
if (this.changeDirectionTimer >= this.changeDirectionInterval) {
tank.direction = this.randomDirection();
this.changeDirectionTimer = 0;
// Рандомизируем интервал (40-80 кадров)
this.changeDirectionInterval = 40 + Math.floor(Math.random() * 40);
}
// === 2. Попытка движения ===
const prevX = tank.x;
const prevY = tank.y;
tank.move(tank.direction);
// Проверка: застрял ли танк (не сдвинулся)
const stuck = (tank.x === prevX && tank.y === prevY && !tank.moving);
if (stuck && !this.wasBlocked) {
// Танк только что застрял — меняем направление
tank.direction = this.randomDirection();
this.wasBlocked = true;
this.changeDirectionTimer = 0;
} else if (!stuck) {
this.wasBlocked = false;
}
// === 3. Автоматическая стрельба ===
this.shootCooldown--;
if (this.shootCooldown <= 0 && tank.canShoot()) {
const bullet = tank.shoot();
if (bullet) {
bullets.push(bullet);
// Рандомизируем cooldown (20-50 кадров)
this.shootCooldown = 20 + Math.floor(Math.random() * 30);
}
}
}
}
Он простой как три рубля, так что, думаю, можно обойтись без объяснений (тем более что комментариев в коде и так предостаточно).
К файле main появились коллекции врагов и их "мозгов"
/** @type {Array<Tank>} */
let enemies = [];
/** @type {Array<EnemyAI>} */
let enemyAIs = [];
Спавн врагов при старте игры
spawnEnemy(0, 0); // Левый угол
spawnEnemy(12 * 8, 0); // Центр (96px)
spawnEnemy(24 * 8 - 16, 0); // Правый угол (176px, учитываем размер танка)
// Пока спавню сразу все три, а не по очереди, как в оригинале
function spawnEnemy(x, y) {
const enemy = new Tank(x, y, TankType.ENEMY_BASIC);
enemy.direction = Direction.DOWN; // Враги всегда смотрят вниз
enemy.setMap(gameMap);
// Создаём AI для врага
const ai = new EnemyAI(enemy);
enemies.push(enemy);
enemyAIs.push(ai);
console.log(`Enemy spawned at (${x}, ${y})`);
}
И рисуем это
for (const enemy of enemies) {
if (!enemy.destroyed) {
enemy.render();
}
}
Там ещё есть обновление ссылок чтоб чистить из памяти уничтоженные танки, но в целом ничего больше интересного.
Жили-были. И всё у них было. И блины пеклись, и масло шкворчало, и Масленица во дворе плясала.
Да вот беда приключилася. Наша хлопотунья Лиса, главная по блинам да по праздникам, поскользнулась на маслице — и бух! Прямиком в тёмный подвал, где солёные огурцы в банках дозревают да картошка прошлогодняя дремлет.
Сидит Лиса, бедная, под провалом в подвал, лапой утирается, тонко подвывает:
— Ой, пропала я, касатики! Не видать мне больше белого света, не печь мне блинов румяных, не встречать весну красну! Век мне теперь в подвале куковать...
Услыхал тот плач первый блинодел. Прибежал, сковал ПЕРВОЕ ЗВЕНО, спустил цепь — тянет-потянет, а вытянуть не может. Да и что сказать? Не цепь, а всего одно звено!
Кликнул он соседа — второе звено сковали. Тянут-потянут — всё одно не достаёт. Кликнули бывалого блинопёка — третье звено приковали. Тянут-потянут — нет, не вытянуть!
И пошло-поехало! Кого только ни кликали: мастеров с печатями, песенников-скоморохов с блинами «жирненькими», стряпух с блинами безлактозными, заварными да разными, гостей заморских привечали, а еще того самого, кто сначала на печи лежал, бока отлёживал, а потом как подскочит - «Ща ворвусь»!
Много звеньев сковали — а цепи всё не хватает. Лиса ухватится, ее тянут, а звенья только растягиваются.
Кликнули Кирюху со стены. Но Кирюха сам маленький, кого он вытянет? Разве что для храбрости приклеился покрепче.
И тут поняли они: одной цепи мало. Нужна СЕТЬ! Чтобы не одной ниточкой тянуть, а всем миром сразу, со всех сторон!
И пошла плестись СЕТЬ СПАСЕНИЯ!
И стали они кликать всех-всех-всех: и тех, кто блины печет, и тех, кто только смотрит, и тех, кто в комментариях шутит, и тех, кто в пяти цепочках сразу бежит!
И когда цепь эта стала длинною в бесконечность, когда связала она всех воедино — от первого блинодела до последнего молчуна в комментариях, — дружно они крикнули:
— РАЗ! ДВА! ТРИ! ТЯНИ-И-И-И!!!
И — АЙ ДА МОЛОДЦЫ! АЙ ДА СПАСАТЕЛИ!
ВЫТЯНУЛИ ЛИСУ!
Вылетела она из подвала пулей, прижимая к груди банку со сгущенкой (стратегический запас, как-никак), отклеенного Кирюху, да Кошь за пазухой. Глаза сияют, хвост трубой, на морде — счастье пополам с блином.
— Спасибо вам, добрые люди! — раскланялась Лиса на все стороны. — Век вашей доброты не забуду! А теперь — ВСЕМ ЗА СТОЛ! БЛИНЫ ЕСТЬ! МАСЛЕНИЦУ ВСТРЕЧАТЬ!
И был пир на весь мир. И блины были — с икрой, со сметаной, с медом, с вареньем, с мясом, с творогом, с селедкой, да со всем, чего душа пожелает. И те, кто пек, и те, кто в цепочках стоял, и те, кто просто мимо проходил — все за одним столом собрались.
А Лиса, главная затейница, всем по блину подкладывала да приговаривала:
— Ешьте, родимые! Ешьте, спасители мои! Без вас бы я там, с огурцами, навеки осталась!
И тут слово молвил главный блинный летописец:
— А кто Лису спасал, кто блины пек да в цепочках стоял — всем носить отныне почётное звание «ВОТ БЛИН ПЕРВОЙ СТЕПЕНИ»! И мастер наш искусный уже за работу принялся — награды ладит, одна к одной, круглые да румяные, прямо как блины, только с душой и на вечную память!
Тут и сказке конец. А кто дочитал да блином закусил — тот и в цепочке нашей навеки остался. С Масленицей вас, люди добрые! 🥞🦊
К сожалению, мы никогда не достигали ядра Земли (и, скорее всего, никогда не достигнем), но мы многое знаем о его строении, так как располагаем замечательной наукой под названием сейсмология, а также данными гравиметрии, геомагнетизма, геохимии и лабораторных экспериментов при экстремальных давлениях.
Помимо этого, часть важных знаний о внутреннем устройстве нашей планеты мы получили благодаря подповерхностным ядерным испытаниям в период Холодной войны, которые снабдили ученых "спровоцированными" сейсмическими сигналами.
Сегодня мы можем с уверенностью сказать, что внешнее ядро Земли расплавлено, а внутреннее — твердое. Кроме того, исходя из наших знаний о распространенности химических элементов во Вселенной и о том, что с ними происходит при определенных условиях, мы знаем, что ядро состоит преимущественно из железа, которое находится под гигантским давлением.
Имеющиеся данные указывают на то, что температура земного ядра составляет примерно 6 000 градусов (тут и далее температура в градусах Цельсия), что делает его даже горячее солнечной поверхности (около 5 500 градусов). От поверхности Земли ядро отделяют порядка 3 000 километров — если бы наше светило оказалось так близко, оно тут же бы испепелило планету.
Почему же тогда более горячее ядро Земли за 4,6 миллиарда лет не расплавило ни планету, ни ее обитателей?
Ядро изолировано от поверхности огромной толщей мантии, состоящей в основном из твердых горячих горных пород, которые "текут" (мантийная конвекция) со скоростью в несколько сантиметров в год.
Несмотря на огромную температуру ядра, тепло из глубин поднимается к поверхности крайне неэффективно, так как породы плохо проводят его, а перенос за счет медленной мантийной конвекции занимает колоссальное время. Поэтому в данном случае важна не только температура ядра, но и то, сколько тепловой энергии может быть передано наружу и с какой скоростью.
В результате до поверхности доходит слишком маленький "поток" тепловой энергии, чтобы прогреть всю планету до температур плавления: Земля просто медленно теряет тепло (оно уходит в космос), а не "закипает" изнутри. При этом мантия не "плавится снизу" так, чтобы расплав постепенно поднимался все выше. В глубине давление повышает температуру плавления пород, поэтому даже при высоких температурах нижняя мантия в основном остается твердой. А там, где расплав все же появляется, он обычно не накапливается: поднимаясь, он попадает в более холодные области и частично кристаллизуется. В итоге в недрах Земли не существует "роста" океана расплава снизу вверх — возникают лишь отдельные зоны частичного плавления.
Искра бенгальского огня может иметь температуру в 1 500 градусов, но если она случайно попадет в вас, то вы, скорее всего, даже не почувствуете этого. А вот погружение в ванну с кипятком (каких-то 100 градусов) стало бы фатальным для большинства обитателей Земли, потому что у воды большая масса и теплоемкость — она успевает передать много энергии.
Тот же принцип и с Землей: "печка" спрятана очень глубоко, и тепло наружу просачивается постепенно — через конвекцию в мантии и теплопроводность пород. Поэтому планета не плавится, а медленно остывает.
ну и хрен с ней))
это оригинально. но у нас другие интриги. записала на всякий случай
ты пыталась:D