Курсовая работа: Java-гра "Тетріс"
Курсовая работа: Java-гра "Тетріс"
Анотація
Курсова
робота присвячена розробці логічної гри «Тетріс» у складі: набір об’єктних
моделей, програмний код. Проводяться усі необхідні роботи з проектування
архітектури гри, аналізуються вимоги до неї, приводиться опис реалізації,
кодування, тестування програми. При написанні гри використовується
об’єктно-орієнтованна мовоа Java.
Робота
викладена на 47 сторінках, містить 5 рисунків, 5 додатків.
Зміст
Вступ
1. Аналіз предметної області та
постановка задачі
1.1 Аналіз предметної області
1.2 Постановка задачі
2. Проект програми
2.1 Ієрархія об’єктів
2.2 Ієрархія спадкування
2.3 Діаграма станів гри
2.4 Алгоритмізація
2.5 Кодування і вибір
інструментальних засобів
2.6 Тестування
ВИСНОВОК
Література
Додатки
Додаток А Опис класів
Додаток Б Опис інтерфейса програми
Додаток В Інструкція з встановлення
Додаток Г Лістинг програми
Додаток Д Результат роботи програми
Вступ
В даній курсовій
роботі реалізується гра «Тетріс». Зміст гри полягає у тому, що випадкові
фігурки падають зверху в прямокутний стакан висотою 10 і шириною 20 кліток. У
польоті гравець може повертати фігурку і рухати її по горизонталі, але не
уповільнювати політ. Фігурка летить, поки не натикнеться на іншу фігурку або на
підлогу стакана. Якщо при цьому заповнився горизонтальний ряд з 10 кліток, він
пропадає і все, що вище за нього, опускається на 1 клітку. Темп гри поступово
збільшується.
При
реалізації програми буде використовуватись об’єктно-орієнтований підхід,
важливим наслідком чого є можливість формування такої структури програми, коли
додавання нових компонентів при її подальшому розвитку не буде впливати на
існуючи компоненти, або такий вплив буде зведено до мінімуму.
Для кодування гри
буде обрана мова Java, що сприяє написанню надійного програмного продукту.
1. Аналіз
предметної області та постановка задачі
1.1
Аналіз предметної області
Метою даної
курсової роботи є розробка гри „Тетріс”. Вона відноситься до логічних ігор, які
допомагають розвинути реакцію, тренують логіку. При тривалій роботі за
комп'ютером виникає бажання трохи відпочити. Для цієї мети не підходять ігри
типу стратегій, бо для них потрібно багато часу, а для 5-10 хвилинного
відпочинку цілком підійде саме «Тетріс». У стандартній поставці операційних
систем даної гри немає, тому виникла необхідність у її створенні.
До ігор такого
типу пред‘являються такі вимоги: використання простих засобів управління;
зручний графічний інтерфейс; поступове ускладнення гри при наборі певної
кількості очок. Під час виконання програма повинна виконуватися коректно і не
приводити до збоїв.
1.2 Постановка задачі
Зміст гри полягає у прагненні
щільно зайняти ігрове поле падаючими геометричними фігурами, змінюючи їх
орієнтацію у просторі, домагаючись відсутності пропусків в кожному рядку.
Фігури
не повинні виходити за кордони ігрового поля, вони мають переміщуватись та
перевертатись. Для надання більшої привабливості зовнішньому вигляду ігрового
поля при написанні гри потрібно використовувати яскраву графіку. Інтерфейс
програми, що розроблюється повинний бути зручний і зрозумілий користувачу.
Програма
повинна реагувати на натискання клавіш клавіатури, виводячи зображення на
екран.
При
реалізації програми було вирішено використовувати об'єктно-орієнтований підхід,
що дозволить уникнути проблем проектування, характерних для процедурного
підходу. Важливим наслідком цього є можливість формування такої структури
програми, коли додавання нових компонентів при її подальшому розвитку не буде
впливати на існуючі компоненти, або такий вплив буде зведено до мінімуму.
Відповідно до 1.1 і 1.2 розробимо наступний проект програми.
2. Проект
програми
2.1 Ієрархія
об’єктів
Аналізуючи
потоки вхідних і вихідних даних, розробляємо загальний інтерфейс програми,
уточнюємо вимоги до функцій, що виконуються програмою визначаємо їх структуру.
На
етапі ескізного проектування були виділені такі об’єкти, що входять до складу
програми: власне гра «Тетріс»; ігрове вікно, яке включає ігрове поле, поле
кнопок і ігрове меню. Графічно це відображається в ієрархії об’єктів на рисунку
1.
Рисунок
1 – Ієрархія об’єктів
2.2 Ієрархія
спадкування
З урахуванням
прийнятої методології і ієрархії класів нам необхідно ієрархію спадкування, яка
зображена на рисунку 2.
Рисунок
2 – Ієрархія спадкування
2.3 Діаграма
станів гри
Діаграма станів
гри зображена на рисунку 3.
Запуск
Вихід
Натиснута кнопка
«Pause»
Обраний пункт меню «Start New Game»
Обраний пункт меню «StopGame»
Натиснута кнопка «Resume»
Фігура досягла верху стакана
Рисунок 3 -
Діаграма станів
2.4
Алгоритмізація
Одною з
найважливіших функцій у даній роботі є очищення заповнених ліній. ЇЇ блок-схема
показана на рисунку 4.
Рисунок 4 –
Блок-схема методу private int clearFullLines()
2.5 Кодування і
вибір інструментальних засобів
Враховуючи
поставлену задачу, ієрархію класів, об’єктів, було зроблено висновок, що для
даної роботи найкраще підійде мова програмування Java,так як використовуючи її
маємо змогу використовувати величезний набір класів, які входять в стандартний
пакет Java. Завдяки чому, наша робота включатиме розробку взаємодії між
готовими класами. Також Java дозволяє досить легко створювати програми з
графічним інтерфейсом користувача. Програма була написана в середовищі NetBeans
6.0.
2.6 Тестування
Тестуючи
програму, бачимо, що в цілому програма працює вірно. Коли ми намагаємося рухати
фігуру клавішами управління – вона рухається. Натискаючи на кнопку «Pause»
бачимо, що програма призупиняється, а коли натискаємо «Resume» – продовжується.
Той самий ефект спостерігаємо при повторному натисканні клавіші F3. При виборі
пункту меню «Start New Game» – гра починається спочатку, а при виборі «Stop
Game» – гра зупиняється.
Висновок
У
даній курсовій роботі був розроблений програмний продукт – логічна гра Тетріс.
Була
обґрунтована необхідність створення програми, проведені усі необхідні роботи по
проектуванню архітектури гри, проаналізовані вимоги до неї, приводиться опис
реалізації, кодування, тестування програми.
При
написанні програми була використана об’єктно-орієнтована мова Java.
Література
1.
Хабибуллин
И.Ш. Самоучитель Java 2. СПб.: БХВ-Петербург, 2007. – 720 с.: ил.
2.
Эккель Б.
Философия Java. Библиотека программиста. СПб.: Питер, 2001
3.
Беркунський
Є.Ю. Об’єктно-орієнтоване програмування мовою Java: Методичні вказівки для
студентів напрямку “ Комп’ютерні науки”. – Миколаїв: НУК, 2006. – 52 с.
Додатки
В даному розділі
буде детально розглянуто кожен з класів даної роботи, його поля і методи
Додаток А Опис
класів
interface
GamePanel – інтерфейс гральної панелі
Поле |
Опис поля |
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() |
Змінити стан гри PAUSE на PLAY і навпаки |
public class
Tetris – основний клас
Метод |
Опис методу |
public static void main(String[] args) |
Запуск програми |
public class
TetrisFrame – вікно програми
Метод |
Опис методу |
public TetrisFrame() |
Конструктор класу TetrisFrame |
private void tetrisGamePanel1KeyPressed (java.awt.event.KeyEvent evt) |
Обробка натискання клавіш управління |
private void menuNewGame1ActionPerformed (java.awt.event.ActionEvent
evt) |
Обробка вибору пункту меню «Start New Game» |
private void menuPauseGame1ActionPerformed (java.awt.event.ActionEvent
evt) |
Обробка вибору пункту меню «Stop Game» |
private void menuFileExit1ActionPerformed (java.awt.event.ActionEvent
evt) |
Обробка вибору пункту меню «Exit» |
public void continueButtonPressed (ActionEvent evt) |
Обробка натискання кнопки «Resume» |
public void pauseButtonPressed
(ActionEvent evt)
|
Обробка натискання кнопки «Pause» |
public class
PlaySound – програвання музики
Метод |
Опис методу |
public PlaySound(String s) |
Конструктор класу PlaySound |
protected void play(String file) |
Програвання музики |
public class
Figure – клас фігури
Поле |
Опис поля |
final static byte[][][] PATTERN |
Шаблони фігур |
final static Color[] COLORS |
Шаблони кольорів фігур |
private int type |
Тип фігури |
private int[][] pat |
Шаблон фігури |
private int x |
Координата х |
private int y |
Координата у |
private int rotation |
Вугол |
private static int nextType |
Наступний тип фігури |
private static int nextRot |
Наступний вугол |
Метод |
Опис методу |
public Figure() |
Конструктор класу Figure |
public int getX() |
Одержати х |
public int getY() |
Одержати у |
public int getHeight() |
Одержати висоту |
public int getWidth() |
Одержати ширина |
public int getCell(int i, int j) |
Одержати вміст фігури |
public void draw(Graphics g) |
Малювати фігуру |
public void drawNext(Graphics g, int px, int py) |
Малювати наступну фігуру |
public void rotate() |
Повернути фігуру |
public boolean canDown |
Чи можна рухати фігуру вниз? |
public void moveDown() |
Рухати фігуру вниз |
public boolean canLeft(Glass stakan) |
Чи можна рухати фігуру вліво? |
public boolean canRight(Glass stakan) |
Чи можна рухати фігуру управо? |
public boolean canRotate(Glass stakan) |
Чи можна повертати фігуру? |
public void moveLeft() |
Рухати фігуру вліво |
public void moveRight() |
Рухати фігуру управо |
public class
Glass – клас стакан
Поле |
Опис поля |
private int[] x |
Координата х стакана |
private int[] y |
Координата у стакана |
private int[][] cells |
Вміст стакана |
Метод |
Опис методу |
public Glass() |
Конструктор класу Glass |
public void clearGlass() |
Очищення стакана |
public int getHeight() |
Одержати висоту стакана |
public int getWidth() |
Одержати ширину стакана |
public int getCell(int i, int j) |
Одержати вміст стакана |
public void draw(Graphics g) |
Малювання стакана |
public void drawCell(Graphics g, int i, int j) |
Малювання осередку стакана |
public int acceptFigure(Figure f) |
Прийняття стаканом фігури, що впала |
private int clearFullLines() |
Очищення повністю заповнених ліній |
public class
ButtonPanel – панель кнопок
Метод |
Опис методу |
public ButtonPanel(TetrisFrame frame) |
Конструктор класу ButtonPanel |
private void jButton1ActionPerformed (java.awt.event.ActionEvent evt) |
Обробка натискання кнопки «Resume» |
private void jButton2ActionPerformed (java.awt.event.ActionEvent evt) |
Обробка натискання кнопки «Pause» |
public class
TetrisGamePanel – ігрова панель
Поле |
Опис поля |
private Glass stakan |
Стакан тетріса |
private Figure fig |
Поточна фігура |
private int score |
Рахунок гри |
private int gameState |
Стан гри |
private int[] DELAY |
Паузи для падіння фігури по рівнях |
private int level |
Рівень гри |
Метод |
Опис методу |
public TetrisGamePanel() |
Конструктор класу TetrisGamePanel |
public void paintComponent(Graphics g) |
Малювання стакана, фігури, рахунка і рівня гри |
public int getScore() |
Поточний рахунок гри |
public void startNewGame() |
Почати нову гру |
public void pauseGame() |
Призупинення гри |
public void resumeGame() |
Продовження гри після паузи |
public void stopGame() |
Зупинити гру |
public int getState() |
Отримати стан гри |
public void figureMoveRight() |
Рухати фігуру вправо |
public void figureMoveLeft() |
Рухати фігуру вліво |
public void figureMoveDown() |
Рухати фігуру вниз |
public void figureRotate() |
Обертати фігуру |
public void gamePauseResume() |
Змінити стан гри PAUSE на PLAY і навпаки |
public void actionPerformed(ActionEvent e) |
Обробка дій, подій таймера |
Додаток Б Опис
інтерфейса програми
Запустивши гру
фігури починають спускатися. Для управління фігурою треба користуватись
клавішами навігації. Для того, щоб призупинити гру треба натиснути кнопку
«Pause» або клавішу F3. Для продовження гри треба натиснути кнопку «Resume» або
клавішу F3. Для початку нової гри треба вибрати пункт меню «Start New Game» або
натиснути клавішу F2, а для того, щоб зупинити гру зовсім – вибрати пункт меню
«Stop Game». Для виходу з гри треба вибрати пункт меню «Exit» або просто закрити
програму.
Додаток В
Інструкція з встановлення
1.На комп’ютері повинна бути
встановлена JRE 6.3(віртуальна машина Java)
2.Монітор повинен підтримувати
режим 1024х768х24bit
3.45kb на жорсткому диску
4.Щоб виконати проект з
командного рядка, перейдіть до каталогу, де знаходиться файл і наберіть
наступне: Java -jar "TetrisGame.jar", або запустіть програму подвійним
клацанням миші.
Додаток Г Лістинг
програми
Файл GamePanel.java
package Tetr;
import
java.awt.event.*;
/**
*
* @author
irdis_13
*/
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;
/**
*
* @author
irdis_13
*/
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;
/**
*
* @author irdis_13
*/
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.*;
/**
*
* @author
irdis_13
*/
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},
{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) j<0
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.*;
/**
*
* @author
irdis_13
*/
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.*;
/**
*
* @author
irdis_13
*/
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;
/**
*
* @author irdis_13
*/
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
/**
* @param args
the command line arguments
*/
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.*;
/**
*
* @author irdis_13
*/
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
}
Додаток Д
Результат роботи програми
Результат роботи
програми зображено на рисунку 5
Рисунок 5 –
Результат роботи програми
|