Как сделать тетрис на паскале

Обновлено: 06.07.2024

Репутация: 0

Вот, недавно решил написать тетрис. Чисто для себя. Ну, вобщем за 3 дня написал, решил показать своё творение. Наверно многие процедуры можно короче сделать, но я пошел напролом по принципу "чтоб заработало". Для 15 лет нормально?

Скомпилированый:
Tetris.zip ( 37.52 килобайт ) Кол-во скачиваний: 1334

Исходник:
tetrispas.rar ( 21.72 килобайт ) Кол-во скачиваний: 1260

Репутация: 0

Эх, молчание. Хоть что-нибудь напишите.

Мда, видно все умерли от ужаса увидев мой исходник. Какой я злой, столько человек убил)))

Шесть, pygame для создания простой игры в тетрис (Basic 1)

1. Начальный интерфейс

Предыдущие игры были относительно простыми, поэтому код был написан процессно-ориентированным способом. На этот раз игра может быть более сложной (например, битва человек-машина, онлайн-битва, использование реквизита и т. Д.). На этот раз я пишу этот проект более объектно-ориентированным.
Окно игры разработано с использованием специального класса Panel для облегчения управления и контроля отдельного игрового окна.
Размер главного окна игры составляет 30 пикселей на квадрат, поэтому ширина составляет 3010 = 300, высота 3020=600


Изображение эффекта

2. Управление кубом


Прежде всего, я думаю, что различные типы блоков могут использовать фабричный режим, поэтому сначала определите базовый класс Block, а затем различные типы блоков наследуют от этого класса Block.Существует семь типов блоков.

В-третьих, создайте блоки и сбросьте блок

Определите функцию для создания блока

Добавьте атрибуты текущего движущегося блока в класс Panel и измените его метод рисования, чтобы нарисовать движущийся блок.

Создайте блок в основном цикле и отрегулируйте блок в начальное положение капли.

Установить время обновления местоположения

Обновить позицию текущего движущегося блока в основном цикле


Теперь вы можете увидеть эффект падения куба

В-четвертых, суждение о приземлении блока

Добавьте функцию оценки перемещения в класс Block, следующая функция can_move может определить, упал ли блок на дно

Измените функцию перемещения Panel на

Здесь добавлена ​​функция add_block для сохранения приземлившихся блоков, поэтому Panel внесла три дополнительных изменения.
1. Добавьте переменную массива для хранения отброшенных блоков.

2. Определите функцию add_block.

3. Нарисуйте self.rect_arr краской.


Теперь вы видите, что блок упадет на дно, а затем упадет новый блок.

Вставить текущую полную программу

Двумерная космическая стрелялка в духе Xenon MegaBlast. Можно редактировать карту, вражеские корабли, создавать новые эпизоды и уровни. BGI Graphics 640x480x256.

Игра - автомобильное ралли. В комплекте несколько различных трасс, со сложными поворотами, крутыми подъемами и спусками. Напоминает древнюю игрушку Death Track.

Вариация на тему СокоБан в стиле xixit. Смысл игры заключается в перетаскивании полудрагоценных камней на предназначенные для них места. Все бы ничего, но игровое поле представляет собой очень запутанный лабиринт, и на деле все оказывается не так просто.

01.04.1999

125k PackMan - Classic Game with BGI Graphics Frederic Gaonac'h

Простая реализация классической игры Packman. 07.12.1997

8k Pong - Ping-Pong Game with a Computer Frederic Gaonac'h

Тривиальная реализация игры Пинг-Понг [ BGI Graphics ] 07.12.1997

5k Pong - Ping-Pong Game for Two Players Frederic Gaonac'h

Тривиальная реализация игры Пинг-Понг для двух игроков [ BGI Graphics ] 07.12.1997

5k Power 4 - Tick-Tack-Toe like Game Frederic Gaonac'h

Тривиальная реализация одного из вариантов игры Крестики-Нолики. Нечто среднее между крестиками-ноликами и Нардами. [BGI Graphics] 07.12.1997

