Реализация игры pong на языке Java с помощью технологии Socket

Сетевые возможности языков программирования. Преимущества использования Java-апплетов. Классы, входящие в состав библиотеки java.awt. Создание пользовательского интерфейса. Сокетное соединение с сервером. Графика в Java. Значения составляющих цвета.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 10.11.2014
Размер файла 508,1 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Министерство обрaзовaния и нaуки Российской Федерации

Федерaльное госудaрственное бюджетное обрaзовaтельное учреждение
высшего профессионального обрaзовaния

«Оренбургский государственный педагогический университет»

Физико-мaтемaтический факультет

Кaфедрa информaтики и методики преподaвaния информaтики

Курсовая рaботa

Реализация игры pong на языке Java с помощью технологии Socket

Мищенко Сергей Геннадьевич

Форма обучения: дневная

Мищенко Сергей Геннадьевич

Научный руководитель:

Ст. преподaвaтель Гaрмaш М.И.

Оренбург 2013

Введение

Использование локального программирования на Java широко распространено. На основе технологий Java работают приставки, принтеры, веб-камеры, игры, навигационные системы для автомобилей, терминалы для проведения лотерей, медицинские устройства, автоматы для оплаты парковки и многое другое. Но со временем локальное программирование все чаще вытесняется сетевым программированием. Это на данный момент очень актуально, и я решил показать это на примере реализации сетевой игры пинг-понг.

Цель работы:

Написать игру пинг-понг на языке Java с используя технологию сокетов.

Для достижения этой цели были поставлены следующие задачи:

1. Рассмотреть сетевые возможности разных языков программирования;

2. Изучить работу с графикой на Java;

3. Рассмотреть возможности использования Java-апплетов;

4. Продемонстрировать работу с сокетами;

5. Реализовать программу.

Глава 1. Сетевые возможности разных языков программирования

1.1 Сетевое программирование в C#

Среда .NET предоставляет два пространства имен: System.Net и System.Net.Sockets для работы с сетью. Эти пространства имен содержат классы и методы, которые позволяют легко создавать программы, которые могут взаимодействовать через сеть.

Взаимодействие может осуществляться как с постоянным подключением по сети, так и без него. Также можно работать как с потокоориентированными данными так и с датаграммами. Наиболее распростанены протоколы TCP (использует потокоориентированное подключение) и UDP (приложения, ориентированные на датаграммы).

Класс System.Net.Sockets.Socket - это основной класс из пространства имен System.Net.Sockets. Экземпляр класса Socket имеет локальную и удаленную точку подключения, через которые он работает. Локальная точка подключения содержит информацию о подключении текущего состояния сокета.

Также существует несколько вспомогательных классов, таких как IPEndPoint, IPAdress, SocketException и др., которые используют при создании сетевых программ. Среда .NET поддерживает синхронное и асинхронное подключения между клиентом и сервером. Для этих двух типов взаимодействия по сети используются различные методы.

Синхронное подключение работает в блочном режиме, в котором метод ожидает завершения операции перед возвратом значения. А вот асинхронное подключение работает в неблочном режиме, при котором значение возвращается сразу, даже если операция взаимодействия не окончена.

Пространство имен System.Net предоставляет класс Dns, с помощью которого можно создавать и посылать запросы для получения информации о хосте сервера через Службу Доменных Имен Интернета (Internet Domain Name Service)

IPHostEntry класс

Этот класс является контейнером для информации о адресах хостов Интернета. Он не содержит гарантий потокобезопасности. Ниже описаны наиболее интересные члены этого класса.

IPEndPoint класс

Этот класс реализует абстрактных класс EndPoint. IPEndPoint класс представляет собой сетевую точку как IP адрес и номер порта.

1.2 Сетевое программирование в Python

Большинство необходимых вам функций обеспечивается тремя модулями: HTTPLIB, URLLIB и новым дополнением, XMLRPCLIB. В истинно Питоновском стиле каждый модуль надстроен над своим предшественником, обеспечивая таким образом прочную, хорошо спроектированную базу для ваших приложений.

HTTPLIB

HTTPLIB представляет собой простую обертку вокруг модуля socket. Из трех упомянутых библиотек, HTTPLIB обеспечивает наибольший контроль при обращении к web-сайту. Это дается за счет увеличения объема работы, необходимого для выполнения задачи. Протокол http не имеет текущего состояния ("stateless") и поэтому ничего не помнит о ваших предыдущих запросах. При соединении с Web-сайтом для каждого запроса нужно построить новый объект HTTPLIB. Эти запросы образуют диалог с Web-сервером, подражая Web-браузеру.

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

import httplib

host = 'www.oreillynet.com'

h = httplib.HTTP(host)

h.putrequest('GET', '/meerkat/?_fl=minimal')

h.putheader('Host', host)

h.putheader('User-agent', 'python-httplib')

h.endheaders()

Запрос GET сообщает серверу, какую страницу вы хотите получить. Заголовок Host сообщает ему имя запрашиваемого вами домена. Современные сервера, использующие HTTP 1.1, могут иметь несколько доменов по одному и тому же адресу. Если вы не говорите им, какой домен вам нужен, в качестве кода возврата вы получите код переадресации '302'. Заголовок User-agent сообщает серверу, к какому типу клиента вы относитесь, чтобы знать, что он может вам посылать, а что нет. Это вся информация, необходимая для обработки запроса Web-сервером. Далее запрашиваем ответ:

returncode, returnmsg, headers = h.getreply()

if returncode == 200: #OK

f = h.getfile()

print f.read()

В результате этого будет распечатана текущая страница Meerkat в минимальном виде. Заголовок отклика и содержимое возвращаются отдельно друг от друга, что помогает как в определении и устранении проблем, так и в разборе данных. Если хотим увидеть заголовки отклика, нужно использовать print headers.

HTTPLIB скрывает механику программирования сокетов, и использование им файлового объекта для буферизации позволяет применять привычный подход к манипуляции данными. HTTPLIB оснащен полезной возможностью отладки. Доступ к ней получаем, вызывая метод h.set_debuglevel(1) в любой момент после инициализации объекта (строка h = httplib.HTTP(host) в нашем примере). С уровнем отладки 1, модуль будет дублировать на экран запросы и результаты любых обращений к getreply().

