Содержание
Введение.3
Глава I.Разработка информационного WEB-сайта.
1.1.Описания языка HTML для создания сайта.5
1.2.Структура HTML.7
Глава II.Язык сценариев JavaScript.
2.1.Введение в JavaScript.12
2.2.Объектная модель JavaScript.16
Практическая часть.21
Заключение.27
Список использованной литературы.28
Выдержка из текста работы
В данной курсовой работе реализуется игра «Тетрис». При реализации программы будет использоваться объектно-ориентированный подход, важным следствием чего является возможность формирования такой структуры программы, когда добавление новых компонентов при ее дальнейшем развитии не будет влиять на существующие компоненты, или такое влияние будет сведено к минимуму.
Для написания кода игры используется язык Java, что способствует получению надежного программного продукта.
Целью данной работы является разработка игры «Тетрис». Она относится к логическим играм, которые помогают развить реакцию, тренируют логику. При длительной работе за компьютером возникает желание немного отдохнуть. Для этой цели подходят игры типа стратегий, поскольку для них требуется много времени, а для 5-10 минутного отдыха вполне подойдет именно «Тетрис». В стандартной поставке операционных систем данной игры нет, поэтому возникла необходимость в ее создании.
Задачами курсовой работы является изучение объектно-ориентированного языка программирования Java, рассмотрение игры Тетрис, и создание программного кода на языке Java.
К играм такого типа предъявляются следующие требования: использование простых средств управления; удобный графический интерфейс, постепенное усложнение игры при наборе определенного количества очков. Во время выполнения программа должна выполняться корректно и не приводить к сбоям.
Смысл игры заключается в стремлении плотно занять игровое поле падающими геометрическими фигурами, изменяя их ориентацию в пространстве, добиваясь отсутствия пробелов в каждой строке.
Фигуры не должны выходить за пределы игрового поля, они перемещаться и переворачиваться. Для придания большей привлекательности внешнему виду игрового поля при написании игры нужно использовать яркую графику. Интерфейс программы, разрабатываемой должен быть удобен и понятен пользователю.
Программа должна реагировать на нажатие клавиш клавиатуры, выводя изображение на экран.
1. Введение в язык программирования Java
1.1 История развития языка программирования Java
Java изначально появилась на свет как язык для создания небольших приложений для Интернета (апплетов), но со временем развилась как универсальная платформа для создания программного обеспечения, которое работает буквально везде — от мобильных устройств и смарт-карт до мощных серверов.
Данная курсовая начинается с изложения истории появления и развития Java. Такие знания позволят лучше понять особенности платформы и спектр существующих продуктов и технологий. Также создание Java является интересным примером истории одного из самых популярных и успешных проектов в компьютерном мире. Затем излагаются основные концепции ООП, необходимые для освоения объектно-ориентированного языка программирования Java. Ключевые понятия и конструкции языка описываются доступным языком, но, тем не менее, на достаточно глубоком уровне. Детально рассмотрены особенности лексики, системы типов данных, объектной модели. Уделяется особое внимание модификаторам доступа, соглашениям по именованию, преобразованию типов, работе с массивами, обработке ошибок (исключительных ситуаций). Курсовая завершается рассмотрением базовых библиотек Java, предоставляющих всю необходимую функциональность для создания самых разных приложений — коллекции объектов, работа с файлами, сетью, создание GUI приложений, построение многопоточной архитектуры и многое другое. Описание сетевой библиотеки предваряется изложением основ сетевых протоколов и технологий.
Казалось бы, на сегодняшний день изобретены уже все языки программирования, какие только можно придумать. Но нет — появился еще один, с названием Java. Этот язык сумел получить весьма заметную известность за последние несколько лет, так как он ориентирован на самую популярную компьютерную среду — сеть Internet и серверы Web.
Персональные компьютеры сделали информационные технологии частью массовой культуры. И тем не менее, уже довольно длительная история развития персональных компьютеров не знала ничего, подобного феномену Java. Что изменилось в мире в последние годы, почему этот феномен стал возможен?
Изменился Интернет. Он стал доступен миллионам людей, далеких от технических проблем. Число пользователей Интернет по порядку величины уже не отличается от числа пользователей персональных компьютеров и продолжает взрывообразно расти. Одновременно Интернет обеспечил такую скорость распространения новинок информационных технологий, которую не могли и никогда не смогут дать традиционные каналы сбыта. Время спрессовалось. В Интернет, опоздав буквально на день, компьютерная компания, даже крупная, рискует серьезно ослабить свои позиции сразу во всем мире.
Язык Java произошел от языка программирования Oak (а не от C++, как думают многие). Oak был приспособлен для работы в Internet и затем переименован в Java.
Синтаксис Java близок к синтаксису языка C++. Унаследовав самое лучшее от языка программирования C++, язык Java при этом избавился от некоторых недостатков C++, в результате чего на нем стало проще программировать. В этом языке нет, например, указателей, которые сложны в использовании и потенциально могут послужить причиной доступа программы к не принадлежащей ей области памяти. Нет множественного наследования и шаблонов, хотя функциональные возможности языка Java от этого не пострадали.
Огромное преимущество Java заключается в том, что на этом языке можно создавать приложения, способные работать на различных платформах. К сети Internet подключены компьютеры самых разных типов — Pentium PC, Macintosh, рабочие станции Sun и так далее. Даже в рамках компьютеров, созданных на базе процессоров Intel, существует несколько платформ, например, MicrosoftWindows версии 3. 1, Windows 95, Windows NT, OS/2, Solaris, различные разновидности операционной системы UNIX с графической оболочкой XWindows. Между тем, создавая сервер Web в сети Internet, хотелось бы, чтобы им могло пользоваться как можно большее число людей. В этом случае выручают приложения Java, предназначенные для работы на различных платформах и не зависящие от конкретного типа процессора и операционной системы.
Программы, составленные на языке программирования Java, можно разделить по своему назначению на две большие группы.
К первой группе относятся приложения Java, предназначенные для автономной работы под управлением специальной интерпретирующей машины Java. Реализации этой машины созданы для всех основных компьютерных платформ. Вторая группа — это так называемыеаплеты (applets). Аплеты представляют собой разновидность приложений Java, которые интерпретируются виртуальной машиной Java, встроенной практически во все современные браузеры.
Приложения, относящиеся к первой группе (будем называть их просто приложениями Java), — это обычные автономные программы. Так как они не содержат машинного кода и работают под управлением специального интерпретатора, их производительность заметно ниже, чем у обычных программ, составленных, например, на языке программирования C++. Однако не следует забывать, что программы Java без перетрансляции способны работать на любой платформе, что само по себе имеет большое значение в плане разработок для Internet.АплетыJava встраиваются в документы HTML, хранящиеся на сервере Web. С помощью аплетов можно сделать страницы сервера Web динамичными и интерактивными. Аплеты позволяют выполнять сложную локальную обработку данных, полученных от сервера Web или введенных пользователем с клавиатуры. Из соображений безопасности аплеты (в отличие от обычных приложений Java) не имеют никакого доступа к файловой системе локального компьютера. Все данные для обработки они могут получить только от сервера Web. Более сложную обработку данных можно выполнять, организовав взаимодействие между аплетами и расширениями сервера Web приложениями CGI и ISAPI.
Для повышения производительности приложений Java в современных браузерах используется компиляция «на лету»— Just-In-Timecompilation (JIT). При первой загрузке аплета его код транслируется в обычную исполнимую программу, которая сохраняется на диске и запускается. В результате общая скорость выполнения аплетаJava увеличивается в несколько раз.
Язык Java является объектно-ориентированным и поставляется с достаточно объемной библиотекой классов. Так же как и библиотеки классов систем разработки приложений на языке C++, библиотеки классов Java значительно упрощают разработку приложений, представляя в распоряжение программиста мощные средства решения распространенных задач. Поэтому программист может больше внимания уделить решению прикладных задач, а не таких, как, например, организация динамических массивов, взаимодействие с операционной системой или реализация элементов пользовательского интерфейса.
Информационные перегрузки — характерная черта нашего времени. Созданы мощные механизмы, обеспечивающие производство огромного количества информации. Существенно меньше сделано для облегчения ее получения и усвоения. Типичной является ситуация, когда инициатива принадлежит поставщику, а не потребителю информации. Поставщик по определенному поводу создает информацию и направляет ее всем, кто, по его мнению, в ней нуждается.
Так работают средства массовой информации, издательства, рекламные агентства. Как работает электронная почта. В большинстве случаев потребителю эта информация, может быть, и нужна, но не в данный момент, не сейчас. Потребитель вынужден архивировать полученную информацию. При этом в лучшем случае велика вероятность, что к моменту, когда информация действительно понадобится, она потеряет актуальность. Обычно же у потребителя просто накапливаются горы мусора, в котором отыскать нечто нужное почти невозможно.
Чтобы информация была актуальной для потребителя, она должна доставляться к нему по запросу — в точности тогда, когда в ней возникла необходимость. Кроме того, поставщик должен сохранять возможность управления информацией, он должен не только создавать ее, но и вовремя обновлять и уничтожать. Централизованные компьютерные системы, доминировавшие еще 10 лет назад, позволяли пользователям сравнительно легко находить информацию в оперативном режиме, однако они затрудняли управление информацией, поскольку ее источники,
как правило, разнородны и территориально разнесены.
Еще один важный недостаток централизованных систем — их сложность и дороговизна. Сети персональных компьютеров существенно дешевле централизованных систем, они оставляют за поставщиком необходимую свободу управления информацией, однако потребителям приходится искать необходимые данные на множестве машин, среди большого числа приложений с различными интерфейсами. Рядовому пользователю работать в такой разнородной прикладной среде крайне неудобно.
Способ разрешения указанных проблем, к которому прибегают ведущие компании, состоит в построении информационной структуры организации по образу и подобию Интернет, с Web-сервисом в качестве концептуальной основы.
Возможность хранения данных различных типов (текст, графика, аудио, видео) в сочетании с механизмами связывания информации, расположенной в разных узлах компьютерной сети, позволяют рассредоточивать информацию в соответствии с естественным порядком ее создания и потребления, осуществлять единообразный доступ, отправляясь от небольшого числа известных «корней». Тем самым поставщик может эффективно готовить и контролировать информацию, а потребитель в состоянии без труда найти необходимые данные именно тогда, когда они стали нужны.
Средства Web, помимо связывания распределенных данных, осуществляют еще одну очень важную функцию. Они позволяют рассматривать информацию с нужной степенью детализации, что существенно упрощает анализ больших объемов данных. Можно быстро отобрать самое интересное, а затем изучить выбранный материал во всех подробностях.
Таким образом, Web-серверы и Web-навигаторы могут и должны использоваться не только в «мировом масштабе». Web — это инфраструктурный сервис, необходимый каждой организации со сколько-нибудь заметными информационными потоками. В то же время, Web-сервису присущи и определенные недостатки, вытекающие из отсутствия объектной ориентации и из природы HTTP-протокола. Во-первых, клиент по существу лишен средств управления внешним представлением объектов на просматриваемой WWW-странице.
Во-вторых, Web-страницы статичны. При использовании протокола HTTP, на клиентскую систему передаются только пассивные данные, но не методы объектов. Из общих соображений очевидна ограниченность подобного подхода. Данный недостаток, разумеется, связан с первым. Объект сам должен знать, как себя показывать — точнее говоря, он должен это выяснить, проанализировав клиентское окружение.
В-третьих, Web-сервис обладает весьма ограниченными интерактивными возможностями, которые сводятся к заполнению пользователем чисто текстовых форм с последующей отправкой на сервер. Сервер анализирует полученные данные, после чего формирует и возвращает клиенту новую WWW-страницу, которая нередко вновь оказывается формой. Такой стиль общения не всегда устраивает пользователей. Java-технология позволяет устранить все отмеченные недостатки. Как именно будет ясно из последующего изложения. В результате Web-сервис, и без того имевший огромную популярность, получил как бы новый импульс. Этот экспресс понесся вперед с удвоенной скоростью, увлекая за собой и Java. JAVA, JOE, NEO.
1.2 Язык Java — это объектно-ориентированный язык программирования
В узком смысле слова Java — это объектно-ориентированный язык, напоминающий C++, но более простой для освоения и использования. В более широком смысле Java — это целая технология программирования, изначально рассчитанная на интеграцию с Web-сервисом, то есть на использование в сетевой среде, Поскольку Web-навигаторы существуют практически для всех аппаратно-программных платформ, Java-среда должна быть как можно более мобильной, в идеале полностью независимой от платформы.
С целью решения перечисленных проблем были приняты, помимо интеграции с Web-навигатором, два других важнейших постулата:
Была специфицирована виртуальная Java-машина, на которой должны выполняться (интерпретироваться) Java-программы. Определены ее архитектура, представление элементов данных и система команд. Исходные Java-тексты транслируются в коды этой машины. Тем самым, при появлении новой аппаратно-программной платформы в портировании будет нуждаться только Java-машина; все программы, написанные на Java, пойдут без изменений.
Определено, что при редактировании внешних связей Java-программы и при работе Web-навигатора прозрачным для пользователя образом может осуществляться поиск необходимых объектов не только на локальной машине, но и на других компьютерах, доступных по сети (в частности, на WWW-сервере). Найденные объекты загружаются, а их методы выполняются затем на машине пользователя.
Несомненно, между двумя сформулированными положениями существует тесная связь. В компилируемой среде трудно как дистанцироваться от аппаратных особенностей компьютера, так и реализовать прозрачную динамическую загрузку по сети. С другой стороны, прием объектов извне требует повышенной осторожности при работе с ними, а, значит, и со всеми Java-программами. Принимать необходимые меры безопасности проще всего в интерпретируемой среде. Вообще, мобильность, динамизм и безопасность — спутники интерпретатора, а не компилятора. Принятые решения сделали Java-среду идеальным средством разработки клиентских компонентов Web-систем. Особо отметим прозрачную для пользователя динамическую загрузку объектов по сети. Из этого вытекает такое важнейшее достоинство, как нулевая стоимость администрирования клиентских систем, написанных на Java. Достаточно обновить версию объекта на сервере, после чего клиент автоматически получит именно ее, а не старый вариант. Без этого реальная работа с развитой сетевой инфраструктурой практически невозможна. С другой стороны, при наличии динамической загрузки действительно возможно появление устройств класса Java-терминалов, изначально содержащих только WWW-навигатор, а все остальное (и программы, и данные) получающих по сети.
Здесь уместно отметить замечательную точность в выборе основных посылок проекта Java. Из минимума предположений вытекает максимум новых возможностей при сохранении практичности реализации.
В то же время, интеграция с WWW-навигатором и интерпретируемая природа Java-среды ставят вполне определенные рамки для реального использования Java-программ (хотя, конечно же, язык Java не менее универсален, чем, скажем, C++). Например, известно, что интерпретация, по сравнению с прямым выполнением, на 1-2 порядка медленнее. Применение компиляции «на лету» и специализированных Java-процессоров, несомненно, улучшит ситуацию, но пока использование Java на серверной стороне представляется проблематичным.
Хотя технология Интернет, основанная на использовании Web-сервиса в качестве информационной основы организации, является огромным шагом вперед, существуют и другие сервисы, как унаследованные, так и современные (например, реляционные СУБД), которые обязательно должны входить в состав корпоративной системы.
Если вся связь между клиентами и упомянутыми серверами будет осуществляться через сервер WWW, последний станет узким местом, а решения Интернет рискуют лишиться такого важнейшего достоинства, как масштабируемость. Значит, необходима прямая связь между клиентскими системами, написанными на языке Java, и произвольными сервисами. Как реализовать такую связь?
В общем виде ответ очевиден — нужны средства для полноценной интеграции Java в распределенную объектную среду. На серверной стороне компания SunMicrosystems имеет соответствующую технологию — NEO (NEtworkedObjects, сетевые объекты). Технология NEO удовлетворяет спецификациям OMG (ObjectManagementGroup), являющимся промышленным стандартом. При реализации корпоративных информационных систем с использованием NEO наиболее естественным представляется использование трехуровневой архитектуры с серверами приложений, построенными на объектных принципах, на втором уровне и с базовыми и унаследованными серверами натретьем уровне.
К сожалению, столь общий ответ никак не помогает осуществлять прямую связь между Java-клиентом и NEO-сервером. Конечно, можно воспользоваться стандартными средствами программирования в сетевой среде (а Java допускает использование библиотек, написанных на C/C++, равно как и вставку машинных кодов), но если бы это было единственной возможностью, Java рисковала остаться на уровне «оживлялок».
В конце марта компания SunSoft объявила о появлении нового продукта с именем Joe, как раз и предназначенного для существенного облегчения встраивания Java-клиентов в информационные системы Интернет, построенные в трехуровневой архитектуре с использованием среды NEO.
Таким образом, сложилась полная и изумительно красивая картина организации современных Интернет-систем.
1.3 Java — язык и технология
Язык программирования Java является мобильным. Это нужно понимать в том смысле, что имеется принципиальная возможность переноса программ Java на различные платформы.
Однако следует отметить, что создание приложений, действительно работающих на разных платформах — непростая задача. К сожалению, дело не ограничивается необходимостью перекомпиляции исходного текста программы для работы в другой среде. Много проблем возникает с несовместимостью программных интерфейсов различных операционных систем и графических оболочек, реализующих пользовательский интерфейс.
Вот хотя бы проблемы, связанные с переносом 16-разрядных приложений Windows в 32-разрядную среду Windows 95 и Windows NT. Даже если тщательно следовать всем рекомендациям, разрабатывая приложения так, чтобы они могли работать в будущих версиях Windows, едва ли удастся просто перекомпилировать исходные тексты, не изменив в них ни строчки. Ситуация еще больше ухудшается, если нужно, например, перенести исходные тексты приложения Windows в среду операционной системы OS/2 или в оболочку X-Windows операционной системы UNIX. А ведь есть еще другие компьютеры и рабочие станции!
Как нетрудно заметить, даже если стандартизовать язык программирования для всех платформ, проблемы совместимости с программным интерфейсом операционной системы значительно усложняют перенос программ на различные платформы. И, конечно, нужно, чтобы загрузочный модуль одной и той же программы мог работать без изменений в среде различных операционных систем и на различных платформах. Если программа подготовлена для процессора Intel, она ни за что не согласится работать на процессоре Alpha или каком-либо другом.
В результате создавая приложение, способное работать на различных платформах, необходимо фактически делать несколько различных приложений и сопровождать их по отдельности.
Покажем, как приложение, изначально разработанное для Windows NT, переносится на платформу AppleMacintosh. Вначале программист готовит исходные тексты приложения для платформы Windows NT и отлаживает их там. Для получения загрузочного модуля исходные тексты компилируются и редактируются. Полученный в результате загрузочный модуль может работать на процессоре фирмы Intel в среде операционной системы Windows NT.
Для того чтобы перенести приложение в среду операционной системы компьютера Macintosh, программист вносит необходимые изменения в исходные тексты приложения. Эти изменения необходимы из-за различий в программном интерфейсе операционной системы Windows NT и операционной системы, установленной в Macintosh. Далее эти исходные тексты транслируются и редактируются, в результате чего получается загрузочный модуль, способный работать в среде Macintosh, но не способный работать в среде Windows NT.
Программа на языке Java компилируется в двоичный модуль, состоящий из команд виртуального процессора Java. Такой модуль содержит байт-код, предназначенный для выполнения Java-интерпретатором. На настоящий момент уже созданы первые модели физического процессора, способного выполнять этот байт-код, однако интерпретаторы Java имеются на всех основных компьютерных платформах. Разумеется, на каждой платформе используется свой интерпретатор, или, точнее говоря, свой виртуальный процессор Java.
Если приложение Java (или апплет) должно работать на нескольких платформах, нет необходимости компилировать его исходные тексты несколько раз. Можно откомпилировать и отладить приложение Java на одной, наиболее удобной для вас платформе. В результате вы получите байт-код, пригодный для любой платформы, где есть виртуальный процессор Java. Таким образом, приложение Java компилируется и отлаживается только один раз, что уже значительно лучше. Остается, правда, вопрос — как быть с программным интерфейсом операционной системы, который отличается для разных платформ?
Приложение Java не обращается напрямую к интерфейсу операционной системы. Вместо этого оно пользуется готовыми стандартными библиотеками классов, содержащими все необходимое для организации пользовательского интерфейса, обращения к файлам, для работы в сети и так далее.
Внутренняя реализация библиотек классов зависит от платформы. Однако все загрузочные модули, реализующие возможности этих библиотек, поставляются в готовом виде вместе с виртуальной машиной Java, поэтому программисту не нужно об этом заботиться. Для операционной системы Windows, например, поставляются библиотеки динамической загрузки DLL, внутри которых запрятана вся функциональность стандартных классов Java.
Абстрагируясь от аппаратуры на уровне библиотек классов, программисты могут больше не заботиться о различиях в реализации программного интерфейса конкретных операционных систем. Это позволяет создавать по-настоящему мобильные приложения, не требующие при переносе на различные платформы перетрансляции и изменения исходного текста.
Еще одна проблема, возникающая при переносе программ, составленных на языке программирования С, заключается в том, что размер области памяти, занимаемой переменными стандартных типов, различный на разных платформах. Например, в среде операционной системы Windows версии 3. 1 переменная типа int в программе, составленной на С, занимает 16 бит. В среде Windows NT этот размер составляет 32 бита.
Очевидно, что трудно составлять программу, не зная точно, сколько имеется бит в слове или в байте. При переносе программ на платформы с иной разрядностью могут возникать ошибки, которые трудно обнаружить.
В языке Java все базовые типы данных имеют фиксированную разрядность, которая не зависит от платформы. Поэтому программисты всегда знают размеры переменных в своей программе.
2. История создания тетриса
Темтрис (производное от «тетрамино» и «теннис»), англ. Tetris — культовая компьютерная игра, изобретённая в СССР Алексеем Пажитновым и представленная общественности 6 июня 1984 года. Идею «Тетриса» ему подсказала купленная им игра в пентамино.
2.1 Правила игры тетрис
Случайные фигурки тетрамино падают сверху в прямоугольный стакан шириной 10 и высотой 20 клеток. В полёте игрок может поворачивать фигурку и двигать её по горизонтали. Также можно «сбрасывать» фигурку, то есть ускорять её падение, когда уже решено, куда фигурка должна упасть. Фигурка летит, пока не наткнётся на другую фигурку либо на дно стакана. Если при этом заполнился горизонтальный ряд из 10 клеток, он пропадает и всё, что выше его, опускается на 1 клетку. Темп игры постепенно увеличивается. Название игры происходит от количества клеток, из которых состоит каждая фигура. Игра заканчивается, когда новая фигурка не может поместиться в стакан. Игрок получает очки за каждую фигурку, поэтому его задача — заполнять ряды, не заполняя сам стакан как можно дольше, чтобы таким образом получить как можно больше очков.
2.2 Начисление очков в игре тетрис
Начисление очков в разных версиях «Тетриса» довольно разнообразное. Очки могут начисляться за убранные линии, за сброшенные фигурки, за переход на новую скорость и тому подобное.
При начислении очков за линии количество очков обычно зависит от того, сколько линий убрано за один раз. Например, в китайских «Тетрисах», популярных в СНГ в 1990-х годах, начисление очков обычно было таким: 1 линия — 100 очков, 2 линии — 300 очков, 3 линии — 700 очков, 4 линии (то есть, сделать Тетрис) — 1500 очков. То есть, чем больше линий убирается за один раз, тем больше отношение количества очков к количеству линий. Любопытно, что тетрисом во многих версиях игры также называется действие, после которого исчезает сразу 4 линии. Это можно сделать только одним способом — сбросить «палку» (фигурку, в которой все клетки расположены на одной линии) в «шахту» ширины 1 и глубины как минимум 4.
При начислении очков за сброшенные фигурки могут учитываться высота, на которой остановилась фигурка (например, чем ниже, тем лучше), расстояние, которое пролетела фигурка после «сбрасывания» (ускорения падения). Хотя обычно приоритетом являются линии, а за фигурки начисляется относительно небольшое количество очков.
2.3 Теоретические проблемы
Обычно игрок проигрывает из-за того, что не может справиться со слишком быстрым темпом игры, или потому, что данная реализация реагирует на клавиши слишком медленно по сравнению с ускоряющимся темпом падения фигурок, вследствие чего игрок уже не может в принципе приложить достаточное количество сдвигов к фигурке.
Была опубликована статья, автор которой доказывает, что даже если бы игрок реагировал мгновенно и всегда принимал правильные решения, то и в этом случае он бы в конечном счёте проиграл. Проблемой являются S- и Z-образные фигурки. Достаточно большое количество S-фигурок заставит игрока оставить дырку в правом нижнем углу. Достаточно большое количество Z-фигурок после этого заставит игрока оставить дырку в левом углу следующего ряда, не заполнив предыдущую дырку. Если после этого опять выпадет достаточно много S-фигурок, достаточно много Z-фигурок, и так много раз, заполнится (с дырками по краям) всё поле, и для следующей фигурки места не останется. Если генератор случайных чисел идеален, любая (в том числе и такая) комбинация рано или поздно выпадет
Однако среднее время, через которое выпадет такая комбинация, огромно и превышает время существования Вселенной. Тем не менее, не исключено, что существует какая-то другая, более трудная для доказательства причина, по которой идеальный игрок должен проиграть намного раньше указанной верхней границы.
Некоторые задачи, решения которых применяются в игре, являются NP-полными.
3. Этапы программирования
В данном разделе будет подробно рассмотрен каждый из классов данной работы, его поля и методы.
Для написания окна программы,и панели управления и главного класса и проигрование музыки будем использовать следующие функции которые представлены в таблицах 1 и 2
Таблица — 1интерфейс игры
Поле |
Описание поля |
|
у finalstaticint PLAY = 1 |
Состояние «игра в процессе» |
|
finalstaticint STOP = 2 |
Сосотояние «игра остановлена» |
|
finalstaticint PAUSE =3 |
Состояние «играприостановлена» |
Таблица — 2 интерфейс игры
Метод |
Описание метода |
|
publicvoidstartNewGame() |
Начать новуюигру |
|
publicvoidpauseGame() |
Приостановить игру |
|
publicvoidresumeGame() |
Продолжить игру |
|
publicvoidstopGame() |
Остановить игру |
|
publicintgetScore() |
Получить счет |
|
publicintgetState() |
Получить состояние игры |
|
publicvoidfigureMoveRight() |
Двигать фигуру вправо |
|
publicvoidfigureMoveLeft() |
Двигать фигурувлево |
|
publicvoidfigureMoveDown() |
Двигать фигуру вниз |
|
publicvoidfigureRotate() |
Повернуть фигуру |
|
publicvoidgamePauseResume() |
Изменить состояние игры pause на play и наоборот |
|
publicstaticvoidmain(String[] args) |
Запуск программы, |
|
publicclassTetrisFrame |
Окно программы |
|
publicTetrisFrame() |
Конструктор классаTetrisFrame |
|
privatevoid tetrisGamePanel1KeyPressed (java.awt.event.KeyEventevt) |
Обработка нажатия клавиш управления |
|
PrivatevoidmenuNewGame1ActionPerformed (java.awt.event.ActionEventevt) |
Обрабка выбора пункта меню «StartNewGame» |
|
privatevoid menuPauseGame1ActionPerformed (java.awt.event.ActionEventevt) |
Обрабка выбора пункта меню «StopGame» |
|
privatevoid menuFileExit1ActionPerformed (java.awt.event.ActionEventevt) |
Обрабка выбора пункта меню «Exit» |
|
publicvoidcontinueButtonPressed (ActionEventevt) |
Обрабка нажатия кнопки «Resume» |
|
publicvoidpauseButtonPressed (ActionEventevt) |
Обробка нажатия кнопки «Pause» |
|
publicclassPlaySound |
Проигрование музыки |
|
publicPlaySound(String s) |
Конструктор класу PlaySound |
|
protectedvoidplay(Stringfile) |
Проигрование музыки |
Для управления,контструирования,и покраски и их разных типов фигурок тетрамино напишем следующий класс publicclassFigure ,будем использовать следующие функции которые представлены в таблице -3и 4
Таблица — 3 шаблоны фигур
Поле |
Описание поля |
|
finalstaticbyte[][][] PATTERN |
Шаблон фигур |
|
finalstaticColor[] COLORS |
Шаблон цветных фигур |
|
privateint[][] pat |
Шаблон фигур |
|
privateint x |
Координата х |
|
privateint y |
Координата у |
|
privateintrotation |
Угол |
|
privatestaticintnextType |
Следующий тип фигуры |
|
privatestaticintnextRot |
Следующий угол |
Таблица 4.конструктор фигур
Метод |
Описание метода |
|
publicFigure() |
Конструктор класу Figure |
|
publicintgetX() |
Получить х |
|
publicintgetY() |
Получить у |
|
publicintgetHeight() |
Получить высоту |
|
publicintgetWidth() |
Получить ширину |
|
publicintgetCell(int i, int j) |
Получить содержимое фигиры |
|
publicvoiddraw(Graphics g) |
Рисовать фигуру |
|
publicvoiddrawNext(Graphics g, intpx, intpy) |
Рисовать следующию фигиру |
|
publicvoidrotate() |
Повернуть фигуру |
|
publicbooleancanDown |
Можно двигать фигуру вниз? |
|
publicvoidmoveDown() |
Двигать фигуру вниз |
|
publicbooleancanLeft(Glassstakan) |
Можно двигать фигурувлево? |
|
publicbooleancanRight(Glassstakan) |
Можно двигать фигуру вправо? |
|
publicbooleancanRotate(Glassstakan) |
Можно повернуть фигуру ? |
|
publicvoidmoveLeft() |
Двигать фигуру влево |
|
publicvoidmoveRight() |
Двигать фигуру вправо |
Таблица5.создание publicclassGlass — клас стакан
Поле |
Описание поля |
|
privateint[] x |
Координата х стакана |
|
privateint[] y |
Координата у стакана |
|
privateint[][] cells |
Содержание стакана |
Таблица 6.
Метод |
Описание метода |
|
publicGlass() |
Конструктор классаGlass |
|
publicvoidclearGlass() |
Очистка стакана |
|
publicintgetHeight() |
Получить высоту стакана |
|
publicintgetWidth() |
Получить ширину стакана |
|
publicintgetCell(int i, int j) |
Получить содержимое стакана |
|
publicvoiddraw(Graphics g) |
Рисование стакана |
|
publicvoiddrawCell(Graphics g, int i, int j) |
Рисование ячейки стакана |
|
publicintacceptFigure(Figure f) |
Принятие стаканом фигуры,упала |
|
privateint[] y |
Координата у стакана |
|
privateint[][] cells |
Содержание стакана |
|
privateintclearFullLines() |
Очистка полностью заполненых линий |
Для написания панели кнопок будем созвать —publicclassButtonPanel —
Таблица7 -панель кнопок
Метод |
Описание метода |
|
publicButtonPanel(TetrisFrameframe) |
Конструктор классаButtonPanel |
|
privatevoid jButton1ActionPerformed (java.awt.event.ActionEventevt) |
Обробка нажатия кнопки «Resume» |
|
privatevoid jButton2ActionPerformed (java.awt.event.ActionEventevt) |
Обробка нажатия кнопки «Pause» |
Таблица 8.
Поле |
Описание поля |
|
privateGlassstakan |
Стакан тетриса |
|
privateFigurefig |
Текущаяфигура |
|
privateintscore |
Счет игры |
|
privateintgameState |
Состояние игры |
|
privateint[] DELAY |
Пауза для падения по уровням |
|
privateintlevel |
Уровеньигры |
Таблица 9.
Метод |
Описание метода |
|
publicTetrisGamePanel() |
Конструктор классаTetrisGamePanel |
|
publicvoidpaintComponent(Graphics g) |
Рисование стакана ,фигуры,счета и уровня игры |
|
publicintgetScore() |
Текучий счет игры |
|
publicvoidstartNewGame() |
Начать новую игру |
|
publicvoidpauseGame() |
Приостановка игры |
|
publicvoidresumeGame() |
Продолжение игры после паузы |
|
publicvoidstopGame() |
Остановить игру |
|
publicintgetState() |
Получить состояние игры |
|
publicvoidfigureMoveRight() |
Двигать фигуру вправо |
|
publicvoidfigureMoveLeft() |
Двигать фигурувлево |
|
publicvoidfigureMoveDown() |
Двигать фигуру вниз |
|
publicvoidfigureRotate() |
Перевернуть фигуру |
|
publicvoidgamePauseResume() |
Изменить состояние игры payse на play и наоборот |
|
publicvoidactionPerformed(ActionEvent e) |
Оброботка действия,события таймера |
3.1 Описание интерфейса программы
Запустив игру фигуры начинают спускаться. Для управления фигурой нужно пользоваться клавишами навигации. Для того, чтобы приостановить игру нужно нажать кнопку «Pause» или клавишу F3. Для продолжения игры необходимо нажать кнопку «Resume» или клавишу F3. Для начала новой игры нужно выбрать пункт меню «Start New Game» или нажать клавишу F2, а для того, чтобы остановить игру совсем — выбрать пункт меню «Stop Game». Для выхода из игры нужно выбрать пункт меню «Exit» или просто закрыть программу.
Инструкция по установке
На компьютере должна быть установлена JRE (виртуальная машина Java)
Монитор должен поддерживать режим 1024х768х24bit
45kb на жестком диске
Чтобы выполнить проект из командной строки, перейдите в каталог, где находится файл и наберите следующее: Java-jar «TetrisGame.jar» или запустите двойным щелчком мыши.
Заключение
В данной курсовой работе был разработан программный продукт — логическая игра Тетрис.
Была обоснована необходимость создания программы, проведены все необходимые работы по проектированию архитектуры игры, проанализированы требования к ней, приводится описание реализации, кодирование, тестирование программы.
При написании программы был использован объектно-ориентированный язык Java.
В результате выполнения курсовой работы была написана игра «Тетрис».
В первой части работы рассмотрены основные моменты, связанные с языком Java: история возникновения и развития, основные возможности языка, преимущества и недостатки.
Вторая часть включает в себя историю и интересные факты об игре Тетрис.
Третья часть курсовой включает в себя практическую часть, в которой был разработан исходный код для программы «Тетрис», также было выполнено тестирование данной программы.
Для разработки приложения использовалась среда интегрированной разработки Eclipse.
Список использованных источников
1. Н.А. Вязовик. Программирование на Java. Курс лекций, Интернет-университет информационных технологий, 2003 г., 592 стр.
2. Герберт Шилдт, Джеймс Холмс, Искусство программирования на Java, 2005 г., 336 стр.
3. http://ru.wikipedia.org/wiki/Тетрис
4. Хабибуллин И.Ш. Самоучитель Java 2. СПб.: БХВ-Петербург, 2007. — 720 с.: Ил.
5. Эккель Б. Философия Java. Библиотека программиста. СПб.: Питер, 2001.
6. Беркунський Е.Ю. Объектно-ориентированное программ-мирование на языке Java: Методические указания для студентов направления «Компьютерные науки». — М.: НУК, 2006. — 52 с.
Приложение
код программы
package Tetr;
import java.awt.event.;
interface GamePanel extends ActionListener{
final static int PLAY = 1;
final static int STOP = 2;
final static int PAUSE =3;
public void startNewGame();
public void pauseGame();
public void resumeGame();
public void stopGame();
public int getScore();
public int getState();
public void figureMoveRight();
public void figureMoveLeft();
public void figureMoveDown();
public void figureRotate();
public void gamePauseResume();
Файл Tetris.java
package Tetr;
public class Tetris {
public static void main(String[] args) throws InterruptedException {
TetrisFrame.setDefaultLookAndFeelDecorated(true);
TetrisFrame frame = new TetrisFrame();
frame.setVisible(true);
String s = «D:\\FirstProb2\\src\\Tetr\\tetris.mid»;
if (args.length>0)
s = args[0];
new PlaySound(s);
Файл ButtonPanel.java
package Tetr;
public class ButtonPanel extends javax.swing.JPanel {
private TetrisFrame frame;
public ButtonPanel(TetrisFrame frame) {
this.frame = frame;
initComponents();
// <editor-fold defaultstate=»collapsed» desc=»Generated Code»>//GEN-BEGIN:initComponents
private void initComponents() {
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
setFocusable(false);
jButton1.setText(«Resume»);
jButton1.setFocusable(false);
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
add(jButton1);
jButton2.setText(«Pause»);
jButton2.setFocusable(false);
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
add(jButton2);
}// </editor-fold>//GEN-END:initComponents
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
frame.continueButtonPressed(evt);
}//GEN-LAST:event_jButton1ActionPerformed
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
frame.pauseButtonPressed(evt);
}//GEN-LAST:event_jButton2ActionPerformed
// Variables declaration — do not modify//GEN-BEGIN:variables
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
// End of variables declaration//GEN-END:variables
Файл Figure.java
package Tetr;
import java.util.Random;
import java.awt.;
public class Figure {
final static byte[][][] PATTERN = {
{{0,0,0,0}, // «пустой» шаблон — просто для удобства
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
{1}, //
{1},
{1},
{{2,0},
{2,0},
{2,2}
{{0,3},
{0,3},
{3,3}
{{4,0},
{4,4},
{4,0}
{{5,0},
{5,5},
{0,5}
{{0,6},
{6,6},
{6,0}
{{7,7},
{7,7}
final static Color[] COLORS = {
Color.GRAY,
Color.BLUE,
Color.CYAN,
Color.GREEN,
Color.MAGENTA,
Color.RED,
Color.PINK,
Color.YELLOW
private int type;
private int[][] pat;
private int x,y,rotation;
private static Random r = new Random();
private static int nextType = 0;
private static int nextRot = -1;
public Figure() {
if (nextType==0) {
type = r.nextInt(PATTERN.length-1)+1;
rotation = r.nextInt(4);
} else {
type = nextType;
rotation = nextRot;
nextType = r.nextInt(PATTERN.length-1)+1;
y = 0; x = 4;
nextRot = r.nextInt(4);
pat = new int[PATTERN[type].length]
[PATTERN[type][0].length];
for (int i=0; i<pat.length; i++)
for (int j=0; j<pat[i].length; j++) {
pat[i][j] = PATTERN[type][i][j];
for (int i=0; i<rotation; i++) rotate();
public int getX() {
return x;
public int getY() {
return y;
public int getHeight() {
return pat.length;
public int getWidth() {
return pat[0].length;
public int getCell(int i, int j) {
if (i<0 || i>=pat.length || j<0 || j>=pat[0].length) return 0;
return pat[i][j];
public void draw(Graphics g) {
for (int i=0; i<pat.length; i++) {
for (int j=0; j<pat[i].length; j++)
if (pat[i][j]!=0){
g.setColor(COLORS[pat[i][j]]);
g.fillRect((x+j)*30+11,(i+y)*30+1,28,28);
drawNext(g,350,50);
public void drawNext(Graphics g, int px, int py) {
int[][] p = new int[PATTERN[nextType].length][PATTERN[nextType][0].length];
for (int i=0; i<p.length; i++) {
for (int j=0; j<p[0].length; j++) {
p[i][j] = PATTERN[nextType][i][j];
for (int kr=0; kr<nextRot; kr++){
int[][] p2 = new int[p[0].length][p.length];
for (int i=0; i<p.length; i++) {
for (int j=0; j<p[0].length; j++) {
p2[j][i] = p[i][j];
p = new int[p2.length][p2[0].length];
for (int i=0; i<p.length; i++) for (int j=0; j<p[0].length; j++) {
p[i][j] = p2[p.length-i-1][j];
for (int i=0; i<4; i++) for (int j=0; j<4; j++) {
g.setColor(COLORS[0]);
g.fillRect(j*30+px, i*30+py, 28,28);
for (int i=0; i<p.length; i++) for(int j=0; j<p[0].length; j++) {
g.setColor(COLORS[p[i][j]]);
g.fillRect(j*30+px, i*30+py, 28,28);
public void rotate() {
int[][] newPat = new int[pat[0].length][pat.length];
for (int i=0; i<pat.length; i++) for (int j=0; j<pat[0].length; j++) {
newPat[j][i] = pat[i][j];
pat = new int[newPat.length][newPat[0].length];
for (int i=0; i<pat.length; i++) for (int j=0; j<pat[0].length; j++) {
pat[i][j] = newPat[pat.length-i-1][j];
public boolean canDown(Glass stakan) {
int[][] a = new int[21][10];
for (int i = 0; i<stakan.getHeight(); i++) {
for (int j = 0; j<stakan.getWidth(); j++) {
a[i][j] = stakan.getCell(i,j);
for (int i=0; i<pat.length; i++) {
for (int j=0; j<pat[i].length; j++) {
int xx = x+j, yy = y+i+1;
if (pat[i][j]>0 && a[yy][xx]>0) {
return false;
return true;
public void moveDown() {
y++;
public boolean canLeft(Glass stakan) {
if (x==0) return false;
int [][] s = new int[pat.length][pat[0].length];
for (int i=0; i<s.length; i++) for (int j=0; j<s[0].length; j++) {
s[i][j] = stakan.getCell(y+i,j+x-1);
for (int i=0; i<s.length; i++) for (int j=0; j<s[0].length; j++) {
if (s[i][j]*pat[i][j]>0) {
return false;
return true;
public boolean canRight(Glass stakan) {
if (x==stakan.getWidth()-pat[0].length) return false;
int [][] s = new int[pat.length][pat[0].length];
for (int i=0; i<s.length; i++) for (int j=0; j<s[0].length; j++) {
s[i][j] = stakan.getCell(y+i,j+x+1);
for (int i=0; i<s.length; i++) for (int j=0; j<s[0].length; j++) {
if (s[i][j]*pat[i][j]>0) {
return false;
return true;
public boolean canRotate(Glass stakan) {
if (x+pat.length>stakan.getWidth()) return false;
int[][] tmpPat = new int[pat[0].length][pat.length];
for (int i=0; i<pat.length; i++) for (int j=0; j<pat[0].length; j++) {
tmpPat[j][i] = pat[i][j];
int[][] tPat = new int[tmpPat.length][tmpPat[0].length];
for (int i=0; i<tPat.length; i++) for (int j=0; j<tPat[0].length; j++) {
tPat[i][j] = tmpPat[tPat.length-i-1][j];
int [][] s = new int[tPat.length][tPat[0].length];
for (int i=0; i<s.length; i++) for (int j=0; j<s[0].length; j++) {
s[i][j] = stakan.getCell(y+i,j+x);
for (int i=0; i<s.length; i++) for (int j=0; j<s[0].length; j++) {
if (s[i][j]*tPat[i][j]>0) {
return false;
return true;
public void moveLeft() {
if (x>0) {
x—;
public void moveRight() {
if (x<10-pat[0].length) {
x++;
Файл Glass.java
package Tetr;
import java.awt.;
public class Glass {
private int[] x = {0, 10, 10, 310, 310, 320, 320, 0};
private int[] y = {0, 0, 600, 600, 0, 0, 610, 610};
private int[][] cells = new int[21][10];
public Glass() {
clearGlass();
public void clearGlass() {
for (int i = 0; i<cells.length; i++) {
for (int j = 0; j<cells[i].length; j++) {
cells[i][j] = (i==cells.length-1) ? 10 : 0;
public int getHeight() {
return cells.length;
public int getWidth() {
return cells[0].length;
public int getCell(int i, int j) {
return cells[i][j];
public void draw(Graphics g) {
g.setColor(Color.GRAY);
g.fillRect(10,0,300,600);
g.setColor(Color.BLUE);
g.fillPolygon(x,y,x.length);
for (int i = 0; i<cells.length-1; i++) {
for (int j = 0; j<cells[i].length; j++) {
drawCell(g,i,j);
public void drawCell(Graphics g, int i, int j) {
g.setColor(Figure.COLORS[cells[i][j]]);
g.fillRect(j*30+11,i*30+1,28,28);
public int acceptFigure(Figure f){
for (int i=0; i<f.getHeight(); i++) {
for (int j=0; j<f.getWidth(); j++) {
int xx = f.getX()+j, yy = f.getY()+i;
if (f.getCell(i,j)!=0) { // клетка не пуста
cells[yy][xx] = f.getCell(i,j);
int lines = clearFullLines();
if (lines>0) return lines;
if (f.getY()==0) return -1;
return 0;
private int clearFullLines() {
int linesCount = 0;
lineLoop: for (int i=1; i<20; i++){
for (int j=0; j<10; j++) {
if (cells[i][j]==0) {
continue lineLoop;
linesCount++;
for (int j=i; j>=1; j—) {
cells[j]=cells[j-1];
cells[0] = new int[10];
for (int j=0; j<10; j++) {
cells[0][j]=0;
return linesCount;
Файл PlaySound.java
package Tetr;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.sound.midi.;
import java.io.;
public class PlaySound implements ActionListener{
public PlaySound(String s){
play(s);
protected void play(String file) {
try{
File f = new File(file);
Sequencer sequencer = MidiSystem.getSequencer();
if (sequencer == null) {
System.err.println(«Sequenser not supported»);
sequencer.open();
Sequence seq = MidiSystem.getSequence(f);
sequencer.setSequence(seq);
sequencer.start();
sequencer.setLoopCount(1000);
}catch(Exception e){
System.err.println(e);
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException(«Not supported yet.»);
Файл TetrisFrame.java
package Tetr;
import Tetr.TetrisGamePanel;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
public class TetrisFrame extends javax.swing.JFrame {
/ Creates new form TetrisFrame /
public TetrisFrame() {
initComponents();
tetrisGamePanel1.grabFocus();
// <editor-fold defaultstate=»collapsed» desc=»Generated Code»>//GEN-BEGIN:initComponents
private void initComponents() {
buttonPanel1 = buttonPanel1 = new ButtonPanel(this);
menuBar = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
menuNewGame = new javax.swing.JMenuItem();
menuPauseGame = new javax.swing.JMenuItem();
jSeparator1 = new javax.swing.JSeparator();
menuFileExit = new javax.swing.JMenuItem();
tetrisGamePanel1 = new Tetr.TetrisGamePanel();
menuBar1 = new javax.swing.JMenuBar();
jMenu2 = new javax.swing.JMenu();
menuNewGame1 = new javax.swing.JMenuItem();
menuPauseGame1 = new javax.swing.JMenuItem();
jSeparator2 = new javax.swing.JSeparator();
menuFileExit1 = new javax.swing.JMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setFocusable(false);
jMenu1.setText(«File»);
menuNewGame.setText(«Item»);
jMenu1.add(menuNewGame);
menuPauseGame.setText(«Item»);
jMenu1.add(menuPauseGame);
jMenu1.add(jSeparator1);
menuFileExit.setText(«Item»);
jMenu1.add(menuFileExit);
menuBar.add(jMenu1);
tetrisGamePanel1.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent evt) {
tetrisGamePanel1KeyPressed(evt);
menuBar1.setFocusable(false);
jMenu2.setText(«File»);
jMenu2.setFocusable(false);
menuNewGame1.setText(«Start New Game»);
menuNewGame1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
menuNewGame1ActionPerformed(evt);
jMenu2.add(menuNewGame1);
menuPauseGame1.setText(«Stop Game»);
menuPauseGame1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
menuPauseGame1ActionPerformed(evt);
jMenu2.add(menuPauseGame1);
jMenu2.add(jSeparator2);
menuFileExit1.setText(«Exit»);
menuFileExit1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
menuFileExit1ActionPerformed(evt);
jMenu2.add(menuFileExit1);
menuBar1.add(jMenu2);
setJMenuBar(menuBar1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(153, 153, 153)
.addComponent(buttonPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(tetrisGamePanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 485, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(buttonPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(tetrisGamePanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 612, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
pack();
}// </editor-fold>//GEN-END:initComponents
private void tetrisGamePanel1KeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tetrisGamePanel1KeyPressed
TetrisGamePanel p = (TetrisGamePanel)tetrisGamePanel1;
switch (evt.getKeyCode()) {
case KeyEvent.VK_LEFT:
p.figureMoveLeft();
break;
case KeyEvent.VK_RIGHT:
p.figureMoveRight();
break;
case KeyEvent.VK_UP:
p.figureRotate();
break;
case KeyEvent.VK_DOWN:
p.figureMoveDown();
break;
case KeyEvent.VK_F2:
p.startNewGame();
break;
case KeyEvent.VK_F3:
p.gamePauseResume();
break;
default: return;
repaint();
}//GEN-LAST:event_tetrisGamePanel1KeyPressed
private void menuNewGame1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuNewGame1ActionPerformed
TetrisGamePanel p = (TetrisGamePanel)tetrisGamePanel1;
p.startNewGame();
}//GEN-LAST:event_menuNewGame1ActionPerformed
private void menuPauseGame1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuPauseGame1ActionPerformed
TetrisGamePanel p = (TetrisGamePanel)tetrisGamePanel1;
p.stopGame();
}//GEN-LAST:event_menuPauseGame1ActionPerformed
private void menuFileExit1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_menuFileExit1ActionPerformed
System.exit(0);
}//GEN-LAST:event_menuFileExit1ActionPerformed
public void continueButtonPressed(ActionEvent evt) {
TetrisGamePanel p = (TetrisGamePanel)tetrisGamePanel1;
p.resumeGame();
public void pauseButtonPressed(ActionEvent evt) {
TetrisGamePanel p = (TetrisGamePanel)tetrisGamePanel1;
p.pauseGame();
// Variables declaration — do not modify//GEN-BEGIN:variables
private Tetr.ButtonPanel buttonPanel1;
private javax.swing.JMenu jMenu1;
private javax.swing.JMenu jMenu2;
private javax.swing.JSeparator jSeparator1;
private javax.swing.JSeparator jSeparator2;
private javax.swing.JMenuBar menuBar;
private javax.swing.JMenuBar menuBar1;
private javax.swing.JMenuItem menuFileExit;
private javax.swing.JMenuItem menuFileExit1;
private javax.swing.JMenuItem menuNewGame;
private javax.swing.JMenuItem menuNewGame1;
private javax.swing.JMenuItem menuPauseGame;
private javax.swing.JMenuItem menuPauseGame1;
private Tetr.TetrisGamePanel tetrisGamePanel1;
Файл TetrisGamePanel.java
package Tetr;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TetrisGamePanel extends javax.swing.JPanel implements GamePanel,ActionListener {
private Glass stakan;
private Figure fig = null;
private int score = 0;
private int gameState;
private int[] DELAY = {500, 450, 400, 350, 300, 250, 200, 150, 100, 50};
private int level = 1;
Timer t = new javax.swing.Timer(DELAY[level], this);
public TetrisGamePanel() {
stakan = new Glass();
startNewGame();
t.start();
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
stakan.draw(g);
fig.draw(g);
g.setFont(new Font(«Times New Roman», Font.BOLD, 24));
g.setColor(Color.BLACK);
g.drawString(«Счет: » + score, 350, 250);
g.drawString(«Уровень: » + level, 350, 300);
public int getScore() {
return score;
public void startNewGame() {
score = 0;
level = 1;
fig = new Figure();
stakan = new Glass();
gameState = PLAY;
public void pauseGame() {
if (gameState == PLAY) {
gameState = PAUSE;
public void resumeGame() {
if (gameState == PAUSE) {
gameState = PLAY;
public void stopGame() {
gameState = STOP;
public int getState() {
return gameState;
public void figureMoveRight(){
if (fig.canRight(stakan)& gameState==PLAY)
fig.moveRight();
public void figureMoveLeft(){
if (fig.canLeft(stakan)& gameState==PLAY)
fig.moveLeft();
public void figureMoveDown(){
t.setDelay(DELAY[level]/20);
public void figureRotate(){
if (fig.canRotate(stakan)& gameState==PLAY)
fig.rotate();
public void gamePauseResume(){
if (gameState==PLAY) {
gameState = PAUSE;
else
if (gameState==PAUSE) {
gameState = PLAY;
public void actionPerformed(ActionEvent e) {
if (gameState != PLAY) {
return;
int bonus;
if (fig.canDown(stakan)) {
fig.moveDown();
} else {
if ((bonus = stakan.acceptFigure(fig)) < 0) {
stopGame();
if (bonus > 0) {
switch (bonus) {
case 4:
score += 20;
case 3:
score += 15;
case 2:
score += 10;
case 1:
score += 5;
int newLevel = score / 100 + 1;
if (newLevel > level && level < 9) {
level++;
if (gameState == PLAY) {
fig = new Figure();
t.setDelay(DELAY[level]);
repaint();
// <editor-fold defaultstate=»collapsed» desc=»Generated Code»>//GEN-BEGIN:initComponents
private void initComponents() {
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
}// </editor-fold>//GEN-END:initComponents
Размещено на