6k StarWars - 2D Shutter like Marsian War [BGI Graphics Frederic Gaonac'h

Тривиальная реализации игры в стиле древней игрушки "Война с марсианами". Несколько вражеских аппаратов бомбят "землю". Задача игрока - сбить все вражеские корабли и при этом уцелеть самому. 07.12.1997

8k Taquin - Classic "15" Game [BGI Graphics] Frederic Gaonac'h

Тривиальная реализация настольной игры "Пятнашки". На поле 4х4 расположено 15 пронумерованных фишек. Задача - за меньшее число ходов расположить фишки по возрастанию их номеров.
The goal is to put the tab under the form: 1234. 07.12.1997

5k Classic Tetris in BGI Graphics Frederic Gaonac'h

Тривиальная реализация игры "Тетрис". 07.12.1997

7k Double Tetris with BGI Graphics Frederic Gaonac'h

Тривиальная реализация игры ТЕТРИС, но только на экране оновременно ДВА тетриса! Управление расчитано на обе руки. 07.12.1997

8k MemCards - Simple Memory Training Game Frederic Gaonac'h

Тривиальная карточная игра для развития памяти [ BGI Graphics ]. Переворачиваем карты по одной и запоминаем, где какая расположена. Задача игрока - открыть 4 карты одинакового цвета.
The goal of the is to get the same colours together.

07.12.1997

5k Power 4 - Tick-Tack-Toe like Game for Two Players Frederic Gaonac'h

Тривиальная реализация одного из вариантов игры Крестики-Нолики. Нечто среднее между крестиками-ноликами и Нардами. Два игрока по очереди делают свой ход. [BGI Graphics] 07.12.1997

5k Mind Over Maze - Labirint Generator and Solver Randy Ding

Программа - генератор лабиринтов [BGI Graphics]. Позволяет создавать лабиринты с различным размером клеток и уровнем сложности. В созданном лабиринте можно сразу поиграть - попробовать найти выход. Управление - стрелками, выход - X. При выходе показывается путь, который ведет к выходу.
Mind Over Maze by Randy Ding. Use I,J,K,M or arrow keys to walk thru the maze, then hit X when you give up! 21.04.1992

7k Space Tennis Game [ Mode 13h ] 3D Clone Interactive

Игра в Теннис для двух игроков на фоне летящих звезд. Используется HSC player для фоновой музыки. Клавиши управления: 1й игрок - A,Z, 2й игрок - стрелки вверх.вниз. Выход по Esc.

Простая игра "Удавчик" для двух игроков. Цель игры - продержаться дольше противника, маневрируя по полю. Первый игрок управляет свои удавом с помощью стрелок, а второй - клавишами A,S,D,W.
Just one of the (dozens) of possible ways of doing the old Tron game.

Модуль для работы с прерываниями от клавиатуры и таймера, специально предназначенный для разработчиков игр. Манипулирует прерыванием Int09h и портом 60h. Позволяет распознавать сразу несколько одновременно нажатых клавиш и отслеживать интервалы времени с точностью до 1 тика (~55ms).
GAMES.TPU is a Turbo Pascal unit designed to rework the keyboard and timer interrupts to better function in game writing.

Простая игрушка с использованием BGI-графики, встроенного HSC-плайера, и поддержкой мышки. Напоминает игру "Нарды". Играют человек и компьютер. Задача игрока - перемещать монетки на несколько позиций вперед таким образом, чтобы последний ход остался за ним. 29.08.1997

722k Игра "Морской Бой" Nikolay Okulov

Очень простая реализация классической игры "Морской Бой". Человек играет с компьютером. С помощью мышки указывает клетку в поле 10х10, в которую он "стреляет". Компьютер делает оветный ход. BGI-графика, 320x200x256.
"Sea Battle" classic game. Mouse support, BGI. 22.11.2000

16k Кубик Рубика Евгений Скляревский

Графическая игра "Кубик Рубика" для TP5.5-7.0. BGI-графика. Кубик можно крутить с помощью цифровой клавиатуры. Для запуска необходим драйвер EGAVGA.BGI

Графическая игра Шашки для BP7. Управление только клавишами. Для работы необходимы BGI драйвер EgaVga.bgi и русифицированные CHr Шрифты. Режимы игры: два игрока, игрок против компьютера или компьютер против компьютера.

Программа демонстрирует перемещение по сцене, напоминающей эпизоды игры Doom. Кроме того, прилагается дополнительная программа для генерации произвольной карты и WAD файла.
This small programms creates a small map like the DOOM scenes and walks around it. You can modify the map and recompile it to new WAD file.

Вот, написал тетрис на делфи. Интерфейс делел похожий на китайские тетрисы (9999 in 1), и оно так и получилось.
Также есть таблица рекордов на 20 записей.
Поводом, для написсания было вот что: Прочитал в википедии, что "первая реализация тетриса была написана 16-летним Вадимом Герасимовым", и как-то стыдно за себя стало. И вот, сейчас исполнил свой долг
Вобщем, играйте наздоровье

3 пользователя(ей) сказали cпасибо:

07.08.2011, 19:56

Хороший тетрис, с музыкой, играл играл, играл играл, задолбало))) специально запоролся на 15900, т.к. на такой скорости играть можно вечно.