URLLIB

URLLIB обеспечивает изощренный интерфейс к функциональности HTTPLIB. Лучше всего использовать его непосредственно для получения данных, а не для анализа Web-сайта. Здесь представлено то же взаимодействие, что и выше, но с использованием URLLIB:

import urllib

u=urllib.urlopen('http://www.oreillynet.com/meerkat/?_fl=minimal')

Одной строкой вы обратились к Meerkat, получили данные и поместили их во временный кэш. Для доступа к заголовку:

print u.headers

И для просмотра всего файла:

print u.read()

Но это еще не все. В дополнение к HTTP, URLLIB может таким же образом обращаться к FTP, Gopher и даже к локальным файлам. Модуль содержит также множество вспомогательных функций, включая те, что используются для разбора url, кодирования строк в url-безопасный формат и обеспечения индикации хода процесса во время пересылки большого объема данных.

1.3 Сетевое программирование в Perl

В Perl используется стандартный и одинаковый для всех СУБД механизм DBI. Perl изначально предлагал намного более богатый список модулей-расширений, работающий с самыми разными библиотеками, и то, что не так давно появилось в PHP, было в Perl уже годы назад. Perl даже можно использовать в более тесной интеграции с веб-сервером apache как модуль mod_perl, точно также как это делается для PHP через модуль apache mod_php.

AddHandler cgi-script .pl

Первый и простой скрипт из документации

Создайте файл test.pl следующего содержимого:

use strict;

use CGI; # or any other CGI:: form handler/decoder

use CGI::Ajax;

my $cgi = new CGI;

my $pjx = new CGI::Ajax( 'exported_func' => \&perl_func );

print $pjx->build_html( $cgi, \&Show_HTML);

sub perl_func {

my $input = shift;

# do something with $input

my $output = $input . " was the input!";

return( $output );

}

sub Show_HTML {

my $html = <<EOHTML;

<HTML>

<BODY>

Enter something:

<input type="text" name="val1" id="val1"

onkeyup="exported_func( ['val1'], ['resultdiv'] );">

<br>

<div id="resultdiv"></div>

</BODY>

</HTML>

EOHTML

return $html;

}

Итак:

use strict;

use CGI; # or any other CGI:: form handler/decoder

use CGI::Ajax;

Первая строка устанавливает "строгий" или "ограниченный" режим функционирования скрипта на Perl. В этом режиме должно чётко соблюдаться объявление локальных и глобальных переменных. В принципе, мы могли бы и не использовать такой режим, но часто его использование позволяет избежать путаницы, когда переменная с одним и тем же именем начинает использоваться глобально и в какой-либо функции. Вторая и третья строки подключают модули для работы CGI и CGI::Ajax. Модуль CGI берёт на себя всю работу по инцициализации веб-окружения и переданных веб-серверу параметров, позволяя также выдавать и редактировать служебные и http-заголовки, куки и параметры POST и GET запросов. Модуль CGI::Ajax ещё и добавляет при этом возможность работы с AJAX

my $cgi = new CGI;

my $pjx = new CGI::Ajax( 'exported_func' => \&perl_func );

print $pjx->build_html( $cgi, \&Show_HTML);

Здесь в первых 2-х строках мы создаём экземляры переменных классов CGI и CGI::Ajax. В момент создания происходит их инициализации и задание неких начальных параметров. Для CGI::Ajax мы видим, что создаётся привязка JavaScript функции exported_func к функции Perl'а perl_func. И наконец, в 3-й строке происходит вызов метода класса CGI::Ajax с именем build_html, который предназначен для вывода HTML содержимого веб-странички. В качестве параметров передаются переменная класса CGI и ссылка на имя функции, которая собственно и отрисовывает веб-страницу.

sub perl_func {

my $input = shift;

# do something with $input

my $output = $input . " was the input!";

return( $output );

}

Это та самая функция на языке Perl, которая будет вызвана при вводе какого-либо значения в поле ввода. Эта функция будет вызвана как отдельный CGI-скрипт. Т.е. данная функция совершенно независмый скрипт внутри основного скрипта. Сама же функция принимает аргумент и добавляет к нему строку "was the input!", после чего возвращает полученную в итоге строку

sub Show_HTML {

my $html = <<EOHTML;

<HTML>

<BODY>

Enter something:

<input type="text" name="val1" id="val1"

onkeyup="exported_func( ['val1'], ['resultdiv'] );">

<br>

<div id="resultdiv"></div>

</BODY>

</HTML>

EOHTML

return $html;

}

Это функция, которая отрисовывает содержимое веб-странички. Функция выводит всего два видимых элемента: поле ввода с именем val1 и что более важно с таким же id, а также область (div), с id="resultdiv", в которой и будут отображаться результаты ввода и работы функции perl_func.

onkeyup="exported_func( ['val1'], ['resultdiv'] );">

В этой строке, для поля ввода val1 назначается обработчик события, возникающего при отпускании нажатой клавиши на клавиатуре - onkeyup. Такое назначение является работой языка JavaScript, поддержка которого встроена во все современные браузеры, ведь сам HTML - это только язык разметки текста, не более. Далее, функции передаются два аргумента в квадратных скобках и одинарных кавычках. Первый аргумент - это id того элемента, событие которого будет обрабатывать функция, а второй - id элемента, в который будет помещён полученный в результате работы результат. Например мы вводим в поле ввода с клавиатуры цифру 1. Когда мы отпускаем кнопку с цифрой 1, случается событие onkeyup, которое подхватывается JavaScript, который далее передаёт управление функции exported_func. Данная функция, код которой автоматически генерируется CGI::Ajax, в свою очередь выполняет AJAX запрос, в результате которого выполняется функция perl_func и возвращённый ей результат, функция exported_func размещает в div с id resultdiv.

CGI::Ajax имеет своё мнение о выводимых заголовках, касаемо кодировки. Если вы выдали такие заголовки ранее, то не забудьте отключить их у CGI::Ajax, добавив после строки:

my $pjx = new CGI::Ajax( 'exported_func' => \&perl_func );

