код игры змейка на java
Своя змейка, или пишем первый проект. Часть 0
Предисловие
Привет Хабр! Меня зовут Евгений «Nage», и я начал заниматься программированием около года назад, в свободное от работы время. Просмотрев множество различных туториалов по программированию задаешься вопросом «а что же делать дальше?», ведь в основном все рассказывают про самые основы и дальше как правило не заходят. Вот после продолжительного времени за просмотром разных роликов про одно и тоже я решил что стоит двигаться дальше, и браться за первый проект. И так, сейчас мы разберем как можно написать игру «Змейка» в консоли со своими начальными знаниями.
Глава 1. Итак, с чего начнем?
Для начала нам ничего лишнего не понадобится, только блокнот (или ваш любимый редактор), и компилятор C#, он присутствует по умолчанию в Windows, находится он в С:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe. Можно использовать компилятор последней версии который поставляется с visual studio, он находится Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\Roslyn\csc.exe.
«@echo off» отключает отображение команд в консоли. С помощью команды goto получаем бесконечный цикл. Задаем переменную name, а с модификатором /p в переменную записывается значение введенное пользователем в консоль. «echo.» просто оставляет пустую строчку в консоли. Далее вызываем компилятор и передаем ему файл нашего кода, который он скомпилирует.
Глава 2. Первые шаги
Подготовим поле нашей игры, начиная с точки входа в нашу программу. Задаем переменные X и Y, размер и буфер окна консоли, и скроем отображение курсора.
Для вывода на экран нашей «графики» создадим свой тип данных — точка. Он будет содержать координаты и символ, который будет выводится на экран. Также сделаем методы для вывода на экран точки и ее «стирания».
Это интересно!
Оператор => называется лямбда-оператор, он используется в качестве определения анонимных лямбда выражений, и в качестве тела, состоящего из одного выражения, синтаксический сахар, заменяющий оператор return. Приведенный выше метод переопределения оператора (про его назначение чуть ниже) можно переписать так:
Создадим класс стен, границы игрового поля. Напишем 2 метода на создание вертикальных и горизонтальных линий, и в конструкторе вызываем отрисовку всех 4х сторон заданным символом. Список всех точек в стенке нам пригодится позже.
Как вы могли заметить для инициализации типа данных Point используется форма Point p = (x, y, ch); как и у встроенных типов, это становится возможным при переопределении оператора implicit, в котором описывается как задаются переменные.
Вернемся к классу Game и объявим поле walls, а в методе Main инициализируем ее.
Все! Можно скомпилировать код и посмотреть, что наше поле построилось, и самая легкая часть позади.
Глава 3. А что сегодня на завтрак?
Добавим генерацию еды на нашем поле, для этого создадим класс FoodFactory, который и будет заниматься созданием еды внутри границ.
Добавляем инициализацию фабрики и создадим еду на поле
Глава 4. Время главного героя
Перейдем к созданию самой змеи, и для начала определим перечисление направления движения змейки.
Теперь можем создать класс змейки, где опишем как она будет ползать, поворачивать. Определим список точек змеи, наше перечисление, шаг на сколько будет перемещаться за ход, и ссылки на хвостовую и головную точки, и конструктор, в котором рисуем змею в заданных координатах и заданной длинны при старте игры.
В методе поворота, что бы избежать возможности повернуть сразу на 180 градусов, просто указываем, что в каждом направлении мы можем повернуть только в 2 стороны. А проблему поворота на 180 градусов двумя нажатиями — поставив «переключатель», отключаем возможность поворачивать после первого нажатия, и включаем после очередного хода.
Осталось вывести ее на экран.
Готово! теперь у нас есть все что нужно, поле огороженное стенами, рандомно появляющаяся еда, и змейка. Пришла пора заставить все это взаимодействовать друг с другом.
Глава 5. Л-логика
Заставим нашу змейку двигаться, напишем бесконечный цикл для считывания клавиш нажатых на клавиатуре, и передаем клавишу в метод поворота змеи
Теперь, перед тем как написать метод движения змейки, надо реализовать взаимодействие головы с едой, стенками и хвостом змеи. Для этого надо написать метод, позволяющий сравнивать две точки на совпадение координат. Переопределим оператор равенства и не равенства, их обязательно нужно переопределять в паре.
Теперь можно написать метод, который будет проверять совпадает ли интересующая нас точка с какой нибудь из массива стен.
И похожий метод проверяющий не совпадает ли точка с хвостом.
И методом проверки съела ли еду наша змейка, и сразу делаем ее длиннее.
теперь можно написать метод движения, со всеми нужными проверками.
Вот и все! Наша змейка в консоли закончена и можно поиграть.
Заключение
Мы посмотрели как можно реализовать первую простенькую игру с небольшим использованием ООП, научились перегружать операторы, посмотрели на кортежи и лямбда оператор, надеюсь это было полезно!
Это была пилотная статья, и если вам понравилось, я напишу про реализацию змейки на Unity.
Всем удачи!
Как написать свою змейку на Java за 15 минут
В предыдущей статье мы писали сапёра за 15 минут, теперь займёмся классической змейкой.
В этот раз нам снова понадобятся:
Подключение библиотек
В прошлый раз у многих возникли с этим вопросом проблемы, поэтому мне показалось уместным посвятить этому немного времени. Во-первых, выше я дал ссылку на скачивание архива с библиотеками, которые использую я, чтобы не было путаницы с версиями и вопросов, где найти что-то. Папку из архива требуется поместить в папку проекта и подключить через вашу IDE.
Во-вторых, у многих пользователей InteliJ IDEA возникли проблемы как раз с их подключением. Я нашёл в сети следующий видеогайд:
После того, как я сделал всё в точности по нему, у меня библиотеки подключились корректно и всё заработало.
Работа с графикой
С этой стороны наша задача мало отличается от той, что мы выполняли при написании Сапёра. Снова создаём класс GUI, который будет хранить и обновлять состояние всех графических элементов. Если точнее:
Как вы можете видеть, здесь я уже использовал несколько констант. Для них был создан отдельный класс Constants с public static полями. Вот он целиком:
Механика игры
Самое время поговорить о том, как наша змея будет, собственно, перемещаться. Вам наверняка доводилось видеть вывески, вокруг которых по кругу бегают огоньки? Разумеется, сами лампочки в них не перемещаются, просто каждый тик последняя гаснет, а первая зажигается. Таким же образом будет перемещаться и наша змея.
Пишем класс клетки
Добавляем геттер и сеттер для состояния клетки поля в GUI
Добавляем метод, создающий начальное поле в GUI
Пишем игру змейка с помощью JavaScript + Canvas
Подготовка
Пожалуй, стоит вообще начать с подготовки к созданию игры и написанию кода. Мы будем использовать простой редактор Sublime Text. Впрочем, это не важно. Все делаем в одном документе, чтобы было быстрее.
Первым делом, напишем сам код для встраивания canvas в документ. Напомню, что canvas поддерживается только в HTML5.
Подготовка завершена, теперь мы можем приступать к созданию самой игры.
Начинаем
Для начала, я хотел бы вам вообще объяснить как будет работать змейка, так будет гораздо понятнее. Наша змейка — это массив. Массив элементов, элементы — это ее части, на которые она делиться. Это всего лишь квадратики, которые имеют координаты X и Y. Как вы знаете, X — горизонталь, Y — вертикаль. В обычном виде мы представляем себе координатную плоскость вот так:
Она абсолютно правильная, в этом нет сомнения, но на мониторе компьютера (в частности, canvas) она выглядит по-другому, вот так:
Это нужно знать, если вы вдруг в первый раз столкнулись с canvas. Я, когда столкнулся с этим, сначала вообще не понял где точка (0,0), благо я быстро разобрался. Надеюсь и у вас проблем не возникло.
Вернемся к элементам змейки, ее частям. Представим, что каждый элемент имеет свои координаты, но одинаковую высоту и одинаковую ширину. Это квадратики, не более. А теперь представим, что мы вот нарисовали змейку, все квадратики, они идут друг за другом, одинаковые такие. И тут мы решили, что нам нужно подвинуть змейку вправо. Как бы вы поступили?
Некоторые люди ответили бы, что нам нужно первый элемент подвинуть вправо, затем второй, затем третий и так далее. Но для меня этот вариант не является правильным, так как в случае, если вдруг змейка огромная, а компьютер слабый, мы можем заметить, что змейка иногда разрывается, что вообще не должно быть. Да и вообще, данный способ требует слишком много команд, когда можно обойтись гораздо меньшим количеством, не потеряв качество. А теперь мой способ: Мы берем последний элемент змейки, и ставим его в начало, изменяя его координаты так, чтобы он был после головы. Теперь этот элемент — голова. Всего-то! И да, эффект движения будет присутствовать, а на компьютере вообще не будет заметно, как мы спрятали хвост, а потом его поставили в начало. именно так мы и будем поступать во время создания движения змейки.
Вот тут точно начинаем
Сначала нам нужно объявить некоторые переменные, которые мы в дальнейшем будем использовать.
И так, вообще, нужно чуть-чуть пояснить зачем нам нужно в функции возвращения случайного числа, умножать и делить на переменную s, которая хранит в себе ни что иное, как ширину, по совместительству и высоту элементов змейки. На самом деле, это нужно, чтобы не было смещений во время движения, так как у нас ширина элемента — 30, то если мы хотим двигать ее без разрывов, то все координаты должны делиться на 30 без остатка. Именно поэтому я делю на число, округляю, а потом умножаю. Таким образом, число возвращается таким, что его можно разделить без остатка на 30.
Вы могли бы возразить, сказав, что ты мог бы просто холсту сделать ширину и высоту, кратную 30. Но на самом деле, это не лучший вариант. Так как я лично привык использовать всю ширину экрана. И в случае, если ширина = 320, то мне пришлось бы аж целых 20 пикселей забирать у пользователя, что могло бы доставить дискомфорт. Именно поэтому в нашей змейки все координаты объектов делятся на 30, чтобы не было никаких неожиданных моментов. Было бы даже правильнее вынести это как отдельную функцию, так как она достаточно часто используется в коде. Но к этому выводу я пришел поздно. (Но возможно это даже не нужно).
Теперь сделаем так, чтобы картинка имела четкое качество отображения. По ходу статьи, я буду дописывать код, в некоторых местах возвращаться к началу, так что при себе имейте полную картину кода.
Если что, то переменные innerWidth и innerHeight хранятся в глобальном пространстве имен.
Поэтому к ним можно обратиться именно так. Правда, я не знаю правильно ли так делать.
Ну что же, теперь начинаем писать код змейки.
Чтобы было движение, нам нужна анимация, мы будем использовать функцию setInterval, вторым параметром которой будет число 60. Можно чуть больше, 75 на пример, но мне нравится 60. Функция всего на всего каждые 60 мс. рисует змейку «заново». Дальнейшее написание кода — это только этот интервал.
Покажу вообще простую отрисовку нашей змейки, пока что без движения.
Чтобы проверить, что наша змейка не сталкивается сама с собой, нам нужно сделать некоторую проверку для каждого элемента, кроме последнего. Мы будем проверять, не равны ли координаты последнего элемента (головы) змейки любым из… То есть проще говоря: не произошло ли столкновение. Эта строчка кода была единой строкой, но вам сделал ее понятной. Напоминаю, что все это добавляется в функцию интервала.
А теперь, вы наверное заметили, что во время того, как мы изменяем координаты, мы вечно что-то «сохраняем», сначала поделив, а потом округлив и умножив на число s. Это все тот же самый способ выравнивания змейки относительно яблока. Движение в данном случае строгое, простое, поэтому и есть змейка яблоко может строго по определенным правилам, которые задан в самом начале интервала. И если бы координаты головы змейки хоть на 1px сместились бы, то яблоко нельзя было бы съесть. И да, это простой вариант, поэтому все так сильно ограничено.
Ну а нам же осталось что сделать? Правильно, удалить из массива хвост (первый элемент), добавить новый элемент в самый конец и отрисовать всю змейку. Сделаем это, добавив в конец интервала вот такие строчки кода.
В добавок к отрисовке змейки, я добавил код, который делает ощущение, что конец экрана — это его начало. И если змейка выходит за границы, то она потом выходит из начала, на погибая.
Вы можете заменить обнуление координат, на пример, на сбрасывание игры, если у вас все очень жестко. Но мне нравится больше так. Ну а теперь, осталось только по нажатию кнопок изменять направление змейки. Делает за считанные секунды. Нужно лишь написать этот код сразу после setInterval. Примерно так:
Тут мы сделали так, что если змейка двигается вправо, то она не может изменить направление налево. Это логично, на самом деле.
Вот и все, друзья. Моя первая статья, написанная новичком для новичков. Надеюсь, все было понятно и кому-то это пригодилось. Змейку можно усовершенствовать, добавив на пример, счетчик очков, рекорды, дополнительные фишки, но это все уже дополнения, которые вы можете сделать сами. На этом все, всем удачи!
Пишем игру змейка с помощью JavaScript + Canvas
Подготовка
Пожалуй, стоит вообще начать с подготовки к созданию игры и написанию кода. Мы будем использовать простой редактор Sublime Text. Впрочем, это не важно. Все делаем в одном документе, чтобы было быстрее.
Первым делом, напишем сам код для встраивания canvas в документ. Напомню, что canvas поддерживается только в HTML5.
Подготовка завершена, теперь мы можем приступать к созданию самой игры.
Начинаем
Для начала, я хотел бы вам вообще объяснить как будет работать змейка, так будет гораздо понятнее. Наша змейка — это массив. Массив элементов, элементы — это ее части, на которые она делиться. Это всего лишь квадратики, которые имеют координаты X и Y. Как вы знаете, X — горизонталь, Y — вертикаль. В обычном виде мы представляем себе координатную плоскость вот так:
Она абсолютно правильная, в этом нет сомнения, но на мониторе компьютера (в частности, canvas) она выглядит по-другому, вот так:
Это нужно знать, если вы вдруг в первый раз столкнулись с canvas. Я, когда столкнулся с этим, сначала вообще не понял где точка (0,0), благо я быстро разобрался. Надеюсь и у вас проблем не возникло.
Вернемся к элементам змейки, ее частям. Представим, что каждый элемент имеет свои координаты, но одинаковую высоту и одинаковую ширину. Это квадратики, не более. А теперь представим, что мы вот нарисовали змейку, все квадратики, они идут друг за другом, одинаковые такие. И тут мы решили, что нам нужно подвинуть змейку вправо. Как бы вы поступили?
Некоторые люди ответили бы, что нам нужно первый элемент подвинуть вправо, затем второй, затем третий и так далее. Но для меня этот вариант не является правильным, так как в случае, если вдруг змейка огромная, а компьютер слабый, мы можем заметить, что змейка иногда разрывается, что вообще не должно быть. Да и вообще, данный способ требует слишком много команд, когда можно обойтись гораздо меньшим количеством, не потеряв качество. А теперь мой способ: Мы берем последний элемент змейки, и ставим его в начало, изменяя его координаты так, чтобы он был после головы. Теперь этот элемент — голова. Всего-то! И да, эффект движения будет присутствовать, а на компьютере вообще не будет заметно, как мы спрятали хвост, а потом его поставили в начало. именно так мы и будем поступать во время создания движения змейки.
Вот тут точно начинаем
Сначала нам нужно объявить некоторые переменные, которые мы в дальнейшем будем использовать.
И так, вообще, нужно чуть-чуть пояснить зачем нам нужно в функции возвращения случайного числа, умножать и делить на переменную s, которая хранит в себе ни что иное, как ширину, по совместительству и высоту элементов змейки. На самом деле, это нужно, чтобы не было смещений во время движения, так как у нас ширина элемента — 30, то если мы хотим двигать ее без разрывов, то все координаты должны делиться на 30 без остатка. Именно поэтому я делю на число, округляю, а потом умножаю. Таким образом, число возвращается таким, что его можно разделить без остатка на 30.
Вы могли бы возразить, сказав, что ты мог бы просто холсту сделать ширину и высоту, кратную 30. Но на самом деле, это не лучший вариант. Так как я лично привык использовать всю ширину экрана. И в случае, если ширина = 320, то мне пришлось бы аж целых 20 пикселей забирать у пользователя, что могло бы доставить дискомфорт. Именно поэтому в нашей змейки все координаты объектов делятся на 30, чтобы не было никаких неожиданных моментов. Было бы даже правильнее вынести это как отдельную функцию, так как она достаточно часто используется в коде. Но к этому выводу я пришел поздно. (Но возможно это даже не нужно).
Теперь сделаем так, чтобы картинка имела четкое качество отображения. По ходу статьи, я буду дописывать код, в некоторых местах возвращаться к началу, так что при себе имейте полную картину кода.
Если что, то переменные innerWidth и innerHeight хранятся в глобальном пространстве имен.
Поэтому к ним можно обратиться именно так. Правда, я не знаю правильно ли так делать.
Ну что же, теперь начинаем писать код змейки.
Чтобы было движение, нам нужна анимация, мы будем использовать функцию setInterval, вторым параметром которой будет число 60. Можно чуть больше, 75 на пример, но мне нравится 60. Функция всего на всего каждые 60 мс. рисует змейку «заново». Дальнейшее написание кода — это только этот интервал.
Покажу вообще простую отрисовку нашей змейки, пока что без движения.
Чтобы проверить, что наша змейка не сталкивается сама с собой, нам нужно сделать некоторую проверку для каждого элемента, кроме последнего. Мы будем проверять, не равны ли координаты последнего элемента (головы) змейки любым из… То есть проще говоря: не произошло ли столкновение. Эта строчка кода была единой строкой, но вам сделал ее понятной. Напоминаю, что все это добавляется в функцию интервала.
А теперь, вы наверное заметили, что во время того, как мы изменяем координаты, мы вечно что-то «сохраняем», сначала поделив, а потом округлив и умножив на число s. Это все тот же самый способ выравнивания змейки относительно яблока. Движение в данном случае строгое, простое, поэтому и есть змейка яблоко может строго по определенным правилам, которые задан в самом начале интервала. И если бы координаты головы змейки хоть на 1px сместились бы, то яблоко нельзя было бы съесть. И да, это простой вариант, поэтому все так сильно ограничено.
Ну а нам же осталось что сделать? Правильно, удалить из массива хвост (первый элемент), добавить новый элемент в самый конец и отрисовать всю змейку. Сделаем это, добавив в конец интервала вот такие строчки кода.
В добавок к отрисовке змейки, я добавил код, который делает ощущение, что конец экрана — это его начало. И если змейка выходит за границы, то она потом выходит из начала, на погибая.
Вы можете заменить обнуление координат, на пример, на сбрасывание игры, если у вас все очень жестко. Но мне нравится больше так. Ну а теперь, осталось только по нажатию кнопок изменять направление змейки. Делает за считанные секунды. Нужно лишь написать этот код сразу после setInterval. Примерно так:
Тут мы сделали так, что если змейка двигается вправо, то она не может изменить направление налево. Это логично, на самом деле.
Вот и все, друзья. Моя первая статья, написанная новичком для новичков. Надеюсь, все было понятно и кому-то это пригодилось. Змейку можно усовершенствовать, добавив на пример, счетчик очков, рекорды, дополнительные фишки, но это все уже дополнения, которые вы можете сделать сами. На этом все, всем удачи!
H Змейка в 33 строки для Android на Java в черновиках
Конечно, 33 строки — это «маркетинговый» ход для привлечения внимания.
Полное количество строк в основном и единственном классе равно 86, но ядро как раз столько и занимает (33). Внутри код змейки, самого маленького приложения для Android, комментарии и некоторые исследования на тему уменьшения размеров, сборка приложения из командной строки с использованием Proguard.
Быстрые ссылки по статье:
самое маленькое приложение;
змейка;
ссылки на github.
Введение
Думаю, что многие видели HelloWorld в Eclipse для Android.
Выглядит, особенно для новичка, весьма некомпактно. Тут очень много, назовём условно, «лишнего», для того чтобы разобраться, как это всё работает, что из чего следует, и как настраивать приложение.
От версии к версии иерархия файлов постоянно усложняется, что простоты к работе не добавляет.
1. две папки с Java-классами (src, gen). src содержит исходники, gen — сгенерированные классы. В основном, в папке gen бывает R.java.
2. Папка для библиотек libs. В случае HelloWorld создаётся библиотека android-support-v4.jar (или её более новая версия). Эта библиотека используется для обратной совместимости приложений.
То есть, если какие-то новые особенности (например объекты UI), создадут разработчики ОС, то, для того чтобы всё работало и на более ранних версиях, используются именно эти библиотеки. Также при помощи этой библиотеки разработчики исправляют некоторые ошибки. При использовании этой библиотеки, приложение, безусловно, значительно увеличит свой размер. Тут можно посмотреть список всех изменений по версиям.
3. ресурсная папка (res), в которой обычно располагаются изображения, настройки стилей, различные строки, и много другого прочего. Все файлы из этой папки получают уникальный ID в автоматически создаваемом при компиляции R.java-файле, который помещается в папку gen. ID можно (нужно) использовать внутри приложения, для того чтобы выделить тот или иной объект. Например, иконка для приложения.
4. asserts служит для хранения всех любых других видов файлов, которые нужно использовать в приложении, но им не будет выделен ID. Например, шрифт.
5. Файл-манифест приложения AndroidManifest.xml. Из него ОС узнаёт, что и как запускать, какие разрешения есть у приложения и т.п.
6. ic_launcher-web.png — файл-изображение для Google Play. Честно говоря, не знаю, насколько сейчас это является обязательным пунктом. В крайний раз, когда обновлял приложение на Google Play, этого не требовалось. Минутка субъективизма: не понимаю, что этот файл заслужил расположение в корне.
7. Текстовых файла для настроек проекта project.properties. Самый, пожалуй, частый вариант редактирования — включить/выключить использование proguard.
8. Текстовый файл для настроек proguard: proguard-project.txt
В принципе, для написания приложения достаточно только основной класс для Activity и AndroidManifest.xml
При помощи project.properties и proguard-project.txt можно настраивать работу Proguard. У него самая главная функция — сокращать имена по минимуму, что помогает усложнить реверс инжиниринг, а также сократить размер выходного файла. Имена переменных, методов и классов сокращаются до одно-, двухбуквенных.
Родная сборка приложения от Eclipse достаточно хороша, но лучше воспользоваться более «ручным» способом создания приложения при помощи командной строки. Как минимум исчезнет класс BuildConfig.java, который «ни с чего» появляется в папке gen. Также я заметил такую особенность, что родной компилятор собирает не только java, но и прочие файлы, которые находятся на одном уровне с исходниками. Чтобы не ошибиться(и не слить в релиз то, что не нужно), лучше воспользоваться компиляцией из командной строки.
Как это сделать, подробно написано в этой отличной статье.
Но при работе Тут bat-файл был переработан: добавлена корректная обработка путей в Windows, работа с Proguard, генерация ключа вынесена в отдельный батник.
Самое маленькое приложение на Android
android-support-v4.jar не используется. Ресурсы из папки res все удалены. В этом случае иконка приложения — это автопортрет Android, а строки (название приложения) записываются не ссылками на ресурсы, а в явном виде.
После сборки получается aSmall.apk — 2832 байта, aSmall.unsigned.apk — 945, что показывает, насколько много отъедает сертификат приложения. dex — 404 байта, classes-processed.jar — 248 байт. Это минимум.
Змейка
Github
В начале, конечно, захотелось мини-Excel, но я не нашёл хороший вариант в Java, при котором будет работать аналог функции exec в Javascript. Будет очень интересно посмотреть на результат, если кто-то сможет реализовать подобное.
Характеристики кода: полное количество строк A.java — 86, без import’ов — 69, «физика» поведения — 33 строки (что сравнимо с Javascript).
Приложение — полноэкранное. Управление при помощи жестов — вверх, вниз, влево, вправо.
Исходный код A.java.
A.java добавлен внутренний класс V extends View, который выводится на полный экран, в V есть в свою очередь свой внутренний класс P (Physics), который и описывает поведение змейки. Вот его размеры и равны примерно 30 строкам.
Алгоритм работы
приложение запускается в портретном режиме, основным элементом становится gv = new V();
В классе gv добавляется обработка жестов и запускается физику. В Физике инициализируется таймер (Timer), внутри которого происходит вычисление поведения змейки. Runnable и ASyncTask по размеру бы были гораздо больше. Сама змейки хранится в ArrayList. Были попытки сделать это через bitArray или через обычный массив, но в ArrayList всё как-то компактней получилось.
Как было сэкономлено место.
Экономия места в коде
1. Использование for, в параметрах которого записано несколько операций.
Пример:
было
2. ()?: вместо сложных if
3. инримент +±- совместно с if, — заменяет целые блоки switch-case
4. инициализация переменных в методах.
пример
было (1ая версия функции)
стало (2ая версия функции)
Уменьшения строк для пунктов 1-3 не дают уменьшения размера выходного apk, так как варианты «до» и «после» в jar-файле имеют примерно одинаковый код.
С пунктом 4 странно на получается странно. Если взять и протестировать использование функции summ в разных вариантах во всех трёх проектах (helloworld, small, snake), как изменяются размеры файлов при использовании в проекте этих методов, то получится следующая картина (цифры — количество байт):
Jar-файл уменьшается при использовании второй функции, а apk и dex увеличиваются. Скорее всего это связано с архивированием данных. Возможно, в некоторых случаях это даст свои результаты. Правда, они могут не оправдать Ваши ожидания.
На этом, пожалуй, всё.