10.08.2011, 01:33

Предлагаю назвать программу "дункан маклауд тетрис" и в качестве пожеления, можно было бы сделать опцию сохранить игру и загрузить игру.
Tetris.jpg

10.08.2011, 22:48

Да, надо попробывать.
Есть идея сделать полный эмулятор китайского тетриса со змейкой. гоночками, танчиками, но один я врадли справлюсь

11.08.2011, 02:12

В предыдущих статьях этой серии мы уже успели написать сапёра, змейку и десктопный клон игры 2048. Попробуем теперь написать свой Тетрис.

Нам, как обычно, понадобятся:

  • 30 минут свободного времени;
  • Настроенная рабочая среда, т.е. JDK и IDE (например, Eclipse);
  • Библиотека LWJGL (версии 2.x.x) для работы с графикой (опционально). Обратите внимание, что для LWJGL версий выше 3 потребуется написать код, отличающийся от того, что приведён в статье;
  • Спрайты, т.е. картинки плиток всех возможных состояний (пустая, и со степенями двойки до 2048). Можно нарисовать самому, или скачать использовавшиеся при написании статьи.

Прежде чем задавать вопрос в комментариях, не забудьте заглянуть в предыдущие статьи, возможно там на него уже давался ответ. Исходный код готового проекта традиционно можно найти на GitHub.

С чего начать?

Начать стоит с главного управляющего класса, который в нашем проекте находится выше остальных по уровню абстракции. Вообще отличный совет — в начале работы всегда пишите код вида if (getKeyPressed()) doSomething() , так вы быстро определите фронт работ.

Это наш main() . Он ничем принципиально не отличается от тех, что мы писали в предыдущих статьях — мы всё так же инициализируем поля и, пока игра не закончится, осуществляем по очереди: ввод пользовательских данных ( input() ), основные игровые действия ( logic() ) и вызов метода отрисовки у графического модуля ( graphicsModule.draw() ), в который передаём текущее игровое поле ( gameField ). Из нового разве что метод sync — метод, который должен будет гарантировать нам определённую частоту выполнения итераций. С его помощью мы сможем задать скорость падения фигуры в клетках-в-секунду.

Вы могли заметить, что в коде использована константа FPS . Все константы удобно определять в классе с public static final полями. Полный список констант, который нам потребуется в ходе разработки, можно посмотреть в классе Constants на GitHub.

Оставим пока инициализацию полей на потом (мы же ещё не знаем, какие нам вообще понадобятся поля). Разберёмся сначала с input() и logic() .

Получение данных от пользователя

Код, честно говоря, достаточно капитанский:

Все данные от ввода мы просто сохраняем в соответствующие поля, действия на основе них будет выполнять метод logic() .

Теперь уже потихоньку становится понятно, что нам необходимо. Во-первых, нам нужны клавиатурный и графический модули. Во-вторых, нужно как-то хранить направление, которое игрок выбрал для сдвига. Вторая задача решается просто — создадим enum с тремя состояниями: AWAITING, LEFT, RIGHT . Зачем нужен AWAITING ? Чтобы хранить информацию о том, что сдвиг не требуется (использования в программе null следует всеми силами избегать). Перейдём к интерфейсам.

Интерфейсы для клавиатурного и графического модулей

Так как многим не нравится, что я пишу эти модули на LWJGL, я решил в статье уделить время только интерфейсам этих классов. Каждый может написать их с помощью той GUI-библиотеки, которая ему нравится (или вообще сделать консольный вариант). Я же по старинке реализовал их на LWJGL, код можно посмотреть здесь в папках graphics/lwjglmodule и keyboard/lwjglmodule.

Интерфейсы же, после добавления в них всех упомянутых выше методов, будут выглядеть следующим образом:

Отлично, мы получили от пользователя данные. Что дальше?

А дальше мы должны эти данные обработать и что-то сделать с игровым полем. Если пользователь сказал сдвинуть фигуру куда-то, то передаём полю, что нужно сдвинуть фигуру в таком-то направлении. Если пользователь сказал, что нужно фигуру повернуть, поворачиваем, и так далее. Кроме этого нельзя забывать, что 1 раз в FRAMES_PER_MOVE (вы же открывали файл с константами?) итераций нам необходимо сдвигать падающую фигурку вниз.

Сюда же добавим проверку на переполнение поля (в Тетрисе игра завершается, когда фигурам некуда падать):

Так, а теперь мы напишем класс для того магического gameField, в который мы всё это передаём, да?

Не совсем. Сначала мы пропишем поля класса Main и метод initFields() , чтобы совсем с ним закончить. Вот все поля, которые мы использовали:

