Розробка гри

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
Комп’ютерні науки
Кафедра:
Не вказано

Інформація про роботу

Рік:
2012
Тип роботи:
Курсова робота
Предмет:
Об’єктно-орієнтоване програмування

Частина тексту файла (без зображень, графіків і формул):

ЗАТВЕРДЖЕНО Наказ Міністерства освіти і науки, молоді та спорту України 29 березня 2012 року № 384 Форма № Н-6.01 Відокремлений структурний підрозділ Золочівський коледж Національного університету «Львівська політехніка» Циклова комісія природничо-математичних та комп’ютерних дисциплін КУРСОВА РОБОТА з дисципліни «Об’єктно орієнтоване програмування» на тему: «Розробка гри «Тетріс» засобами мови Java» Студента 3 курсу ОПС - 3 групи Напряму підготовки 6.050101 Комп’ютерні науки Спеціальності 5.05010101 «Обслуговування програмних систем і комплексів» Мандзія Романа Васильовича Керівник викладач Олійник Б.П. Національна шкала _____________________________________ Кількість балів: __________Оцінка: ECTS ______________ Члени комісії ________________ ______________________________ (підпис) (прізвище та ініціали) ________________ ______________________________ (підпис) (прізвище та ініціали) ________________ ______________________________ (підпис) (прізвище та ініціали) м. Золочів - 2017рік Відокремлений структурний підрозділ Золочівський коледж Національного університету «Львівська політехніка» Циклова комісія природничо-математичних та комп’ютерних дисциплін Графік виконання курсової роботи студента (ки) 3 курсу, спеціальності Обслуговування програмних систем і комплексів (прізвищеім.’япо батькові) з дисципліни Об’єктно-орієнтоване програмування в 2016-2017 н.р. № Етапи виконання курсової роботи Календарні терміни виконання Відмітки про виконання  1. Обрання теми курсової роботи, попередня постановка завдання 24.01.2017р. виконано  2. Підбір літератури та веб-джерел 07.02.2017р. виконано  3. Уточнення завдань проектування (вимоги до проекту) 21.02.2017р. виконано  4. Підготовка оглядової частини та 50% теоретичної роботи 28.03.2017р. виконано  5. Подання керівникові чернетки роботи 07.04.2017р. виконано  6. Уточнення назви, висновків, підготовка презентаційних матеріалів 27.04.2017р. виконано  7. Подання курсової роботи на рецензування 05.05.2017р. виконано  8. Захист курсової роботи 15.05.2017р. виконано   Відокремлений структурний підрозділ Золочівський коледж Національного університету «Львівська політехніка» Відділення ______________________________________________________________ Циклова комісія: Природничо-математичних та комп’ютерних наук Освітньо-кваліфікаційний рівень: молодший спеціаліст Напрям підготовки: 6.050101 Комп’ютерні науки Спеціальність: 5.05010101 Обслуговування програмних систем і комплексів ЗАТВЕРДЖУЮ Голова циклової комісії ____________________________ “____”______________20__ року З А В Д А Н Н Я НА КУРСОВУ РОБОТУ СТУДЕНТУ Мандзій Роман Васильович 1. Тема курсової роботи: «Розробка гри «Тетріс» засобами мови Java» керівник роботи: Олійник Богдан Петрович затверджені наказом Золочівського коледжу НУ «Львівська політехніка» від “23” лютого 2017 року № 24-1 2. Строк подання студентом роботи 7 травня 2017 року; 3. Зміст практичної частини курсової роботи 3.1. Завдання проекту; 3.2. Блок схема; 3.3. Вихідний код програми; 3.4. Опис коду програми. 4. Дата видачі завдання 24 січня 2017 року Студент ___________ Мандзій Р.В. (підпис ) Керівник курсової роботи ___________ Олійник Б.П. ( підпис ) Відокремлений структурний підрозділ Золочівський коледж Національного університету «Львівська політехніка» (найменування вищого навчального закладу) Рецензія на курсову роботу Студента _______________________________________________________________________ (прізвище, ім’я по батькові) Який (яка) навчається на ______ курсі, Спеціальність Курсова робота з дисципліни Тема: Реєстраційний №________________ Дата отримання «____»______________20__ р. Рецензент (вчене звання, прізвище, ім’я по батькові) Зміст рецензії ________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ Допущений (на) до захисту «___»_______________20__ р. ___________________________ (підпис рецензента) Курсова робота захищена «___»________________20__ р. з оцінкою ______________________________________________________________________ Підпис рецензента ______________________________________________________________________ ЗМІСТ ВСТУП 6 РОЗДІЛ 1. ТЕОРЕТИЧНІ ВІДОМОСТІ 7 1.1.Середовище програмування Java 7 1.2.Теоретичні відомості до проекту «Тетріс» 11 РОЗДІЛ 2. ПРАКТИЧНА РЕАЛІЗАЦІЯ 12 2.1.Завдання проекту 12 2.2.Блок-схема 14 2.3.Вихідний код програми 15 2.4.Опис коду 31 СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ 38 ДОДАТКИ 39 ВСТУП В даній курсовій роботі реалізується гра «Тетріс». Зміст гри полягає у тому, що випадкові фігурки падають зверху в прямокутний стакан висотою 10 і шириною 20 кліток. У польоті гравець може повертати фігурку і рухати її по горизонталі, але не уповільнювати політ. Фігурка летить, поки не натикнеться на іншу фігурку або на підлогу стакана. Якщо при цьому заповнився горизонтальний ряд з 10 кліток, він пропадає і все, що вище за нього, опускається на 1 клітку. Темп гри поступово збільшується. При реалізації програми буде використовуватись об’єктно-орієнтований підхід, важливим наслідком чого є можливість формування такої структури програми, коли додавання нових компонентів при її подальшому розвитку не буде впливати на існуючи компоненти, або такий вплив буде зведено до мінімуму. Для кодування гри буде обрана мова Java, що сприяє написанню надійного програмного продукту. РОЗДІЛ 1. ТЕОРЕТИЧНІ ВІДОМОСТІ Середовище програмування Java Мова програмування Java зародилася в 1991 р. в лабораторіях компанії Sun Microsystems. Розробку проекту започаткував Джеймс Ґослінґ, сам проект мав назву «Green» (Зелений). Створення першої робочої версії, яка мала назву «Oak» (дуб), зайняло 18 місяців. Оскільки виявилось, що ім'я Oak уже використовувалось іншою фірмою, то в результаті тривалих суперечок навколо назви нової мови з-поміж ряду запропонованих було вибрано назву Java, у 1995 р. мову було офіційно перейменовано. Головним мотивом створення Java була потреба в мові програмування, яка б не залежала від платформи (тобто від архітектури) і яку можна було б використовувати для створення програмного забезпечення, що вбудовується в різноманітні побутові електронні прилади, такі як мобільні засоби зв'язку, пристрої дистанційного керування тощо. Досить скоро майже всі найпопулярніші тогочасні веб-оглядачі отримали можливість запускати «безпечні» для системи Java-аплети всередині веб-сторінок. У грудні 1998 р. Sun Microsystems випустила Java 2 (спершу під назвою J2SE 1.2), де було реалізовано декілька конфігурацій для різних типів платформ. Наприклад, J2EE призначалася для створення корпоративних застосунків, а значно урізана J2ME для приладів з обмеженими ресурсами, таких як мобільні телефони. У 2006 році в маркетингових цілях версії J2 було перейменовано у Java EE, Java ME та Java SE відповідно[4]. 13 листопада 2006 року Sun випустили більшу частину Java як вільне та відкрите програмне забезпечення згідно з умовами GNU General Public License (GPL). 8 травня 2007 корпорація закінчила процес, в результаті якого всі початкові коди Java були випущенні під GPL, за винятком невеликої частини коду, на який Sun не мала авторського права. Період становлення Java збігся у часі з розквітом міжнародної інформаційної служби World Wide Web. Ця обставина відіграла вирішальну роль у майбутньому Java, оскільки Web теж вимагала платформо-незалежних програм. Як наслідок, були зміщені акценти в розробці Sun з побутової електроніки на програмування для Інтернет[2].  Рисунок 1.2.1 Головне вікно Java Під «незалежністю від архітектури» мається на увазі те, що програма, написана на мові Java, працюватиме на будь-якій підтримуваній апаратній чи системній платформі без змін у початковому коді та перекомпіляції. Цього можна досягти, компілюючи початковий Java код у байт-код, який є спрощеними машинними командами. Потім програму можна виконати на будь-якій платформі, що має встановлену віртуальну машину Java, яка інтерпретує байткод у код, пристосований до специфіки конкретної операційної системи і процесора. Зараз віртуальні машини Java існують для більшості процесорів і операційних систем. Стандартні бібліотеки забезпечують загальний спосіб доступу до таких платформозалежних особливостей, як обробка графіки, багатопотоковість та роботу з мережами. У деяких версіях задля збільшення продуктивності JVM байт-код можна компілювати у машинний код до або під час виконання програми[1]. Основна перевага використання байт-коду — це портативність. Тим не менш, додаткові витрати на інтерпретацію означають, що інтерпретовані програми будуть майже завжди працювати повільніше, ніж скомпільовані у машинний код, і саме тому Java одержала репутацію «повільної» мови. Проте, цей розрив суттєво скоротився після введення декількох методів оптимізації у сучасних реалізаціях JVM. Одним із таких методів є just-in-time компіляція (JIT, що перетворює байт-код Java у машинний під час першого запуску програми, а потім кешує його. У результаті така програма запускається і виконується швидше, ніж простий інтерпретований код, але ціною додаткових витрат на компіляцію під час виконання. Складніші віртуальні машини також використовують динамічну рекомпіляцію, яка полягає в тому, що віртуальна машина аналізує поведінку запущеної програми й вибірково рекомпілює та оптимізує певні її частини. З використанням динамічної рекомпіляції можна досягти більшого рівня оптимізації, ніж за статичної компіляції, оскільки динамічний компілятор може робити оптимізації на базі знань про довкілля періоду виконання та про завантажені класи. До того ж він може виявляти так звані гарячі точки (англ. hot spots) — частини програми, найчастіше внутрішні цикли, які займають найбільше часу при виконанні. JIT-компіляція та динамічна рекомпіляція збільшує швидкість Java-програм, не втрачаючи при цьому портативності[3].  Рисунок 1.2.2 Робота з конструктором Java Існує ще одна технологія оптимізації байткоду, широко відома як статична компіляція, або компіляція ahead-of-time (AOT). Цей метод передбачає, як і традиційні компілятори, безпосередню компіляцію у машинний код. Це забезпечує хороші показники в порівнянні з інтерпретацією, але за рахунок втрати переносності: скомпільовану таким способом програму можна запустити тільки на одній, цільовій платформі. Швидкість офіційної віртуальної машини Java значно покращилася з моменту випуску ранніх версій, до того ж, деякі випробування показали, що продуктивність JIT-компіляторів у порівнянні зі звичайними компіляторами у машинний код майже однакова. Проте ефективність компіляторів не завжди свідчить про швидкість виконання скомпільованого коду, тільки ретельне тестування може виявити справжню ефективність у даній системі. 1.2 Теоретичні відомості до проекту «Тетріс» Курсова робота присвячена розробці логічної гри «Тетріс» у складі: набір об’єктних моделей, програмний код. Проводяться усі необхідні роботи з проектування архітектури гри, аналізуються вимоги до неї, приводиться опис реалізації, кодування, тестування програми. При написанні гри використовується об’єктно-орієнтованна мова Java. До ігор такого типу пред‘являються такі вимоги: використання простих засобів управління; зручний графічний інтерфейс; поступове ускладнення гри при наборі певної кількості очок. Під час виконання програма повинна виконуватися коректно і не приводити до збоїв. 2. ПРАКТИЧНА РЕАЛІЗАЦІЯ 2.1.Завдання проекту Зміст гри полягає у прагненні щільно зайняти ігрове поле падаючими геометричними фігурами, змінюючи їх орієнтацію у просторі, домагаючись відсутності пропусків в кожному рядку. Фігури не повинні виходити за кордони ігрового поля, вони мають переміщуватись та перевертатись. Для надання більшої привабливості зовнішньому вигляду ігрового поля при написанні гри потрібно використовувати яскраву графіку. Інтерфейс програми, що розроблюється повинний бути зручний і зрозумілий користувачу. Програма повинна реагувати на натискання клавіш клавіатури, виводячи зображення на екран. При реалізації програми було вирішено використовувати об'єктно-орієнтований підхід, що дозволить уникнути проблем проектування, характерних для процедурного підходу. Важливим наслідком цього є можливість формування такої структури програми, коли додавання нових компонентів при її подальшому розвитку не буде впливати на існуючі компоненти, або такий вплив буде зведено до мінімуму. У кінцевому результаті додаток має виглядати так (Рис. 2.1.1.):  Рисунок 2.1.1. Кінцевий вигляд додатку 2.2.Блок-схема  Рисунок 2.2.1. Блок-схема програми 2.3.Вихідний код програми Код файлу 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) { 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.*; /** * * @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){
Антиботан аватар за замовчуванням

03.11.2017 16:11-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!