строку

$pjx->skip_header(1);

Если необходимо обрабатывать ввод в нескольких элементах ввода, вы можете видоизменить функцию exported_func, добавив аргументы:

onkeyup="exported_func(['val1','val2'], ['resultdiv1','resultdiv2']);"

А если необходимы разные функции-обработчики, добавляем их при создании экземпляра класса CGI::Ajax:

my $pjx = new CGI::Ajax( 'exported_func' =>\&perl_func,

'exported_func2' =>\&perl_func2);

1.4 Графика в Java

Графику в Java обслуживают классы Graphics и Graphics2D. Работа с графикой осуществляется в графическом контексте элементов, унаследованных от класса Component. Понимать это можно так: на элементах управления, например, JFrame, JPanel, JButton и других, есть возможность рисовать. Такие элементы обладают графическим контекстом, в этом контескте мы и рисуем. Всё, что нарисуем в контексте будет показано на элементе. Классы Graphics и Graphics2D нужны для работы с графическим контекстом. Мы должны получить экземпляр такого класса и, используя его методы, рисовать. Получить экземпляр контекста можно в методе paint:

public void paint(Graphics g);

этот метод наследуется из класса Component. Аргумент Graphics g создаётся системой, а мы берём его в готовом виде и используем для рисования. При создании элемента метод paint будет вызван автоматически.

Начнём изучать работу с графикой в Java с класса Graphics.

public void paint(Graphics g)

{

g.drawLine(20, 20, 360, 20);

Color oldColor = g.getColor();

Color newColor = new Color(0, 0, 255);

g.setColor(newColor);

g.drawLine(20, 30, 360, 30);

g.setColor(oldColor);

g.drawRect(20, 40, 340, 20);

newColor = new Color(0, 215, 255);

g.setColor(newColor);

g.fillRect(21, 41, 339, 19);

g.setColor(oldColor);

g.drawRoundRect(20, 70, 340, 30, 20, 15);

g.drawOval(20, 110, 150, 60);

g.drawOval(200, 110, 60, 60);

g.drawArc(280, 110, 80, 60, 0, 180);

int[] arrayX = {20, 100, 100, 250, 250, 20, 20, 50};

int[] arrayY = {180, 180, 200, 200, 220, 200, 200, 190};

Polygon poly=new Polygon(arrayX, arrayY, 8);

g.drawPolygon(poly);

Point aPoint = new Point(50, 190);

if(poly.contains(aPoint))

{

g.drawString("Yes", 50, 190);

}

newColor = new Color(0, 0, 255);

g.setColor(newColor);

Font font =new Font("Tahoma",Font. BOLD|Font.ITALIC, 40);

Font oldFont = g.getFont();

g.setFont(font);

g.drawString("SBP", 270, 220);

g.setFont(oldFont);

g.setColor(oldColor);

g.drawLine(20, 220, 20, 350);

g.drawLine(20, 350, 360, 350);

g.drawString("Y", 25, 230);

g.drawString("X", 350, 346);

int[] xArray = {20, 40, 60, 80, 100, 120, 130, 140, 280, 332};

int[] yArray={350,345, 340, 310, 290, 280, 275, 273, 271, 269};

int nPoint = 10;

g.setColor(newColor);

g.drawPolyline(xArray, yArray, nPoint);

g.setColor(oldColor);

g.drawString("y = f(x)", 180, 267);

Рис 1.1 Пример работы с графикой

Метод drawLine класса Graphics начертит прямую линию:

g.drawLine(20, 30, 360, 30);

здесь 20, 30 -- это координаты x, y начала линии, 360, 30 -- координаты конца линии.

Метод setColor класса Graphics сделает текущим новый цвет:

Запоминаем исходный цвет;

Color oldColor = g.getColor();

Создаём синий цвет;

Color newColor = new Color(0, 0, 255);

Устанавливаем синий цвет;

g.setColor(newColor);

Чертим линию синим цветом;

g.drawLine(20, 30, 360, 30);

Восстанавливаем исходный цвет;

g.setColor(oldColor);

Аргументы конструктора new Color(0, 0, 255) -- это красный, зелёный и синий цвета соответственно (rgb).

В примере задан чисто синий цвет, т.к. значения других составляющих равны нулю. Вот чисто красный цвет:

Color newColor = new Color(255, 0, 0);

А это чисто зеленый цвет:

Color newColor = new Color(0, 255, 0);

Значения составляющих цвета изменяются от 0 до 255.

Светло-синий цвет, который мы использовали для заливки прямоугольника:

newColor = new Color(0, 215, 255);

Задать цвет фона можно методом setBackground:

mainFrame.setBackground(Color.white);

Нарисовать треугольник можно методом drawRect класса Graphics:

g.drawRect(20, 40, 340, 20);

20, 40 -- это координаты верхнего левого угла прямоугольника;

340 -- длина;20 -- высота прямоугольника.

Что бы залить прямоугольник цветом понадобится методом fillRect класса Graphics:

newColor = new Color(0, 215, 255);

g.setColor(newColor);
g.fillRect(21, 41, 339, 19);

g.setColor(oldColor);

Что бы нарисовать прямоугольник с закругленными углами нужен метод drawRoundRect класса Graphics.

Сопряжение, т.е. закругление на углах, делается с помощью частей овала.

g.drawRoundRect(20, 70, 340, 30, 20, 15);

первые 4 аргумента как у обычного прямоугольника. Пятый аргумент-- 20 -- это ширина прямоугольника, в который вписана часть овала сопряжения. Шестой аргумент -- 15 -- это высота прямоугольника, в который вписана часть овала сопряжения.

Для того, чтобы нарисовать овал воспользуемся методом drawOval класса Graphics:

g.drawOval(20, 110, 150, 60);

Аргументы определяют прямоугольник, в который вписан овал.

Чтобы нарисовать окружность воспользуемся тем же методом, что и для овала.

Методом drawOval класса Graphics:

g.drawOval(200, 110, 60, 60);

Аргументы определяют прямоугольник, в который вписана окружность. Здесь рисуем овал, но длина и высота описанного прямоугольника равны, что и даёт окружность.

Для того, чтобы нарисовать дугу воспользуемся методом drawArc класса Graphics:

g.drawArc(280, 110, 80, 60, 0, 180);

Первые 4 аргумента как у обычного прямоугольника. Пятый аргумент-- 0 -- это угол, от которого отсчитывается угол самой дуги. 180 -- это угол дуги. Углы отсчитывают от горизонтальной оси: по часовой стрелке отрицательное направление, протв -- положительное. В примере 180 градусов (величина дуги) отсчитываем от горизонтальной линии.

Многоугольник можно нарисовать с помощью методом drawPolygon класса Graphics:

int[] arrayX = {20, 100, 100, 250, 250, 20, 20, 50};

int[] arrayY = {180, 180, 200, 200, 220, 200, 200, 190};

Polygon poly = new Polygon(arrayX, arrayY, 8);

g.drawPolygon(poly);

Здесь создаём объект класса Polygon. arrayX -- это х-координаты вершин многоугольника, arrayY -- это y-координаты вершин многоугольника, 8 -- число вершин многоугольника.

Для создания объекта «точка» используется класс Point:

Point aPoint = new Point(50, 190);

аргументы -- это x, y координаты.

Чтобы определить, принадлежит ли точка многоугольнику нужно:

Polygon poly = new Polygon(arrayX, arrayY, 8);

g.drawPolygon(poly);

Point aPoint = new Point(50, 190);

if(poly.contains(aPoint))

{ g.drawString("Yes", 50, 190); }

Чтобы вывести строку используем методом drawString класса Graphics:

g.drawString("Yes", 50, 190);

строка "Yes" будет выведена от точки с координатами 50, 190.

Для того, чтобы задать шрифт используем класс Font:

Font font = new Font("Tahoma", Font.BOLD|Font.ITALIC, 40);

где "Tahoma" -- название шрифта,

Font.BOLD|Font.ITALIC -- жирный шрифт с наклоном,

40 -- высота шрифта.

После задания шрифта мы делаем его текущим и выводим строку этим шрифтом:

g.setFont(font);

g.drawString("SBP", 270, 220);

Чтоб задать цвет текста создадим и установим в графический контекст новый цвет:

newColor = new Color(0, 0, 255);

g.setColor(newColor);

Здесь мы создали чисто синий цвет. А теперь выводим строку синим цветом:

g.drawString("SBP", 270, 220);

Для того, чтобы начертить график функции сначала начертим координатные оси:

Draw axes;

g.drawLine(20, 220, 20, 350);

g.drawLine(20, 350, 360, 350);

g.drawString("Y", 25, 230);

g.drawString("X", 350, 346);

А теперь построить график функции можно просто. Для этого используем метод drawPolyline класса Graphics:

Draw a curve;

int[] xArray = {20,40,60,80,100,120,130,140,280,332};

int[] yArray = {350,345,340,310,290,280,275,273,271,269};

int nPoint = 10;

g.setColor(newColor);

g.drawPolyline(xArray, yArray, nPoint);

g.setColor(oldColor);

g.drawString("y = f(x)", 180, 267);

График строим по точкам, xArray -- это x-координаты точек, yArray -- y-координаты точек графика, nPoint -- это число точек.

Наш график являет собой кривую намагничивания. Что бы график не был таким угловатым, можно взять больше точек, после чего график будет более плавным.

1.5. Аплеты в Java

Java-апплет -- прикладная программа, чаще всего написанная на языке программирования Java в форме байт-кода. Java-апплеты выполняются в веб-обозревателе с использованием виртуальной Java машины (JVM), или в Sun's AppletViewer, автономном средстве для испытания апплетов. Java-апплеты были внедрены в первой версии языка Java в 1995 году. Java-апплеты обычно пишутся на языке программирования Java, но могут быть написаны и на других языках, которые компилируются в байт?код Java, таких, как Jython.

Апплеты используются для предоставления интерактивных возможностей веб-приложений, которые не могут быть предоставлены HTML. Так как байт-код Java платформо-независим, то Java-апплеты могут выполняться с помощью плагинов браузерами многих платформ, включая Microsoft Windows, UNIX, Apple Mac OS и GNU/Linux. Такие программы с открытым исходным кодом, как applet2app[1], могут быть использованы для преобразования апплета в самостоятельные программы на Java или исполняемые файлы Linux и Windows.

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

Java-апплеты в большинстве браузеров выполняются в «песочнице», предотвращая их доступ к локальным данным. Код апплета загружается с веб-сервера, и браузер либо вставляет апплет в веб-страницу, либо открывает новое окно с собственным пользовательским интерфейсом апплета. Апплет может быть отображен на веб-странице путем использования устаревшего HTML элемента applet, или рекомендуемого элемента object. Этим определяется месторасположение и источник апплета.

Главный класс апплета расширяет класс java.applet.Applet или, если создаётся Swing апплет, javax.swing.JApplet. Класс должен переопределить методы создания пользовательского интерфейса внутри себя. (Applet является потомком Panel, который, в свою очередь, является потомком Container).

Преимущества использования Java-апплетов

- кроссплатформенность

- апплет может работать на «всех» установленных к этому времени версиях Java, а не только с последней версией; однако, если апплет требует последнюю версию JRE, то клиент будет вынужден ждать более длительной загрузки;

- апплет поддерживается большинством браузеров;

- он кэшируется в большинстве браузеров, а потому будет быстро загружаться при возвращении на веб-страницу; но апплет может сохраняться в кэше и создавать проблемы после выхода новых версий;

- он может иметь полный доступ к машине, на которой выполняется, если пользователь согласен на это;

- апплет может улучшить использование: после первого запуска апплета, когда JVM уже выполняется и быстро запускается, преимущественно у постоянных пользователей Java, однако JVM придется перезапускать каждый раз, когда запускается новый браузер.

- он может запуститься с сопоставимой (но обычно медленнее) скоростью на других компилируемых языках, таких как C++, но во много раз быстрее, чем JavaScript

- он может перенести работу с сервера к клиенту, делая Интернет-решение с, большим числом пользователей / клиентов.

Java-апплет обладает следующими недостатками:

- он требует установки Java-расширения (plug-in), которое не во всех браузерах доступно по умолчанию;

- он не может запуститься до тех пор, пока не запустится виртуальная Java-машина, и это может занять значительное время при первом запуске;

- создание и дизайн хорошего пользовательского интерфейса с использованием апплетов считается более сложной задачей, чем с помощью технологии, основанной на HTML;

- некоторые организации допускают только программное обеспечение, установленное администраторами. В результате многие пользователи не могут видеть апплеты по умолчанию.

- апплеты могут потребовать использования определенного JRE.

Однако, доступны свободно распространяемые реализации, такие как GCJ-plugin, Blackdown Java-plugin.

Вопросы совместимости

Компания Sun предприняла значительные усилия для обеспечения совместимости между Java-версиями по мере их появления. Например, Microsoft Internet Explorer, самый популярный браузер с конца 1990х, имел обыкновение загружать собственную JVM для Microsoft по умолчанию. MS JVM имеет ряд дополнительных функций, не входящих в Java, которые, будучи использованы, будут препятствовать выполнению MS JVM-апплетам в среде Sun's Java (но не наоборот). Sun предъявила Microsoft иск за нарушение прав на товарный знак, так как суть Java заключается в том, что не должно быть никакого собственного расширения и что код должен работать везде. Развитие MS JVM было заморожено до правового урегулирования, оставив многих пользователей с чрезвычайно устаревшими виртуальными Java-машинами. Позже, в октябре 2001 года, MS остановил включение Java в Windows, и в течение ряда лет было оставлено на усмотрение производителей компьютеров устанавливать Java или нет, независимо от операционной системы. Большинство новых машин сейчас поставляется с официальной Sun Java. Некоторые браузеры (в частности, Netscape) не очень хорошо обеспечивают 100%-ую совместимость, что затрудняет выполнение апплета большинством браузеров (JavaScript может с трудом использоваться для этой цели). Поскольку апплет создает свое собственное главное окно, это не является хорошим решением, так как это оставляет окно браузера в значительной степени бесполезным и приводит к тому, что увеличивается шанс непреднамеренного закрытия апплета пользователем путем закрытия исходного окна браузера.

Альтернативы

Существуют альтернативные технологии (например, DHTML, Microsoft Silverlight и Adobe Flash), которые реализуют некоторые возможности апплетов. Ещё одной альтернативой апплетов для клиента Java является Java Web Start, который запускается вне браузера. В дополнение к функциям, доступным в апплете, простой доступ к полям предоставляет программам Java Web Start доступ по чтению и-или записи определенных файлов, хранящихся у клиента, а также к буферу обмена клиента.

Глава 2. Разработка программы

2.1 Программирование сокетов

Сокетное соединение с сервером создается клиентом с помощью объекта класса Socket. При этом указывается IP-адрес сервера и номер порта. Если указано символьное имя домена, то Java преобразует его с помощью DNS-сервера к IP-адресу. Например, если сервер установлен на этом же компьютере, соединение с сервером можно установить из приложения клиента с помощью инструкции:

Socket socket = new Socket("ИМЯ_СЕРВЕРА", 3128);

Сервер ожидает сообщения клиента и должен быть заранее запущен с указанием определенного порта. Объект класса ServerSocket создается с указанием конструктору номера порта и ожидает сообщения клиента с помощью метода accept()класса ServerSocket, который возвращает сокет клиента:

ServerSocket server = new ServerSocket(3128);

Socket socket = server.accept();

Таким образом, для установки необходимо установить IP-адрес и номер порта сервера, IP-адрес и номер порта клиента. Обычно порт клиента и сервера устанавливаются одинаковыми. Клиент и сервер после установления сокетного соединения могут получать данные из потока ввода и записывать данные в поток вывода с помощью методов getInputStrеam() и getOutputStrеam() или к PrintStream для того, чтобы программа могла трактовать поток как выходные файлы.

Класс ServerSocket немного отличается от класса Socket. Класс Socket - это и есть сокет. Главное отличие ServerSocket заключается в том, что он умеет заставлять программу ждать подключений от клиентов. Когда вы его создаете, нужно указывать порт, с которым он будет работать, и вызвать его метод accept(). Этот метод заставляет программу ждать подключений по указанному порту. Исполнение программы зависает в этом месте, пока клиент не подключится. После успешного подключения клиентом, создается нормальный Socket объект, который вы можете использовать для выполнения все существующий операций с сокетом. Заметим также, что этот Socket объект отображает другой конец соединения. Если вы хотите отослать данные клиенту, то вы не можете использовать для этого ваш собственный сокет.

Следующим рассмотрим Socket класс. Вы можете создать Socket объект, указав IP-адрес и порт. Вы можете использовать InetAddress класс для отображения IP-адреса (этот способ более предпочтительный). Для создания InetAddress объекта используйте следующий метод:

InetAddress ipAddress = InetAddress.getByName(address);

После того как мы создали InetAddress, то можно создать Socket:

Socket socket = new Socket(ipAddress, serverPort);

После создания Socket объекта, можно взять входной и выходной потоки сокета. Входной поток позволит вам читать с сокета, а выходной поток дает возможность писать в сокет.

InputStream sin = socket.getInputStream();

OutputStream sout = socket.getOutputStream();

Следующие строки просто конвертируют потоки в другие типы потоков. После этого нам легче будет работать с String объектами. Этот код ничего не делает с сетью.

DataInputStream in = new DataInputStream(sin);

DataOutputStream out = new DataOutputStream(sout);

2.2 Проектирование и реализация

Для начала нам нужно подключить все необходимые библиотеки классов.

import java.applet.

Библиотека классов java.applet

Библиотека классов java.applet инкапсулирует поведение аплетов Java. Когда вы будете создавать свои аплеты, вам будет нужен класс Applet, расположенный в этой библиотеке классов. Дополнительно в библиотеке классов java.applet определены интерфейсы для подключения аплетов к содержащим их документам и классы для проигрывания звуковых фрагментов.

import java.awt.*;

import java.awt.event.*;

Библиотека классов java.awt

Для создания пользовательского интерфейса аплеты Java могут и должны использовать библиотеку классов java.awt. AWT - это сокращение от Abstract Window Toolkit (инструментарий для работы с абстрактными окнами).

Классы, входящие в состав библиотеки java.awt, предоставляют возможность создания пользовательского интерфейса способом, не зависящим от платформы, на которой выполняется аплет Java. Вы можете создавать обычные окна и диалоговые панели, кнопки, переключатели, списки, меню, полосы просмотра, однострочные и многострочные поля для ввода текстовой

import java.io.InputStream;

import java.io.OutputStream;

Библиотека классов java.io

В библиотеке классов java.io собраны классы, имеющие отношение к вводу и выводу данных через потоки. Заметим, что с использованием этих классов можно работать не только с потоками байт, но также и с потоками данных других типов, например числами int или текстовыми строками.

import java.net.InetAddress;

import java.net.Socket; - этот класс реализует клиентские сокеты. Сокет представляет собой конечную точку для связи между двумя машинами.

import java.net.ServerSocket; - этот класс реализует серверный сокет. Серверный сокет ожидает запросы, приходящие по сети от клиентов и может, при необходимости отправлять ответ.

Библиотека классов java.net

Язык программирования Java разрабатывался в предположении, что им будут пользоваться для создания сетевых приложений. Поэтому было бы странно, если бы в составе среды разработки приложений Java не поставлялась библиотека классов для работы в сети. Библиотека классов java.net предназначена как раз для этого. Она содержит классы, с помощью которых можно работать с универсальными сетевыми адресами URL, передавать данные с использованием сокетов TCP и UDP, выполнять различные операции с адресами IP.

Эта библиотека содержит также классы для выполнения преобразований двоичных данных в текстовый формат, что часто бывает необходимо.

Ниже будут представлены куски кода с кратким описанием выполняемых ими действий в данной программе, а так же некоторые экранные снимки.

Host.setBounds((screenWidth - buttonWidth) / 2, 20, buttonWidth, buttonHeight);

Connect.setBounds((screenWidth - buttonWidth) / 2, 70, buttonWidth, buttonHeight);

Quit.setBounds((screenWidth - buttonWidth) / 2, 120, buttonWidth, buttonHeight);

Задает границы и место размещение кнопок.

private void addButtons() {

Host = new JButton("Создать игру");

Connect = new JButton("Подключиться к игре");

Quit = new JButton("Выход");

}

Добавляет кнопки к JFrame и задает название кнопок.

private void addActions() {

Host.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

dispose();

new CreateServer();

}

});

Кнопка «Создать игру».

Connect.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

dispose();

new ClientPlayer();

}

});

Quit.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

System.exit(0);

}

});

Кнопки «Подключиться к игре» и «Выход» соответственно.

Рис.2.1 Главное меню

public class CreateServer extends Canvas implements Runnable, KeyListener

Создание сервера.

private void requestInformation() {

try {

serverPort = Integer.parseInt(JOptionPane.showInputDialog("Какой порт задействовать? (убедитесь, что он открыт)"));

} catch (Exception e) {

e.printStackTrace();

}

Подключение порта.

Рис.2.2 Выбор порта

Вводим порт и появляется вот такое окно:

Рис. 2.3 Игрок 1

Чтобы второму игроку подключиться ему нужно в меню выбрать пункт «Подключиться к игре».

Рис.2.4 IP-адрес сервера

Вводим IP сервера, жмем на кнопку «OK»? подключается следующее окно:

Рис.2.5 Порт сервера

Вводим порт, жмем «ОК» и наслаждаемся игрой.

Рис.2.6 Игрок 2

Заключение

В ходе работы были выполнены все поставленные задачи. Выяснили какие средства используются для сетевого программирования в различных языках, таких как C#, Perl и Python. Рассмотрели примеры.

Так же в ходе работы выяснилось, что на языке Java удобно работать с графикой. К примеру по средствам класса Graphics. Еще на Java часто используются Апплеты - прикладные программы. И благодаря платформенной независимости языка, апплеты могут выполняться с помощью плагинов браузерами многих платформ.

Изучена и рассмотрена технология использования сокетов на Java. С помощью всех полученных знаний была создана сетевая игра. В ходе тестирования были обнаружены небольшие недоработки, после чего все было исправлено и налажено.

сокетный сервер графика java

Список используемой литературы

1. Берд Б. Программирование на Java для чайников,-- М.: «Диалектика», 2013. -- 384 с.

2. Блох. Д. Java. Эффективное программирование-- М.: Лори, 2002. 224 с.

3. Лонг Ф, Дхрув М, Сикорд Р.С, Дин Ф. Сазерленд, Свобода Д. Руководство для программиста на Java . -- М.: «Вильямс», 2014. -- 256 с.

4. Нейгел К. C# 5.0 и платформа .NET 4.5 для профессионалов -- М.: «Диалектика», 2013. -- 1440 с.

5. Сузи Р. А. Язык программирования Python. -- М.: «Лаборатория знаний», 2006. -- 328 с.

6. Хорстманн К.С, Корнелл Г. Java. Библиотека профессионала, том 1. -- М.: «Вильямс», 2013. -- 864 с.

7. Шварц Р. Л., Феникс Т, Фой Б. Д. Изучаем Perl. М.: «Символ», 2009.С. 377.

Приложение 1

import java.awt.BorderLayout;

import java.awt.Canvas;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.Graphics;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.awt.image.BufferStrategy;

import java.awt.image.BufferedImage;

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.IOException;

import java.net.Socket;

import javax.swing.JFrame;

import javax.swing.JOptionPane;

public class ClientPlayer extends Canvas implements Runnable, KeyListener {

private static final long serialVersionUID = 1L;

DataOutputStream out;

DataInputStream in;

String serverIP;

int serverPort;

Socket socket;

JFrame frame;

int width = 600;

int height = 400;

public final Dimension gameDim = new Dimension(width, height);

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

int pWidth = 15;

int pHeight = 45;

int xPos;

int yPos;

int sXPos;

static int sYPos;

boolean moveUp = false;

boolean moveDown = false;

static int serverScore = 0;

static int clientScore = 0;

static int bX;

static int bY;

int bSize = 8;

private int ticks = 0;

private int frames = 0;

private int FPS = 0;

private int UPS = 0;

public double delta;

boolean limitFrameRate = false;

boolean shouldRender;

public void run() {

long lastTime = System.nanoTime();

double nsPerTick = 1000000000D / 60D;

long lastTimer = System.currentTimeMillis();

delta = 0D;

while (true) {

long now = System.nanoTime();

delta += (now - lastTime) / nsPerTick;

lastTime = now;

shouldRender = false;

while (delta >= 1) {

ticks++;

tick();

delta -= 1;

shouldRender = true;

}

if (!limitFrameRate && ticks > 0)

shouldRender = true;

if (shouldRender) {

frames++;

render();

}

if (System.currentTimeMillis() - lastTimer >= 1000) {

lastTimer += 1000;

FPS = frames;

UPS = ticks;

frames = 0;

ticks = 0;

}

}

}

private void requestInformation() {

serverIP = JOptionPane.showInputDialog("IP-адрес сервера.");

serverPort = Integer.parseInt(JOptionPane.showInputDialog("Порт сервера."));

}

private void createFrame() {

setMinimumSize(gameDim);

setMaximumSize(gameDim);

setPreferredSize(gameDim);

frame = new JFrame("Клиент");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setLayout(new BorderLayout());

frame.add(this, BorderLayout.CENTER);

frame.pack();

frame.setResizable(false);

frame.setLocationRelativeTo(null);

frame.setVisible(true);

xPos = frame.getWidth() - pWidth - 15;

yPos = frame.getHeight() / 2 - pHeight;

sXPos = 15;

sYPos = frame.getHeight() / 2 - pHeight;

addKeyListener(this);

requestFocus();

Thread thread = new Thread(this);

thread.start();

}

private void handShake() {

try {

socket = new Socket(serverIP, serverPort);

out = new DataOutputStream(socket.getOutputStream());

in = new DataInputStream(socket.getInputStream());

try {

out.writeUTF("это идёт к подключенному игроку");

} catch (IOException e1) {

e1.printStackTrace();

}

Input serverIn = new Input(in);

Thread inputThread = new Thread(serverIn);

inputThread.start();

} catch (IOException e) {

System.out.println("Соединение разорвано.");

}

}

public ClientPlayer() {

requestInformation();

handShake();

createFrame();

}

private void movement() {

if (moveUp && yPos > 0) {

yPos -= 3;

}

if (moveDown && yPos + pHeight < getHeight()) {

yPos += 3;

}

}

private void tick() {

movement();

try {

out.writeInt(yPos);

} catch (IOException e) {

e.printStackTrace();

}

}

private void render() {

BufferStrategy bs = getBufferStrategy();

if (bs == null) {

createBufferStrategy(3);

return;

}

Graphics g = bs.getDrawGraphics();

g.drawImage(image, 0, 0, getWidth(), getHeight(), null);

g.setColor(Color.WHITE);

g.fillRect(xPos, yPos, pWidth, pHeight);

g.fillRect(sXPos, sYPos, pWidth, pHeight);

g.fillOval(bX, bY, bSize, bSize);

g.drawString("P1 Score: " + serverScore, 40, 10);

g.drawString("P2 Score: " + clientScore, getWidth() - 105, 10);

g.dispose();

bs.show();

}

public void keyPressed(KeyEvent e) {

if (e.getKeyCode() == KeyEvent.VK_W) {

moveUp = true;

}

public void keyReleased(KeyEvent e) {

if (e.getKeyCode() == KeyEvent.VK_W) {

moveUp = false;

}

public void keyTyped(KeyEvent e) {

}

}

class Input implements Runnable {

DataInputStream in;

public Input(DataInputStream in) {

this.in = in;

}

public void run() {

while (true) {

try {

ClientPlayer.bX = in.readInt();

ClientPlayer.bY = in.readInt();

ClientPlayer.sYPos = in.readInt();

ClientPlayer.serverScore = in.readInt();

ClientPlayer.clientScore = in.readInt();

} catch (IOException e) {

System.out.println("Соединение потеряно.");

System.exit(0);

}

}

}

}

Приложение 2

import java.awt.BorderLayout;

import java.awt.Canvas;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.Graphics;

import java.awt.Rectangle;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.awt.image.BufferStrategy;

import java.awt.image.BufferedImage;

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

import javax.swing.JFrame;

import javax.swing.JOptionPane;

public class CreateServer extends Canvas implements Runnable, KeyListener {

private static final long serialVersionUID = 1L;

Ball b;

DataOutputStream out;

DataInputStream in;

ServerSocket serverSocket;

Socket socket;

int serverPort;

JFrame frame;

int width = 600;

int height = 400;

public final Dimension gameDim = new Dimension(width, height);

BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

int pWidth = 15;

int pHeight = 45;

int xPos;

int yPos;

int cXPos;

static int cYPos;

boolean moveUp = false;

boolean moveDown = false;

Rectangle serverRect;

Rectangle clientRect;

int serverScore = 0;

int clientScore = 0;

private int ticks = 0;

private int frames = 0;

private int FPS = 0;

private int UPS = 0;

public double delta;

boolean limitFrameRate = false;

boolean shouldRender;

private void requestInformation() {

try {

serverPort = Integer.parseInt(JOptionPane.showInputDialog("Какой порт задействовать? (убедитесь, что он открыт)"));

} catch (Exception e) {

e.printStackTrace();

}

}

public void run() {

long lastTime = System.nanoTime();

double nsPerTick = 1000000000D / 60D;

long lastTimer = System.currentTimeMillis();

delta = 0D;

while (true) {

long now = System.nanoTime();

delta += (now - lastTime) / nsPerTick;

lastTime = now;

shouldRender = false;

while (delta >= 1) {

ticks++;

tick();

delta -= 1;

shouldRender = true;

}

if (!limitFrameRate && ticks > 0)

shouldRender = true;

if (shouldRender) {

frames++;

render();

}

if (System.currentTimeMillis() - lastTimer >= 1000) {

lastTimer += 1000;

FPS = frames;

UPS = ticks;

frames = 0;

ticks = 0;

}

}

}

private void createFrame() {

setMinimumSize(gameDim);

setMaximumSize(gameDim);

setPreferredSize(gameDim);

frame = new JFrame("Сервер");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setLayout(new BorderLayout());

frame.add(this, BorderLayout.CENTER);

frame.pack();

frame.setResizable(false);

frame.setLocationRelativeTo(null);

frame.setVisible(true);

xPos = 15;

yPos = frame.getHeight() / 2 - pHeight;

cXPos = frame.getWidth() - pWidth - 15;

cYPos = frame.getHeight() / 2 - pHeight;

serverRect = new Rectangle(xPos, yPos, pWidth, pHeight);

clientRect = new Rectangle(cXPos, cYPos, pWidth, pHeight);

b = new Ball(this);

addKeyListener(this);

requestFocus();

Thread thread = new Thread(this);

thread.start();

}

private void handShake() {

try {

serverSocket = new ServerSocket(serverPort);

socket = serverSocket.accept();

if (out == null || in == null) {

out = new DataOutputStream(socket.getOutputStream());

in = new DataInputStream(socket.getInputStream());

}

ConnectedPlayer cp = new ConnectedPlayer(out, in);

Thread userThread = new Thread(cp);

System.out.println("Пользователь подключен");

userThread.start();

} catch (IOException e) {

e.printStackTrace();

}

}

public CreateServer() {

requestInformation();

handShake();

createFrame();

}

private void movement() {

if (moveUp && yPos > 0) {

yPos -= 3;

}

if (moveDown && yPos + pHeight < getHeight()) {

yPos += 3;

}

}

private void tick() {

movement();

serverRect.setBounds(xPos, yPos, pWidth, pHeight);

clientRect.setBounds(cXPos, cYPos, pWidth, pHeight);

b.tick();

try {

out.writeInt(b.x);

out.writeInt(b.y);

out.writeInt(yPos);

out.writeInt(serverScore);

out.writeInt(clientScore);

} catch (Exception e) {}

}

private void render() {

BufferStrategy bs = getBufferStrategy();

if (bs == null) {

createBufferStrategy(3);

return;

}

Graphics g = bs.getDrawGraphics();

g.drawImage(image, 0, 0, getWidth(), getHeight(), null);

g.setColor(Color.WHITE);

g.fillRect(xPos, yPos, pWidth, pHeight);

g.fillRect(cXPos, cYPos, pWidth, pHeight);

b.render(g);

g.drawString("Счёт игрока 1: " + serverScore, 40, 10);

g.drawString("Счёт игрока 2: " + clientScore, getWidth() - 105, 10);

g.dispose();

bs.show();

}

public void keyPressed(KeyEvent e) {

if (e.getKeyCode() == KeyEvent.VK_W) {

moveUp = true;

}

if (e.getKeyCode() == KeyEvent.VK_S) {

moveDown = true;

}

}

public void keyReleased(KeyEvent e) {

if (e.getKeyCode() == KeyEvent.VK_W) {

moveUp = false;

}

if (e.getKeyCode() == KeyEvent.VK_S) {

moveDown = false;

}

}

public void keyTyped(KeyEvent e) {

}

}

Размещено на Allbest.ur


Подобные документы

  • История развития языка программирования Java. История тетриса - культовой компьютерной игры, изобретённой в СССР. Правила проведения игры, особенности начисления очков. Создание интерфейса программы, ее реализация в среде Java, кодирование, тестирование.

    курсовая работа [168,1 K], добавлен 27.09.2013

  • История создания языка Java. Основные принципы объектно-ориентированного программирования. Структура, особенности синтаксиса и примеры прикладных возможностей использования языка Java, его преимущества. Перспективы работы программистом на языке Java.

    курсовая работа [795,9 K], добавлен 14.12.2012

  • Основа пользовательского интерфейса. Возможности пакетов java.awt.geom, java.awt, классов java.awt.Graphics и java.awt.Graphics2D. Основные графические примитивы и работа с потоками. Листинг программы и составление композиции аффинных преобразований.

    методичка [525,3 K], добавлен 30.06.2009

  • Создание языка программирования с помощью приложения "Java". История названия и эмблемы Java. Обзор многообразия современных текстовых редакторов. Обработка строки. Методы в классе String. Java: задачи по обработке текста. Примеры программирования.

    курсовая работа [276,1 K], добавлен 19.07.2014

  • Разработка графического редактора для рисования двухмерной и трехмерной графики, используя язык программирования Java и интерфейсы прикладного программирования Java 2D и Java 3D. Создание графического редактора 3D Paint. Основные методы класса Graphics.

    курсовая работа [197,5 K], добавлен 19.11.2009

  • Общее понятие о пакете "java.net". Логическая структура соединений через сокеты. Создание объекта Socket, соединение между узлами Internet. Способы создания потока. Алгоритм работы системы клиент-сервер. Листинг ServerForm.java, запуск подпроцесса.

    лабораторная работа [174,6 K], добавлен 27.11.2013

  • Архитектура Java и Java RMI, их основные свойства, базовая система и элементы. Безопасность и виртуальная Java-машина. Интерфейс Java API. Пример использования приложения RMI. Работа с программой "Calculator". Универсальность, портативность платформ.

    курсовая работа [208,6 K], добавлен 03.12.2013

  • Преимущество использования программ, написанных на Java, требования к ним и настройки на клиентском ПК. Развертывание и последующее "автоматическое" обновление версий GUI клиента с помощью использования технологии Java Web Start в среде Windows.

    реферат [33,2 K], добавлен 16.05.2011

  • Разработка и создание игры "Змейка". Использование динамически-активных принципов языка Java. Графические объекты программы. Описание игры, правила, теоретические сведения. Классы приложения. Типы данных. Реализация. Метод. Объект. Блок-схема игры.

    курсовая работа [12,4 K], добавлен 18.06.2008

  • Принцип работы Java. Аплеты как особенность Java-технологии, характеристика методов их защиты. Модель безопасности JDK1.2 и концепция "песочницы". Иерархия криптографических сервисов, алгоритмов. Объектная организация криптографической подсистемы Java.

    реферат [54,8 K], добавлен 09.09.2015

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.