А инициализировать мы их будем так:

Если вы решили не использовать LWJGL и написали свои классы, реализующие GraphicsModule и KeyboardHandleModule , то здесь нужно указать их конструкторы вместо, соответственно new LwjglGraphicsModule() и new LwjglKeyboardHandleModule() .

А вот теперь мы переходим к классу, который отвечает за хранение информации об игровом поле и её обновление.

Класс GameField

Этот класс должен, во-первых, хранить информацию о поле и о падающей фигуре, а во-вторых, содержать методы для их обновления, и получения о них информации — кроме тех, которые мы уже использовали, необходимо написать метод, возвращающий цвет ячейки по координатам, чтобы графический модуль мог отрисовать поле.

Начнём по порядку.

Хранить информацию о поле…

…и о падающей фигуре

TpReadableColor — простой enum, содержащий элементы с говорящими названиями (RED, ORANGE и т.п.) и метод, позволяющий получить случайным образом один из этих элементов. Ничего особенного в нём нет, код можно посмотреть тут.

Это все поля, которые нам понадобятся. Как известно, поля любят быть инициализированными.
Сделать это следует в конструкторе.

Конструктор и инициализация полей

Далее в конструкторе стоит заполнить массив theField значениями константы EMPTINESS_COLOR , а countFilledCellsInLine — нулями (второе в Java не требуется, при инициализации массива все int‘ы равны 0). Или можно создать несколько слоёв уже заполненных ячейкам — на GitHub вы можете увидеть реализацию именно второго варианта.

А что это там за spawnNewFigure()? Почему инициализация фигуры вынесена в отдельный метод?

Вы правильно догадались, spawnNewFigure() действительно инициализирует поле figure . А в отдельный метод это вынесено, потому что нам придётся делать инициализацию каждый раз, когда будет создаваться новая фигура.

На этом с хранением данных мы закончили. Переходим к методам, которые отдают информацию о поле другим классам.

Методы, передающие информацию об игровом поле

Таких метода всего два. Первый возвращает цвет ячейки (для графического модуля):

А второй сообщает, переполнено ли поле (как это происходит, мы разобрали выше):

Методы, обновляющие фигуру и игровое поле

Начнём реализовывать методы, которые мы вызывали из Main.logic() .

Сдвиг фигуры

Что мы сделали в этом методе? Мы запросили у фигуры ячейки, которые бы она заняла в случае сдвига. А затем для каждой из этих ячеек мы проверяем, не выходит ли она за пределы поля, и не находится ли по её координатам в сетке статичный блок. Если хоть одна ячейка фигуры выходит за пределы или пытается встать на место блока — сдвига не происходит. Coord здесь — класс-оболочка с двумя публичными числовыми полями (x и y координаты).

Поворот фигуры

Логика аналогична сдвигу:

Падение фигуры

Сначала код в точности повторяет предыдущие два метода:

Так как в результате переноса ячеек какая-то линия может заполниться полностью, после каждого добавления ячейки мы проверяем линию, в которую мы её добавили, на полноту:

Этот метод возвращает истину, если линию удалось уничтожить. После добавления всех кирпичиков фигуры в сетку (и удаления всех заполненных линий), мы, при необходимости, запускаем метод, который сдвигает на место пустых линий непустые:

Теперь GameField реализован почти полностью — за исключением геттера для фигуры. Её ведь графическому модулю тоже придётся отрисовывать:

Теперь нам нужно написать алгоритмы, по которым фигура определяет свои координаты в разных состояниях. Да и вообще весь класс фигуры.

Класс фигуры

Rotation мод здесь будет выглядеть таким образом:

Соответственно, от самого класса Figure нам нужен только конструктор, инициализирующий поля:

И методы, которыми мы пользовались в GameField следующего вида:

Вдобавок, у фигуры должен быть цвет, чтобы графический модуль мог её отобразить. В тетрисе каждой фигуре соответствует свой цвет, поэтому цвет мы будем запрашивать у формы:

Форма фигуры и маски координат

Чтобы не занимать лишнее место, здесь я приведу реализацию только для двух форм: I-образной и J-образной. Код для остальных фигур принципиально не отличается и выложен на GitHub.

Реализуем методы, которые использовали выше:

Ну а сами маски координат я предлагаю просто захардкодить следующим образом:

Т.е. для каждого объекта enum‘а мы передаём с помощью импровизированных (других в Java нет) делегатов метод, в котором в зависимости от переданного состояния поворота возвращаем разные реальные координаты блоков. В общем-то, можно обойтись и без делегатов, если хранить в каждом элементе отсупы для каждого из режимов поворота.

Читайте также: