<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CE8NQ3o6cCp7ImA9WhRaE0U.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794</id><updated>2012-02-16T11:01:32.418+02:00</updated><category term="linux" /><category term="сетевое программирование" /><category term="интеллектуальные_системы" /><category term="javascript" /><category term="php" /><category term="silverlight" /><category term="cycloid" /><category term="вконтакте" /><category term="liqpay" /><category term="HLSL" /><category term="gadget" /><category term="Wix" /><category term="MSI" /><category term="Java" /><category term="XNA" /><category term="ASP.NET" /><category term="C++" /><category term="gamedesign" /><category term="универ" /><category term="iTunes" /><category term="физика" /><category term="gamedev" /><category term="структуры данных" /><category term="coding" /><category term="uml" /><category term="fun" /><category term="xbox" /><title>Jack Spektor's blog</title><subtitle type="html">Евгений Спектор.персональный блог.&lt;br&gt;
C#, Delphi, coding and just life...</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://mr-kody.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>42</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/mr-kody" /><feedburner:info uri="mr-kody" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;A0cFQHY7cSp7ImA9WhdWEUk.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-2619510728189723400</id><published>2011-09-04T18:10:00.001+03:00</published><updated>2011-09-04T18:10:11.809+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-04T18:10:11.809+03:00</app:edited><title>MongoDB + NoRM - первые впечатления</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Решил сегодня разобраться с MongoDB.&lt;br /&gt;
&lt;br /&gt;
Т.к. ставить локально сервер не хотелось начал издалека. Нашёл бесплатный сервер MongoDB - MongoHQ. Хостинг обладает вполне адекватными ценовыми планами(16 МБ данных отдаётся в полном распоряжение разработчику бесплатно).&lt;br /&gt;
&lt;br /&gt;
Итого после регистрации я получил полнофункциональный instance MongoDB.&lt;br /&gt;
&lt;br /&gt;
Начал с поиска удобных GUI для просмотра БД. Вначале скачал MongoExplorer, однако тот наотрез отказался подключатся к удалённому серверу, поэтому выбор пал на MongoVUE. Последний подключился вполне успешно.&lt;br /&gt;
&lt;br /&gt;
Далее я следуя советам статьи:&lt;br /&gt;
&lt;a href="http://weblogs.asp.net/shijuvarghese/archive/2010/04/16/nosql-with-mongodb-norm-and-asp-net-mvc.aspx"&gt;http://weblogs.asp.net/shijuvarghese/archive/2010/04/16/nosql-with-mongodb-norm-and-asp-net-mvc.aspx&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Скачал NoRM, добавил в солюшн. Впрочем это было необязательно, т.к. в &amp;nbsp;NuGet уже есть пакет с последней версией NoRM.&lt;br /&gt;
&lt;br /&gt;
Итак, написав скромненький сайтик я решил поэксперементировать с Mongo, и какое же было моё разочарование, когда NoRM не захотел подключатся к MongoHQ. Вначале я подумал что я неправильно составил класс. Возможно использовал запрещённые типы, но на самом деле всё оказалось гораздо проще.&lt;br /&gt;
&lt;br /&gt;
Главной причиной проблем была версия Монго. На сервере MongoHQ стояла 1.8.1,а последняя &amp;nbsp;(и очевидно единственно поддерживаемая) есть 1.8.3, в результате чего операции добавления не работали. Поэтому как только я поставил сервер локально всё магическим образом заработало и обьекты были добавлены в БД.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Итого:&lt;/b&gt;&lt;br /&gt;
Плюсы:&lt;br /&gt;
- Классы автоматически сериализуются в JSON &amp;nbsp;и добавляются в БД. Писать слой доступа к данным крайне удобно&lt;br /&gt;
- БД обладает вполне достойным фреймворком для доступа из .NET (NoRM)&lt;br /&gt;
&lt;br /&gt;
Минусы:&lt;br /&gt;
- Всё таки невозможность поддержки 1.8.1 мне непонятна.&amp;nbsp;&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-2619510728189723400?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GsAXN6MEy8oaGU7v17P9nT4GA4k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GsAXN6MEy8oaGU7v17P9nT4GA4k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GsAXN6MEy8oaGU7v17P9nT4GA4k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GsAXN6MEy8oaGU7v17P9nT4GA4k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/xAOkBcGSo2E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/2619510728189723400/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2011/09/mongodb-norm.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/2619510728189723400?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/2619510728189723400?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/xAOkBcGSo2E/mongodb-norm.html" title="MongoDB + NoRM - первые впечатления" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2011/09/mongodb-norm.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQESH85eSp7ImA9WhdQEUo.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-6136829493653228994</id><published>2011-08-12T21:21:00.000+03:00</published><updated>2011-08-12T21:21:49.121+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-12T21:21:49.121+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gamedev" /><category scheme="http://www.blogger.com/atom/ns#" term="cycloid" /><category scheme="http://www.blogger.com/atom/ns#" term="XNA" /><category scheme="http://www.blogger.com/atom/ns#" term="xbox" /><title>Cycloid release</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Не прошло и года как игра дошла до своего финального состояние - а именно нахождения в Xbox Marketplace.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://marketplace.xbox.com/en-GB/Product/Cycloid/66acd000-77fe-1000-9115-d80258550917"&gt;http://marketplace.xbox.com/en-GB/Product/Cycloid/66acd000-77fe-1000-9115-d80258550917&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Случилось это ровно 11 августа - какраз на мой ДР. Вот такой подарок.&lt;br /&gt;
&lt;br /&gt;
Теперь остаётся ждать результатов продаж и надеятся что они окупят вложенные усилия :)&lt;br /&gt;
&lt;br /&gt;
PS: Счастливые владельцы Xbox могут бесплатно скачать триальную версию, а если понравится я с удовольствием поделюсь ключиком на полную версию.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-6136829493653228994?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/bT-IDV049Z7LFbJJwcp3BkvA3oY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bT-IDV049Z7LFbJJwcp3BkvA3oY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/bT-IDV049Z7LFbJJwcp3BkvA3oY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bT-IDV049Z7LFbJJwcp3BkvA3oY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/Oux67Q1G6xY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/6136829493653228994/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2011/08/cycloid-release.html#comment-form" title="Комментарии: 2" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/6136829493653228994?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/6136829493653228994?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/Oux67Q1G6xY/cycloid-release.html" title="Cycloid release" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2011/08/cycloid-release.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEABQ3k8cSp7ImA9WhZaGEw.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-3515180578459925320</id><published>2011-07-04T23:52:00.000+03:00</published><updated>2011-07-04T23:52:32.779+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-04T23:52:32.779+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="fun" /><title>Осторожно, Фиддлер</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Сегодня наткнулся на неприятную проблему - не работал ТФС, Online Services Sign In, что конечно не могло не расстраивать.&lt;br /&gt;
&lt;br /&gt;
2 перезагрузки компьютера не привели к результату.&lt;br /&gt;
&lt;br /&gt;
Вначале я подумал что всему виной смена пароля утром, но потом по подсказке коллеги узнал что всему виной ни кто иной как Fiddler. Который по непонятной причине не дружит с TFS, Online Services Sign In &amp;nbsp;и даже после закрытия не даёт возможности пользоваться благами цивилизации.&lt;br /&gt;
&lt;br /&gt;
Поэтому всё что оставалось это открыть фиддлер и снять флажок с Capture Traffic. После чего магическим образом всё заработало.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-3515180578459925320?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/jraP7qET8rUp-tc3nCr3A7-ZJ5I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jraP7qET8rUp-tc3nCr3A7-ZJ5I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/jraP7qET8rUp-tc3nCr3A7-ZJ5I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jraP7qET8rUp-tc3nCr3A7-ZJ5I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/G8ESpCHh4R4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/3515180578459925320/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2011/07/blog-post.html#comment-form" title="Комментарии: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/3515180578459925320?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/3515180578459925320?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/G8ESpCHh4R4/blog-post.html" title="Осторожно, Фиддлер" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2011/07/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQERnk5fCp7ImA9WhZSEkk.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-646479647628688076</id><published>2011-03-27T19:11:00.001+03:00</published><updated>2011-03-27T19:11:47.724+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-27T19:11:47.724+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MSI" /><category scheme="http://www.blogger.com/atom/ns#" term="Wix" /><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Создание msi инсталлятора с использованием Wix</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;В этом посте я хотел бы описать свой опыт использования инструментария Wix для создания инсталляционных пакетов.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Wix &lt;/b&gt;- это библиотека которая упрощает создание MSI пакетов. Wix интегрируется в Visual Studio и содержит несколько типов проектов. Я не хочу полностью описывать процесс создания инсталляционного пакета, а кратко опишу сложности с которыми я столкнулся.&lt;br /&gt;
&lt;br /&gt;
Полный туториал для изучения Wix можно легко найти например здесь: http://www.tramontana.co.hu/wix/&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. Deploy Database project output SQL script&lt;/b&gt;&lt;br /&gt;
Несмотря на то что что Wix содержит готовое расширение для установки БД в задаче пришлось делать по своему. Причиной тому послужило использование Visual Studio Database Project.&lt;br /&gt;
&lt;br /&gt;
Итак сам процесс занял следующие шаги:&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;1.Настройка Database Project&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: left;"&gt;По умолчанию Database Project самостоятельно задаёт переменную БД, в  результате чего даже если передать название БД в параметры sqlcmd в  скрипте она будет переопределена. Для того чтобы это предотвратить  необходимо задать в настройках Database Project  (Database.sqlDeployment) CommentOutSetVarDeclarations в false.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;u&gt;2.Создание CustomAction-а&lt;/u&gt;&lt;/div&gt;&lt;br /&gt;
Database project генерирует sql скрипт, для выполнения которого необходимо пользоваться утилитой sqlcmd. Поэтому для установки БД&amp;nbsp; необходимо вызывать sqlcmd из CustomAction-а, передавая в качестве параметра имя создаваемой БД.&lt;br /&gt;
&lt;br /&gt;
Сам CustomAction всего лишь запускает процесс sqlcmd.exe через Process.Start. Аргументы получаются через CustomActionData.&lt;br /&gt;
&lt;br /&gt;
В качестве аргументов задаются параметры подключения к SQL Server, а также имя БД. &lt;br /&gt;
Более полную информация о параметрах sqlcmd можно найти на http://msdn.microsoft.com/en-us/library/ms162773.aspx&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;3.Использование CustomAction-а&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;
Добавим компонент который будет содержат сгенерированный SQL скрипт. Для того чтобы скрипт автоматически подтягивался из Database Project-а последний добавим в References.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Component&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;SomeDatabase.sql&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;DiskId&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;1&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Guid&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;E1B7D00A-D6D8-4694-B4E0-E9AF67877119&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;File&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;SomeDatabase.sql&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Source&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;$(var.SomeDatabase.TargetDir)SomeDatabase.sql&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;KeyPath&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;yes&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;/&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&lt;/span&gt;&lt;span style="color: blue;"&gt;&lt;span style="color: #a31515;"&gt;Component&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
Для того чтобы использовать созданный CustomAction добавляем в References в Setup Project, после чего обьявляем CustomAction в коде Wix&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Binary&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;DeploySQLDll&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;SourceFile&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;$(var.DeploySQL.TargetDir)DeploySQL.CA.dll&lt;/span&gt;"&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;CustomAction&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;action&lt;/span&gt;"
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;BinaryKey&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;DeploySQLDll&lt;/span&gt;"
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;DllEntry&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Deploy&lt;/span&gt;"
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Return&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;ignore&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Execute&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;deferred&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;CustomAction&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;SetDeploySQLArguments&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Return&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;check&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Property&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;action&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;-U&amp;nbsp;[SQLLOGIN]&amp;nbsp;-P&amp;nbsp;[SQLPASSWORD]&amp;nbsp;-S&amp;nbsp;[SQLSERVER]&amp;nbsp;-i&amp;nbsp;"[#SomeDatabase.sql]"&amp;nbsp;-v DatabaseName="[DATABASENAME]"&amp;nbsp;&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;nbsp;/&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt; &lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;
Естественно переменные SQLLOGIN, SQLPASSWORD, SQLSERVER должны быть обьявлены ранее в файле проекта Wix.&lt;br /&gt;
&lt;br /&gt;
Последний штрих - вызов CustomAction в InstallSequence&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Custom&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Action&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;SetDeploySQLArguments&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;After&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;InstallFiles&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;NOT&amp;nbsp;Installed&lt;span style="color: blue;"&gt;&lt;span style="color: #a31515;"&gt;Custom&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Custom&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Action&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;action&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;After&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;SetDeploySQLArguments&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;NOT&amp;nbsp;Installed&lt;span style="color: blue;"&gt;&lt;span style="color: #a31515;"&gt;Custom&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;NOT Installed говорит о том, что данные действия будут запущенны только при установке программы. В случае удаления действия будут пропущены. Если же после удаления программы необходимо удалить БД, можно пользоваться уже созданным CustomAction-ом, но вместа скрипта создания БД выполнять скрипт удаления. Например приведённый ниже:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-attachment: scroll; background-clip: initial; background-color: white; background-image: none; background-origin: initial; background-position: 0% 0%; background-repeat: repeat repeat; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;EXEC&lt;/span&gt;&amp;nbsp;&lt;span style="color: teal;"&gt;msdb&lt;/span&gt;&lt;span style="color: grey;"&gt;.&lt;/span&gt;&lt;span style="color: teal;"&gt;dbo&lt;/span&gt;&lt;span style="color: grey;"&gt;.&lt;/span&gt;&lt;span style="color: maroon;"&gt;sp_delete_database_backuphistory&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: teal;"&gt;@database_name&lt;/span&gt;&amp;nbsp;&lt;span style="color: grey;"&gt;=&lt;/span&gt;&amp;nbsp;&lt;span style="color: red;"&gt;N'$(DatabaseName)'&lt;/span&gt;
&lt;span style="color: blue;"&gt;GO&lt;/span&gt;
 
&lt;span style="color: blue;"&gt;USE&lt;/span&gt;&amp;nbsp;&lt;span style="color: teal;"&gt;[master]&lt;/span&gt;
&lt;span style="color: blue;"&gt;GO&lt;/span&gt;
&lt;span style="color: blue;"&gt;ALTER&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;DATABASE&lt;/span&gt;&amp;nbsp;$&lt;span style="color: grey;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;DatabaseName&lt;/span&gt;&lt;span style="color: grey;"&gt;)&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;SET&lt;/span&gt;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;SINGLE_USER&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;WITH&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;ROLLBACK&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;IMMEDIATE&lt;/span&gt;
&lt;span style="color: blue;"&gt;GO&lt;/span&gt;
&lt;span style="color: blue;"&gt;USE&lt;/span&gt;&amp;nbsp;&lt;span style="color: teal;"&gt;[master]&lt;/span&gt;
&lt;span style="color: blue;"&gt;GO&lt;/span&gt;
&lt;span style="color: blue;"&gt;DROP&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;DATABASE&lt;/span&gt;&amp;nbsp;$&lt;span style="color: grey;"&gt;(&lt;/span&gt;&lt;span style="color: teal;"&gt;DatabaseName&lt;/span&gt;&lt;span style="color: grey;"&gt;)&lt;/span&gt;
&lt;span style="color: blue;"&gt;GO&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;2. Сохранить значение Property для использования во время Uninstall-а&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Допустим в процессе установки пользователь ввёл настройки подключения к БД для её установки,а во время удаления программы необходимо ими воспользоваться, чтобы БД удалить. К сожалению MSI не сохраняет данные значения, поэтому это придётся сделать самостоятельно.&lt;br /&gt;
&lt;br /&gt;
&lt;u&gt;Для этого необходимо:&lt;/u&gt;&lt;br /&gt;
1. Добавить сохранение свойства в реестр при установке:&lt;br /&gt;
&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;RegistryValue&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Root&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;HKLM&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Key&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;SOFTWARE\OurApp\SetupUninstall&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;SQLSERVER&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;[SQLSERVER]&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;string&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;nbsp;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;br /&gt;
2. При старте установщика искать в реестре значение свойства:&lt;br /&gt;
&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Property&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;SQLSERVER&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;localhost&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;RegistrySearch&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;RememberProperty1&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Root&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;HKLM&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Key&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;SOFTWARE\OurApp\SetupUninstall&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;SQLSERVER&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;'&lt;span style="color: blue;"&gt;raw&lt;/span&gt;'&lt;span style="color: blue;"&gt;&amp;nbsp;/&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&lt;span style="color: #a31515;"&gt;Property&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&lt;span style="color: blue;"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;/pre&gt;Теперь установщик будет сохранять введённые параметры установки. Не самый чистый способ, т.к. мусорит реестр, однако быстрый и надёжный.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3. Deploy Web-Site&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Т.к. Web-Site добавить в Reference нельзя ( в отличии от Web-Application),&amp;nbsp; и к тому же он обычно содержит много файлов удобнее пользоваться входящий в комплект Wix инструментом heat. Данная тулза позволяет собирать из папки все файлы и организовать их как Wix Fragment File.&lt;br /&gt;
&lt;br /&gt;
В моём случае тулза запускалась чтобы собрать сайт в файл фрагмента и далее добавить файлы в проект установщика. Для автоматической сборки в Pre-Build event добавлено событие:&lt;br /&gt;
&lt;br /&gt;
"$(WIX)bin\heat.exe" dir "$(SolutionDir)\ABC\UI" -gg -ke -template Fragment -out "$(ProjectDir)UI.wxs" -sfrag -srd -sreg -dr UIRef -cg UI -wixvar -var&amp;nbsp; wix.UI&lt;br /&gt;
&lt;br /&gt;
$(SolutionDir)\ABC\UI - путь к сайту&lt;br /&gt;
&lt;br /&gt;
Файл с фрагментом создаётся в файле UI.wxs, для и&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;спользования его в проекте Wix следует&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;добавить файл в проект, а в главный Wix файл продукта ссылку на со&lt;/span&gt;зданную директорию&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;Directory&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;UIRef&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;gt;&lt;span style="color: #a31515;"&gt;Directory&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;/pre&gt;Кроме того необходимо определить Wix-переменную&lt;br /&gt;
&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;span style="color: blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;WixVariable&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Id&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;UI&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;Value&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;$(var.SolutionDir)\ABC\UI&lt;/span&gt;"&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;pre style="background-attachment: scroll; background-clip: initial; background-color: white; background-image: none; background-origin: initial; background-position: 0% 0%; background-repeat: repeat repeat; color: black;"&gt;&lt;span style="color: blue; font-family: Arial, Helvetica, sans-serif;"&gt;
&lt;/span&gt;&lt;/pre&gt;Как можно заметить Id директории задаётся в параметрах heat.exe. Более подробную информацию о параметрах&lt;br /&gt;
heat можно найти на http://wix.sourceforge.net/manual-wix3/heat.htm&lt;br /&gt;
&lt;br /&gt;
Для создания веб-сайта в IIS можно воспользоваться готовыми расширениями Wix (WebApplication, WebDirectory и др.)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt; Плюсы:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;Легко интегрируется в Visual Studio, проект установщика хранится в TFS&lt;/li&gt;
&lt;li&gt;Возможна интеграция в MSBuild. Удобно для continuous integration.&lt;/li&gt;
&lt;li&gt;Имеет множество возможностей для конфигурации&lt;/li&gt;
&lt;li&gt;Open-source&lt;/li&gt;
&lt;/ul&gt;&lt;b&gt;Минусы:&lt;/b&gt;&lt;br /&gt;
&lt;div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;Процесс написания инсталляционного пакета занимает больше времени чем для автоматических утилит ( InnoSetup например).&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;В целом Wix очень удобен для инсталляции приложений, требующих сложной конфигурации и настройки ( deploy DB, Website, etc.).&lt;br /&gt;
&lt;pre style="background: none repeat scroll 0% 0% white; color: black; font-family: Consolas; font-size: 13px;"&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-646479647628688076?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Kk5HCyCAX4-Fa8qxVehWVzxqLuc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Kk5HCyCAX4-Fa8qxVehWVzxqLuc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Kk5HCyCAX4-Fa8qxVehWVzxqLuc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Kk5HCyCAX4-Fa8qxVehWVzxqLuc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/uavy3OhlTaA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/646479647628688076/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2011/03/msi-wix.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/646479647628688076?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/646479647628688076?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/uavy3OhlTaA/msi-wix.html" title="Создание msi инсталлятора с использованием Wix" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2011/03/msi-wix.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UHQns8eip7ImA9Wx5VFk8.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-61052474252542991</id><published>2010-10-09T14:41:00.001+03:00</published><updated>2010-10-09T14:53:53.572+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-09T14:53:53.572+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XNA" /><category scheme="http://www.blogger.com/atom/ns#" term="физика" /><title>2D Физика для игр - Separate Axis Theorem - Вектор сдвига</title><content type="html">&lt;i&gt;Как и обещал продолжаю перевод серии статей про игровую физику. Сегодня я напишу как получить вектор сдвига и разьединить 2 столкнувшихся многоугольника.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;Как было точно подмечено анонимным комментатором метод отделяющей оси работает только для выпуклых многоугольников.&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;
&lt;/i&gt;&lt;br /&gt;
&lt;b&gt;Итак, дано: &lt;/b&gt;2 столкнувшихся многоугольника&lt;br /&gt;
&lt;b&gt;Задача: &lt;/b&gt;Разьединить 2 многоугольника, причём минимальным сдвигом.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
В прошлом посте я писал как узнать пересекаются ли 2 многоугольника, это полезная информация, однако мы можем узнать больше. В случае если 2 многоугольника пересекаются хотелось бы сдвинуть их от друг друга, чтобы они не пересекались.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Для решения данной задачи может быть применён описанный ранее метод, только немного доработанный. Мы будем возвращать глубину проникновения и вектор, указывающий в какую сторону следует сдвинуть полигоны, чтобы они перестали пересекаться. Подобная комбинация называется MTD ( Minimum Translation Distance ), или минимальное расстояние сдвига.&lt;br /&gt;
&lt;br /&gt;
Вычислять MTD можно в процессе вычисления отделяющей оси.&lt;br /&gt;
&lt;br /&gt;
Когда 2 обьекта пересекаются, мы знаем интервал, вычисленный на каждой отделяющей оси для каждого обьекта. Интервал полученный пересечением двух интервалов есть вектор сдвига, который следует приложить к обьектам, чтобы их проэкции перестали пересекаться по отделяющей оси.&lt;br /&gt;
&lt;br /&gt;
&lt;span id="goog_72194188"&gt;&lt;/span&gt;&lt;span id="goog_72194189"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_U9jxq5NwSC4/TLBPcNZ0KsI/AAAAAAAADq8/-zLx585iero/s1600/image002a.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="265" src="http://2.bp.blogspot.com/_U9jxq5NwSC4/TLBPcNZ0KsI/AAAAAAAADq8/-zLx585iero/s320/image002a.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Очевидно, что можно сдвигать обьекты вектором сдвига по любой оси, но следует выбрать ту ось, на которой пересечение проекций обьектов минимально. Найденный вектор сдвига и является минимальным расстоянием сдвига ( MTD ).&lt;br /&gt;
&lt;br /&gt;
Получив вектор сдвига мы можем легко отделить 2 обьекта:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;A.position+=MTD*0.5f;&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;B.position-=MTD*0.5f;&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Код проверки пересечения с нахождением MTD:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// Проверяет на пересечение 2-х полигонов&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="a"&amp;gt;Первый многоугольник&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="b"&amp;gt;Второй многоугольник&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Intersect(Polygon a, Polygon b,&lt;span class="kwrd"&gt;out&lt;/span&gt; Vector2 pushV)
        {
            pushV = Vector2.Zero;
            &lt;span class="rem"&gt;//Если один из многоугольников пустой - то не пересекаются&lt;/span&gt;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (a == &lt;span class="kwrd"&gt;null&lt;/span&gt; || b == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;

            Vector2 pushAxis=Vector2.Zero;
            &lt;span class="kwrd"&gt;float&lt;/span&gt; mindepth = &lt;span class="kwrd"&gt;float&lt;/span&gt;.MaxValue;

            &lt;span class="rem"&gt;//Вычисляем отступ между многоугольниками для приведения к центру координат&lt;/span&gt;
            Vector2 offset = a.Offset - b.Offset;

            &lt;span class="rem"&gt;//В данной переменной храним ось на которую будет проецировать&lt;/span&gt;
            Vector2 xAxis = Vector2.Zero ;
            &lt;span class="kwrd"&gt;float&lt;/span&gt; depth;

            &lt;span class="rem"&gt;//Проходим по всем сторонам первого многоугольника и используем их как ось&lt;/span&gt;
            &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; j = a.VertexCount-1,i=0; i &amp;lt; a.VertexCount;j=i,i++)
            {
                &lt;span class="rem"&gt;//Вычисляем вектор стороны многоугольника&lt;/span&gt;
                Vector2 E = Vector2.Subtract(a[j], a[i]);
                &lt;span class="rem"&gt;//Вычисляем вектор нормали к стороне многоугольника&lt;/span&gt;
                xAxis = &lt;span class="kwrd"&gt;new&lt;/span&gt; Vector2(-E.Y, E.X);

                &lt;span class="rem"&gt;//Если проекции многоугольников не пересекаются - то по теореме многоугольники не пересекаются&lt;/span&gt;
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (!IntervalIntersect(a, b, &lt;span class="kwrd"&gt;ref&lt;/span&gt; xAxis, offset, &lt;span class="kwrd"&gt;out&lt;/span&gt; depth))
                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
                &lt;span class="kwrd"&gt;else&lt;/span&gt;
                {
                    &lt;span class="rem"&gt;//Находим ось по которой будем брать ось сдвига как ось минимального сдвига&lt;/span&gt;
                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (depth &amp;lt; mindepth)
                    {
                        pushAxis = xAxis;
                        mindepth = depth;
                    }
                }
            }

            &lt;span class="rem"&gt;//Если пока не нашли нужной оси - проходим по всем сторонам второго многоугольника&lt;/span&gt;
            &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; j = b.VertexCount - 1, i = 0; i &amp;lt; b.VertexCount; j = i, i++)
            {
                &lt;span class="rem"&gt;//Вычисляем вектор стороны и нормаль&lt;/span&gt;
                Vector2 E = Vector2.Subtract(b[j], b[i]);
                xAxis = &lt;span class="kwrd"&gt;new&lt;/span&gt; Vector2(-E.Y, E.X); &lt;span class="rem"&gt;//Getting normal vector&lt;/span&gt;

                &lt;span class="rem"&gt;//И проверяем на пересечение проекций&lt;/span&gt;
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (!IntervalIntersect(a, b, &lt;span class="kwrd"&gt;ref&lt;/span&gt; xAxis, offset, &lt;span class="kwrd"&gt;out&lt;/span&gt; depth))
                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
                &lt;span class="kwrd"&gt;else&lt;/span&gt;
                {
                        &lt;span class="rem"&gt;//Ищем ось сдвига&lt;/span&gt;
                        &lt;span class="kwrd"&gt;if&lt;/span&gt; (depth &amp;lt; mindepth)
                        {
                            pushAxis = xAxis;
                            mindepth = depth;
                        }
                }
            }

            &lt;span class="rem"&gt;//Вычисляем вектор сдвига&lt;/span&gt;
            pushV = pushAxis;
            mindepth /= pushV.Length();

            &lt;span class="rem"&gt;//Нормируем вектор сдвига и умножаем на длину пересечения&lt;/span&gt;
            pushV.Normalize();
            pushV *= (mindepth*1.01f);

            &lt;span class="rem"&gt;//Если вектор сдвига указывает в неправильно направлении - отражаем его&lt;/span&gt;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (Vector2.Dot(pushV, offset) &amp;lt; 0)
                pushV = Vector2.Negate(pushV);

            &lt;span class="rem"&gt;//Если ни одна из осей не нашла не пересекающихся проекций, то очевидно по теореме&lt;/span&gt;
            &lt;span class="rem"&gt;//многоугольники пересекаются - возвращаем тру.&lt;/span&gt;
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        }


        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// Проверяет на пересечение проекций многоугольников&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="a"&amp;gt;Первый многоугольник&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="b"&amp;gt;Второй многоугольник&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="xAxis"&amp;gt;Ось проекции&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="offset"&amp;gt;Отступ&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IntervalIntersect(Polygon a, Polygon b,&lt;span class="kwrd"&gt;ref&lt;/span&gt; Vector2 xAxis, Vector2 offset,&lt;span class="kwrd"&gt;out&lt;/span&gt; &lt;span class="kwrd"&gt;float&lt;/span&gt; depth)
        {
            depth = 0;
            
            &lt;span class="kwrd"&gt;float&lt;/span&gt; min0, max0, min1, max1; &lt;span class="rem"&gt;//проекции на ось первого и второго многоугольника&lt;/span&gt;
            GetInterval(a, xAxis, &lt;span class="kwrd"&gt;out&lt;/span&gt; min0, &lt;span class="kwrd"&gt;out&lt;/span&gt; max0);&lt;span class="rem"&gt;//получаем первую проекцию&lt;/span&gt;
            GetInterval(b, xAxis, &lt;span class="kwrd"&gt;out&lt;/span&gt; min1, &lt;span class="kwrd"&gt;out&lt;/span&gt; max1);&lt;span class="rem"&gt;//получаем вторую проекцию&lt;/span&gt;

  

            &lt;span class="kwrd"&gt;float&lt;/span&gt; h = Vector2.Dot(offset, xAxis); &lt;span class="rem"&gt;//получаем проекцию отступа &lt;/span&gt;
            min0 += h; max0 += h; &lt;span class="rem"&gt;// и добавляем её к первому многоугольнику&lt;/span&gt;


            &lt;span class="kwrd"&gt;float&lt;/span&gt; d0 = min0 - max1; 
            &lt;span class="kwrd"&gt;float&lt;/span&gt; d1 = min1 - max0;

            &lt;span class="rem"&gt;//если проекции не пересекаются то минимум первого больше максимума второго или&lt;/span&gt;
            &lt;span class="rem"&gt;//минимум второго больше максимума первого.&lt;/span&gt;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (d0 &amp;gt; 0 || d1 &amp;gt; 0)
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            &lt;span class="kwrd"&gt;else&lt;/span&gt;
            {
                depth = Math.Min(Math.Abs(d0), Math.Abs(d1));
                Trace.WriteLine(depth);
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            }
        }&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;b&gt;Исходные файлы:&lt;/b&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;b&gt;
&lt;/b&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;a href="https://docs.google.com/leaf?id=0B6h7yaggRA4pOWFhYmE0MTgtYTgxZC00MGViLTgxNmQtZjU4NmE2YWRjMTRl&amp;amp;hl=en"&gt;https://docs.google.com/leaf?id=0B6h7yaggRA4pOWFhYmE0MTgtYTgxZC00MGViLTgxNmQtZjU4NmE2YWRjMTRl&amp;amp;hl=en&lt;/a&gt;

&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-61052474252542991?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yvrAUp5yJ-8WGNxoGwkzAv0d8WQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yvrAUp5yJ-8WGNxoGwkzAv0d8WQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yvrAUp5yJ-8WGNxoGwkzAv0d8WQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yvrAUp5yJ-8WGNxoGwkzAv0d8WQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/oFlA09Aqr54" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/61052474252542991/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/10/2d-separate-axis-theorem_09.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/61052474252542991?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/61052474252542991?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/oFlA09Aqr54/2d-separate-axis-theorem_09.html" title="2D Физика для игр - Separate Axis Theorem - Вектор сдвига" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_U9jxq5NwSC4/TLBPcNZ0KsI/AAAAAAAADq8/-zLx585iero/s72-c/image002a.gif" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/10/2d-separate-axis-theorem_09.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UMR3s-fip7ImA9Wx5VFk8.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-7283743872119795959</id><published>2010-10-01T21:31:00.003+03:00</published><updated>2010-10-09T14:54:46.556+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-09T14:54:46.556+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gamedev" /><category scheme="http://www.blogger.com/atom/ns#" term="XNA" /><category scheme="http://www.blogger.com/atom/ns#" term="физика" /><title>2D Физика для игр - Separate Axis Theorem</title><content type="html">&lt;i&gt;Нашёл в интернете очень интересную подборку статей и кода, которая описывает написание физики для игр. Я подумал что было бы полезно перевести серию тех статей и портировать код на XNA. Как для себя, так и для интересующихся игровой физикой.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Первая статья будет посвящена &lt;b&gt;Separete Axis Theorem&lt;/b&gt;&amp;nbsp;( &lt;b&gt;теорема о разделяющей оси&lt;/b&gt; )- методу проверки столкновений между многоугольниками. Данный метод является наиболее быстрым на данный момент и используется повсеместно во всех 2D физических библиотеках.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Итак, задача&lt;/b&gt;: Нам даны два многугольника в виде массива координат вершин. Необходимо проверить их на пересечение.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Separeta Axis Theorem &lt;/b&gt;утверждает, что если два обьекта не пересекаются, то существует прямая которая разделяет эти обьекты, т.е. проекции на нормаль этой прямой не пересекаются.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_U9jxq5NwSC4/TKYbr9Ri2jI/AAAAAAAADq0/5bf1a8ELNos/s1600/image001a.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="238" src="http://3.bp.blogspot.com/_U9jxq5NwSC4/TKYbr9Ri2jI/AAAAAAAADq0/5bf1a8ELNos/s320/image001a.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Заметим что таких прямых может быть несметное количество, однако к счастью в нашем случае мы их ограничим. Доказано что для многоугольников &amp;nbsp;одна из таких осей является сторона одного из многоугольников. Если ни одна из 4-х сторон прямоугольников не подходит, то очевидно прямоугольники пересекаются.&lt;br /&gt;
&lt;br /&gt;
Аналогично происходит с треугольниками, пятиугольниками и т.д.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_U9jxq5NwSC4/TKYc_qbH16I/AAAAAAAADq4/HyoxU0mueEQ/s1600/image001b.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="248" src="http://4.bp.blogspot.com/_U9jxq5NwSC4/TKYc_qbH16I/AAAAAAAADq4/HyoxU0mueEQ/s320/image001b.gif" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
На данном рисунке мы видим, что проекции на красную ось пересекаются, что не даёт нам возможности утверждать, что треугольники разделены. В то время выбрав в качестве оси нормаль одного из треугольников ( синяя ось) проекции не пересекаются, т.е. треугольники&lt;b&gt; не пересекаются.&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
Таким образом алгоритм состоит из трёх частей:&lt;br /&gt;
1. Поиск оси, которая разделяет многоугольники. (фактически проверка каждой стороны многоугольников)&lt;br /&gt;
2. Получение проекций многоугольников на ось.&lt;br /&gt;
3. Проверка на пересечение интервалов.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
 font-size: small;
 color: black;
 font-family: Consolas, "Courier New", Courier, Monospace;
 background-color: #ffffff;
 /*white-space: pre;*/
}

.csharpcode pre { margin: 0em; }

.csharpcode .rem { color: #008000; }

.csharpcode .kwrd { color: #0000ff; }

.csharpcode .str { color: #006080; }

.csharpcode .op { color: #0000c0; }

.csharpcode .preproc { color: #cc6633; }

.csharpcode .asp { background-color: #ffff00; }

.csharpcode .html { color: #800000; }

.csharpcode .attr { color: #ff0000; }

.csharpcode .alt 
{
 background-color: #f4f4f4;
 width: 100%;
 margin: 0em;
}

.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;br /&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; Intersect(Polygon a, Polygon b)
        {
            &lt;span class="rem"&gt;//Если один из многоугольников пустой - то не пересекаются&lt;/span&gt;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (a == &lt;span class="kwrd"&gt;null&lt;/span&gt; || b == &lt;span class="kwrd"&gt;null&lt;/span&gt;)
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;

            &lt;span class="rem"&gt;//Вычисляем отступ между многоугольниками для приведения к центру координат&lt;/span&gt;
            Vector2 offset = a.Offset - b.Offset;

            &lt;span class="rem"&gt;//В данной переменной храним ось на которую будет проецировать&lt;/span&gt;
            Vector2 xAxis = Vector2.Zero ;

            &lt;span class="rem"&gt;//Проходим по всем сторонам первого многоугольника и используем их как ось&lt;/span&gt;
            &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; j = a.VertexCount-1,i=0; i &amp;lt; a.VertexCount;j=i,i++)
            {
                &lt;span class="rem"&gt;//Вычисляем вектор стороны многоугольника&lt;/span&gt;
                Vector2 E = Vector2.Subtract(a[j], a[i]);
                &lt;span class="rem"&gt;//Вычисляем вектор нормали к стороне многоугольника&lt;/span&gt;
                xAxis = &lt;span class="kwrd"&gt;new&lt;/span&gt; Vector2(-E.Y, E.X); 

                &lt;span class="rem"&gt;//Если проекции многоугольников не пересекаются - то по теореме многоугольники не пересекаются&lt;/span&gt;
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (!IntervalIntersect(a, b, xAxis, offset))
                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            }

            &lt;span class="rem"&gt;//Если пока не нашли нужной оси - проходим по всем сторонам второго многоугольника&lt;/span&gt;
            &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; j = b.VertexCount - 1, i = 0; i &amp;lt; b.VertexCount; j = i, i++)
            {
                &lt;span class="rem"&gt;//Вычисляем вектор стороны и нормаль&lt;/span&gt;
                Vector2 E = Vector2.Subtract(b[j], b[i]);
                xAxis = &lt;span class="kwrd"&gt;new&lt;/span&gt; Vector2(-E.Y, E.X); &lt;span class="rem"&gt;//Getting normal vector&lt;/span&gt;

                &lt;span class="rem"&gt;//И проверяем на пересечение проекций&lt;/span&gt;
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (!IntervalIntersect(a, b, xAxis, offset))
                    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            }

            &lt;span class="rem"&gt;//Если ни одна из осей не нашла не пересекающихся проекций, то очевидно по теореме&lt;/span&gt;
            &lt;span class="rem"&gt;//многоугольники пересекаются - возвращаем тру.&lt;/span&gt;
            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        }&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Код функций нахождения проэкции и пересечения интервалов:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// Проверяет на пересечение проекций многоугольников&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="a"&amp;gt;Первый многоугольник&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="b"&amp;gt;Второй многоугольник&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="xAxis"&amp;gt;Ось проекции&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="offset"&amp;gt;Отступ&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;bool&lt;/span&gt; IntervalIntersect(Polygon a, Polygon b, Vector2 xAxis, Vector2 offset)
        {
            &lt;span class="kwrd"&gt;float&lt;/span&gt; min0, max0, min1, max1; &lt;span class="rem"&gt;//проекции на ось первого и второго многоугольника&lt;/span&gt;
            GetInterval(a, xAxis, &lt;span class="kwrd"&gt;out&lt;/span&gt; min0, &lt;span class="kwrd"&gt;out&lt;/span&gt; max0);&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;//получаем первую проекцию&lt;/span&gt;
            GetInterval(b, xAxis, &lt;span class="kwrd"&gt;out&lt;/span&gt; min1, &lt;span class="kwrd"&gt;out&lt;/span&gt; max1);&lt;span class="rem"&gt;
//получаем вторую проекцию&lt;/span&gt;

            &lt;span class="kwrd"&gt;float&lt;/span&gt; h = Vector2.Dot(offset, xAxis); &lt;span class="rem"&gt;//получаем проекцию отступа &lt;/span&gt;
            min0 += h; max0 += h; &lt;span class="rem"&gt;// и добавляем её к первому многоугольнику&lt;/span&gt;

            &lt;span class="kwrd"&gt;float&lt;/span&gt; d0 = min0 - max1; 
            &lt;span class="kwrd"&gt;float&lt;/span&gt; d1 = min1 - max0;

            &lt;span class="rem"&gt;//если проекции не пересекаются то минимум первого больше максимума второго или&lt;/span&gt;
            &lt;span class="rem"&gt;//минимум второго больше максимума первого.&lt;/span&gt;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (d0 &amp;gt; 0.0f || d1 &amp;gt; 0.0f)
                &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;false&lt;/span&gt;;
            &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;true&lt;/span&gt;;
        }

        &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// Получает проекцию на ось&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="a"&amp;gt;Многоугольник&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="xAxis"&amp;gt;Ось&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="min0"&amp;gt;Начало проекции&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="rem"&gt;/// &amp;lt;param name="max0"&amp;gt;Конец проекции&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; GetInterval(Polygon a, Vector2 xAxis, &lt;span class="kwrd"&gt;out&lt;/span&gt; &lt;span class="kwrd"&gt;float&lt;/span&gt; min0, &lt;span class="kwrd"&gt;out&lt;/span&gt; &lt;span class="kwrd"&gt;float&lt;/span&gt; max0)
        {
            min0 = max0 = Vector2.Dot(a[0],xAxis);
            &lt;span class="rem"&gt;//Проходимся по всем вершинам и проецируем их на ось&lt;/span&gt;
            &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 1; i &amp;lt; a.VertexCount; i++)
            {
                &lt;span class="rem"&gt;//проецируем вершину на ось&lt;/span&gt;
                &lt;span class="kwrd"&gt;float&lt;/span&gt; dot = Vector2.Dot(a[i], xAxis); 
                &lt;span class="rem"&gt;//Устанавливаем минимум и максимум&lt;/span&gt;
                &lt;span class="kwrd"&gt;if&lt;/span&gt; (dot &amp;lt; min0)
                    min0 = dot;
                &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (dot &amp;gt; max0)
                    max0 = dot;
            }
        }&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;b&gt;Полные исходные коды можно скачать здесь:&lt;/b&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;b&gt;&lt;a href="https://sites.google.com/site/jackdevolpment/files/physicsTutorial.7z?attredirects=0&amp;amp;d=1"&gt;https://sites.google.com/site/jackdevolpment/files/physicsTutorial.7z?attredirects=0&amp;amp;d=1&lt;/a&gt;&lt;/b&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;или здесь&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;a href="https://docs.google.com/leaf?id=0B6h7yaggRA4pNDg1M2Y1ODUtNDYyMC00Yjg2LTlhMWUtMWNlYWNlYTFlNjJl&amp;amp;hl=en"&gt;https://docs.google.com/leaf?id=0B6h7yaggRA4pNDg1M2Y1ODUtNDYyMC00Yjg2LTlhMWUtMWNlYWNlYTFlNjJl&amp;amp;hl=en&lt;/a&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;b&gt;Ссылки на другие ресурсы по SAT:&lt;/b&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;b&gt;&lt;a href="http://www.metanetsoftware.com/technique/tutorialA.html"&gt;http://www.metanetsoftware.com/technique/tutorialA.html&lt;/a&gt;&lt;/b&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;a href="http://www.sevenson.com.au/actionscript/sat/"&gt;http://www.sevenson.com.au/actionscript/sat/&lt;/a&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;a href="http://www.gamedev.ru/code/terms/SAT"&gt;http://www.gamedev.ru/code/terms/SAT&lt;/a&gt;&lt;/pre&gt;&lt;pre class="csharpcode"&gt;&lt;a href="http://noregret.org/tutor/n/collision/"&gt;http://noregret.org/tutor/n/collision/&lt;/a&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-7283743872119795959?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/40RQj-KMdmFJyrkj3xHYaYoa1Rs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/40RQj-KMdmFJyrkj3xHYaYoa1Rs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/40RQj-KMdmFJyrkj3xHYaYoa1Rs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/40RQj-KMdmFJyrkj3xHYaYoa1Rs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/ixKugGolytc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/7283743872119795959/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/10/2d-separate-axis-theorem.html#comment-form" title="Комментарии: 2" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/7283743872119795959?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/7283743872119795959?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/ixKugGolytc/2d-separate-axis-theorem.html" title="2D Физика для игр - Separate Axis Theorem" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_U9jxq5NwSC4/TKYbr9Ri2jI/AAAAAAAADq0/5bf1a8ELNos/s72-c/image001a.gif" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/10/2d-separate-axis-theorem.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QFR3c4fyp7ImA9Wx5VFk8.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-3774438892251960277</id><published>2010-09-25T21:27:00.003+03:00</published><updated>2010-10-09T14:55:16.937+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-09T14:55:16.937+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="вконтакте" /><category scheme="http://www.blogger.com/atom/ns#" term="php" /><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Vkontakte Merchant API</title><content type="html">Сегодня был свободный день и почти всё время провёл дома. Но решил не тратить его попусту и сделать небольшой сайт-магазин для моей игры, попутно немного изучив &lt;b&gt;Vkontakte Merchant API&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
В принципе что меня удивило - это простота установки данного API. Сам процесс вставки в сайт кнопки покупки действительно занимает минуты,а большинство времени было потрачено на написание заглушек для Callback-страниц.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Т.к. к сожалению Callback страница обязательна должна быть в интернете пришлось зарегистрировать аккаунт на бесплатном пхп хостинге. Тут мне был в помощь сервис &lt;a href="http://0fees.net/"&gt;0fees.net&lt;/a&gt;. Данный сервис предложил вполне адекватных пхп хостинг и включал в себя БД, поддержку отправки почты через &amp;nbsp;mail, и наверно единственным его минусом было то что в нём было ограничение на макс.размер файлов. Прямым текстом это нигде не написано, но архив с моей игрой удалялся сразу после закачки на сервер. К счастью на процесс тестирования АПИ это ограничение никак не влияло.&lt;br /&gt;
&lt;br /&gt;
Как оно всегда бывает заглушка-пример не работала и примерно через попыток 10 ковыряния я решил подойти к вопросу кардинально и начал писать с нуля. Кстати, замечу что сервис довольно гибкий, включает обратные вызовы для списков методов доставки и т.д. Мне же нужен был только один обратный вызов - оповещение сервера об оплате пользователем товара. Поэтому реализовывал я только 1 заглушку, а другие отключил.&lt;br /&gt;
&lt;br /&gt;
В принципе вся работа заглушки сводится к обработке входящих через ПОСТ переменных, проверки хэша и вывода в случае успеха ХМЛ следующего вида:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8" ?&amp;gt;
&amp;lt;success&amp;gt;
  &amp;lt;order-id&amp;gt;идентификатор заказа в платёжной системе&amp;lt;/order-id&amp;gt;
  &amp;lt;merchant-order-id&amp;gt;идентификатор заказа в системе продавца&amp;lt;/merchant-order-id&amp;gt;
&amp;lt;/success&amp;gt; &lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;
Вообщем хочется подытожить свои ощущения от использования:&lt;br /&gt;
+ скрипт легко устанавливает и конфигурируется&lt;br /&gt;
&lt;b&gt;+ &lt;/b&gt;пользователь получает инструменты управления магазином и заказами. если заглушки не писать можно обрабатывать заказы вручную&lt;br /&gt;
- не описаны методы как сделать нестандартный дизайн кнопки&lt;br /&gt;
- немного раздражает факт наличия всплывающих окон&lt;br /&gt;
&lt;br /&gt;
Всё моё художество можно увидеть на&amp;nbsp;&lt;a href="http://jackthehack.0fees.net/"&gt;http://jackthehack.0fees.net/&lt;/a&gt;&lt;br /&gt;
Кстати походу упал сервер userapi.com на который ссылаются виджеты комментариев и "мне нравится" =(&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-3774438892251960277?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/mWkURI1qKFupjlt5L_7eBzpbPYM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mWkURI1qKFupjlt5L_7eBzpbPYM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/mWkURI1qKFupjlt5L_7eBzpbPYM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/mWkURI1qKFupjlt5L_7eBzpbPYM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/eJQmAVODsgw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/3774438892251960277/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/09/vkontakte-merchant-api.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/3774438892251960277?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/3774438892251960277?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/eJQmAVODsgw/vkontakte-merchant-api.html" title="Vkontakte Merchant API" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/09/vkontakte-merchant-api.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QBSXgycCp7ImA9Wx5VFk8.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-2257558526168681354</id><published>2010-08-27T13:03:00.001+03:00</published><updated>2010-10-09T14:55:58.698+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-09T14:55:58.698+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gamedev" /><category scheme="http://www.blogger.com/atom/ns#" term="XNA" /><category scheme="http://www.blogger.com/atom/ns#" term="HLSL" /><title>RadialBlur HLSL Shader - 3 сэмпла</title><content type="html">Решил добавить в игру простенький &lt;b&gt;эффект радиальной размытия&lt;/b&gt;. В нете к счастью нашёл много информации, в результате скомпонованный шейдер получился следующего вида:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
sampler ColorMapSampler : register(s0);&lt;br /&gt;
&lt;br /&gt;
float4 radialBlur(float2 vTex:TEXCOORD0):COLOR&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;float4 result=float4(1,0,0,1);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;//массив с сэмплами. тут их 3 для производительности&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;float samples[3] = {0.05 ,0.03, &amp;nbsp;0.01};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;// 0.5,0.5 центр экранных координат&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;// т.е. отнимая от (0.5,0.5) текстурные координаты&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;// мы получаем вектор указывающий на центр экрана&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;float2 dir = 0.5 - vTex;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;// вычисляем расстояние до центра&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;float dist = length(dir);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;// нормализуем&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;dir = dir/dist;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;// получаем цвет текущего пикселя&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;float4 color = tex2D(ColorMapSampler,vTex);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;float4 sum = color;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;// берём ещё 3 сэмпла из пикселей противоположных центру экрана&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;for (int i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;sum += tex2D( ColorMapSampler, vTex + dir * samples[i] * dist );&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;// всего взяли 4 сэмпла ( 3 соседних и 1 текущий)&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;sum *= 0.25f;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;// коэффициент 0.7 указывается силу эффекта&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;float t = dist * 0.7f;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;t = clamp( t ,0.0,1.0);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;//интерполируем текущий цвет с рассчитанным по расстоянию до центра&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;result = lerp( color, sum, t );&lt;br /&gt;
&lt;br /&gt;
return result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
technique PostProcess&lt;br /&gt;
{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;pass P1&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;// A post process shader only needs a pixel shader.&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;PixelShader = compile ps_2_0 radialBlur();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
}&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-2257558526168681354?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HyRxRgqdi3qxR_kSauJugAQIQHo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HyRxRgqdi3qxR_kSauJugAQIQHo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HyRxRgqdi3qxR_kSauJugAQIQHo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HyRxRgqdi3qxR_kSauJugAQIQHo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/JinyNIbdWKc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/2257558526168681354/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/08/radialblur-hlsl-shader-3.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/2257558526168681354?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/2257558526168681354?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/JinyNIbdWKc/radialblur-hlsl-shader-3.html" title="RadialBlur HLSL Shader - 3 сэмпла" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/08/radialblur-hlsl-shader-3.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUUARn44fCp7ImA9Wx5REkw.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-383210759552526212</id><published>2010-08-19T13:20:00.000+03:00</published><updated>2010-08-19T13:20:47.034+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-19T13:20:47.034+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XNA" /><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title /><content type="html">Убрал баг с Alt-Tab, который возникал в полноэкранном режиме игры. Оказывается теперь XNA сама заботиться об восстановлении графического устройства после его потери. Я же думал что его нужно восстанавливать вручную по событию DeviceLost, что конечно неправильно.&lt;br /&gt;
&lt;br /&gt;
Слава богу существует класс Trace который позволяет сделать быстрый лог того что происходит и значительно упростил отладку и поиск ошибки.&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-383210759552526212?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6DekZ-aiqu-Ebhz-YmNB1b5Uvgo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6DekZ-aiqu-Ebhz-YmNB1b5Uvgo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6DekZ-aiqu-Ebhz-YmNB1b5Uvgo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6DekZ-aiqu-Ebhz-YmNB1b5Uvgo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/Grj1IQI60io" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/383210759552526212/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/08/alt-tab.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/383210759552526212?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/383210759552526212?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/Grj1IQI60io/alt-tab.html" title="" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/08/alt-tab.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUHQHs6eip7ImA9WxFaGUw.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-1099151537087970975</id><published>2010-07-23T21:37:00.000+03:00</published><updated>2010-07-23T21:37:11.512+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-23T21:37:11.512+03:00</app:edited><title>Диплом в Шаге - 12/12</title><content type="html">Наконец-то сдал диплом в Шаге на оценку 5+. Процесс защиты длился 12 часов с часовым перерывом, но и студенты и преподаватели выдержали этот экзамен =)&lt;br /&gt;
На радостях выкладываю видео дипломного проекта и арканоида. Разработка не прекращается,а продолжается и как я обещал скоро будет новое оформление и релиз.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;center&gt;&lt;br /&gt;
&lt;iframe frameborder="0" height="360" src="http://vkontakte.ru/video_ext.php?oid=3667736&amp;amp;id=147283521&amp;amp;hash=c1662caafea85eb9" width="500"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;/center&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-1099151537087970975?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5gdUC0zkVVM1nusPxulXZIORz8Q/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5gdUC0zkVVM1nusPxulXZIORz8Q/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5gdUC0zkVVM1nusPxulXZIORz8Q/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5gdUC0zkVVM1nusPxulXZIORz8Q/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/571QyjHklKs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/1099151537087970975/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/07/1212.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/1099151537087970975?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/1099151537087970975?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/571QyjHklKs/1212.html" title="Диплом в Шаге - 12/12" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/07/1212.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4DQXc-eSp7ImA9WxFaFEk.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-2574134415582491421</id><published>2010-07-18T13:20:00.002+03:00</published><updated>2010-07-18T13:29:30.951+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-18T13:29:30.951+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gamedev" /><category scheme="http://www.blogger.com/atom/ns#" term="XNA" /><title>HLSL шейдеры для чайников</title><content type="html">&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Шейдерная графика сейчас наиболее популярна. Большинство игр так и пестрят системными требованиями Shader 2.0, что&amp;nbsp;конечно&amp;nbsp;разочаровывает владельцев стареньких ПК, и радует картинкой современных геймеров. В этой статье я попытаюсь рассказать вкратце о том как писать HLSL шейдеры на XNA и в результате получить шейдер радиальной градиентной заливки.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Итак. Нам понадобяться следующие инструменты:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;XNA Game Studio&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Видеокарта с поддержкой шейдеров&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Итак для начала мы создадим "Windows Game" проект в студии. Далее нам необходимо создать небольшую текстурку. Неважно её содержимое, сколько само её существование. Поэтому добавляем к Content новый элемент - текстуру 2*2.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Далее нам необходимо нарисовать её, поэтому добавляем в класс Game переменную Texture2D и загружаем её в LoadContent&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Texture2D texture;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;protected override void LoadContent()&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;// Create a new SpriteBatch&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;spriteBatch = new SpriteBatch(GraphicsDevice);&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;texture = Content.Load&lt;texture2d&gt;("tex");&lt;/texture2d&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;и далее отрисовываем её, например так:&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;protected override void Draw(GameTime gameTime)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;GraphicsDevice.Clear(Color.CornflowerBlue);&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.SaveState);&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;spriteBatch.Draw(texture,&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;new Rectangle(0, 0,&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;400, 300), Color.White);&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;spriteBatch.End();&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;base.Draw(gameTime);&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Если всё сделано правильно, то запустив мы увидим белый прямоугольник на голубом фоне.&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Кстати советую spriteBatch.Begin написать &amp;nbsp;именно так как описано выше, т.к иначе шейдер может не сработать.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Наконец можно приступить к написанию шейдера =)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Добавляем к Content новый шейдер (Effect file). Студия автоматически создаст шаблон шейдера, однако мы далее его переделаем, т.к он содержит много лишнего.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Далее добавим переменную в класс Game -&amp;nbsp;Effect effect;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Загружаем шейдер в LoadContent&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;effect = Content.Load&lt;effect&gt;("gradient");&lt;/effect&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;И переписываем процедуру рисования:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;protected override void Draw(GameTime gameTime)&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;GraphicsDevice.Clear(Color.CornflowerBlue);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.SaveState);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;effect.Begin();&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;foreach (EffectPass pass in effect.Techniques[0].Passes)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;pass.Begin();&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;spriteBatch.Draw(texture,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;new Rectangle(0, 0,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;400, 300), Color.White);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt; &amp;nbsp;pass.End();&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;effect.End();&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;spriteBatch.End();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;base.Draw(gameTime);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Теперь не спешите запускать проект. Последний мазок - переписываем шейдер:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;sampler ColorMapSampler : register(s0);&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;&lt;br /&gt;
&lt;/b&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;// Grayscale&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;{&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;return float4(1,0,0,1);&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;}&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;technique PostProcess&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;pass P0&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;PixelShader = compile ps_2_0 PixelShader();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Здесь я удалил вершинный шейдер и лишние переменные. Для простоты оставил только пиксельный. Теперь если запустить проект то должен получится красный квадратик&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_U9jxq5NwSC4/TELKF6DP7vI/AAAAAAAADpY/634rdyOnmGk/s1600/%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="249" src="http://4.bp.blogspot.com/_U9jxq5NwSC4/TELKF6DP7vI/AAAAAAAADpY/634rdyOnmGk/s320/%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Не очень впечатляет, но это ведь только начало ;)&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Давайте посмотрим ближе на шейдер. Шейдер - это программа которая выполняется на видеоадаптере компьютера. Как известно видеоадаптер в разы быстрее обрабатывает информацию, поэтому шейдеры так удобны. Существуют различные виды шейдеров:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Пиксельный&lt;/li&gt;
&lt;li&gt;Вершинный&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Пиксельный обрабатывает пиксели,а вершинный соотвественно вершины. Так вот у нас пиксельный. На вход мы получаем текстурные координаты пикселя ( его положение в пространстве). Они изменяется от [0..1]. А на выход пиксельный шейдер ( по сути это функция) должна возвращать float4 - вектор из 4 компонент, который указывает выходной цвет пикселя.&lt;/div&gt;&lt;div&gt;В нашем шейдере мы всем пикселям указали цвет (1,0,0,1), т.е красный по цветовой модели RGBA.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Теперь давайте поиграемся с текстурными координатами. Попробуем визуализировать их. И перепишем строчку возвращения цвета в шейдере как:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;return float4(Tex.x,Tex.y,0,1);&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_U9jxq5NwSC4/TELLie1VgxI/AAAAAAAADpc/DeRBt-lprRk/s1600/%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="249" src="http://3.bp.blogspot.com/_U9jxq5NwSC4/TELLie1VgxI/AAAAAAAADpc/DeRBt-lprRk/s320/%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div&gt;Помойму смотрится уже лучше =) Как видим там где x текстурная координата ближе к 1 мы видим больше красного,а где ближе к 1 y координата больше зелёного. Что в принципе и должен был делать наш шейдер.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Давайте двигаться дальше. Конечной целью статьи было написание градиентной круговой заливки. В качестве параметров заливка должна иметь:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Радиус градиента&lt;/li&gt;
&lt;li&gt;Центр градиента&lt;/li&gt;
&lt;li&gt;Начальный и конечный цвет&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;Итак, начнём:&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float2 Center=float2(0.5f,0.5f);&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float &amp;nbsp;Radius=0.2f;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float4 start=(1,0,0,1);&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float4 end=(0,1,0,1);&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float dist=distance(Center,Tex);&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;return float4(dist,0,0,1);&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Мы добавили в шейдер переменные центра, радиуса, начального и конечного цвета градиента. Кроме того здесь мы вычисляем с помощью встроенной функции в HLSL расстояние между центром и текстурными координатами пикселя. А далее мы расстояние визуализируем. Получаем:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_U9jxq5NwSC4/TELNQ6XrHiI/AAAAAAAADpg/l2AlIkU_PHE/s1600/%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="249" src="http://4.bp.blogspot.com/_U9jxq5NwSC4/TELNQ6XrHiI/AAAAAAAADpg/l2AlIkU_PHE/s320/%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Получили красный градиент с центром в (0.5,0.5). Нам однако всё ещё нужно чтобы были начальные и конечные цвета,а также радиус градиента. Поэтому переписываем шейдер:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;float2 Center=float2(0.5f,0.5f);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;float &amp;nbsp;Radius=0.6f;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;float4 start=float4(0,0,1,1);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;float4 end=float4(0,1,0,1);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float dist=min(1,distance(Center,Tex)/Radius);&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float4 realcolor=smoothstep(start,end,dist);&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt; &lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;return realcolor;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Теперь помедленней:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;distance - возвращает float - расстояние между двумя векторами&lt;/li&gt;
&lt;li&gt;smoothstep - делает переход на основе 3-го параметра между двумя векторами. В данном случае это делает переход из одного цвета в другой.&lt;/li&gt;
&lt;li&gt;min - функция минимума&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Теперь если запустим всё будет по честному, только одно но... Хочется все параметры задавать из программы. Поэтому можете запускать посмотреть результат... а я дальше пойду. Опять переписываем шейдер:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float2 Center;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float &amp;nbsp;Radius;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float4 start;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;float4 end;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;float4 PixelShader(float2 Tex: TEXCOORD0) : COLOR&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;float dist=min(1,distance(Center,Tex)/Radius);&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;float4 realcolor=smoothstep(start,end,dist);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;return realcolor;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;И также переписываем метод рисования:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;div&gt;spriteBatch.Begin(SpriteBlendMode.None, SpriteSortMode.Immediate, SaveStateMode.SaveState);&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;b&gt;effect.Parameters["Radius"].SetValue(0.9f);&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;effect.Parameters["Center"].SetValue(new Vector2(0.5f, 0.5f));&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;effect.Parameters["start"].SetValue(Color.White.ToVector4());&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;effect.Parameters["end"].SetValue(Color.Red.ToVector4());&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;effect.CommitChanges();&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;effect.Begin();&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Что получилось?&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_U9jxq5NwSC4/TELTeRfd1jI/AAAAAAAADpk/XjycSKDXFa4/s1600/%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="249" src="http://1.bp.blogspot.com/_U9jxq5NwSC4/TELTeRfd1jI/AAAAAAAADpk/XjycSKDXFa4/s320/%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA.PNG" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;Довольно симпатично. Что поменялось? Мы вынесли переменные из функции шейдера, таким образом сделали их глобальными параметрами шейдера. А в процедуре рисования мы присваивали им значения. Таким образом шейдер управляется из программы.&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;На этом пока что всё. Статья получилось немного длинная, но надеюсь суть ясна. Исходники можно скачать по адресу:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;a href="https://docs.google.com/leaf?id=0B6h7yaggRA4pZGIzNzU1NzMtZWY1MC00MWMzLTk4NDMtNjE5ZWNiN2ZhMmMw&amp;amp;hl=en"&gt;https://docs.google.com/leaf?id=0B6h7yaggRA4pZGIzNzU1NzMtZWY1MC00MWMzLTk4NDMtNjE5ZWNiN2ZhMmMw&amp;amp;hl=en&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;a href="http://sites.google.com/site/jackdevolpment/files/shadertest.7z?attredirects=0&amp;amp;d=1"&gt;http://sites.google.com/site/jackdevolpment/files/shadertest.7z?attredirects=0&amp;amp;d=1&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-2574134415582491421?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/XJlshN2tVeZDO2cdzrYgJPJ7CiM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XJlshN2tVeZDO2cdzrYgJPJ7CiM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/XJlshN2tVeZDO2cdzrYgJPJ7CiM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/XJlshN2tVeZDO2cdzrYgJPJ7CiM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/WsIqjYhN2ic" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/2574134415582491421/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/07/hlsl.html#comment-form" title="Комментарии: 1" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/2574134415582491421?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/2574134415582491421?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/WsIqjYhN2ic/hlsl.html" title="HLSL шейдеры для чайников" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_U9jxq5NwSC4/TELKF6DP7vI/AAAAAAAADpY/634rdyOnmGk/s72-c/%D0%A1%D0%BD%D0%B8%D0%BC%D0%BE%D0%BA.PNG" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/07/hlsl.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0MER3o-eCp7ImA9WxFaEk4.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-8009769942777604593</id><published>2010-07-16T01:03:00.000+03:00</published><updated>2010-07-16T01:03:26.450+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-16T01:03:26.450+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gamedev" /><category scheme="http://www.blogger.com/atom/ns#" term="XNA" /><title>Cycloid. Новости</title><content type="html">Рад сообщить что разработка игры под XNA идёт полным ходом. Почти все&amp;nbsp;предполагаемые&amp;nbsp;фичи реализованы, так что работа переходит в стадию тестирования и допиливания.&lt;br /&gt;
&lt;br /&gt;
Кроме того я договорился с художником о создании оформления для игры. Конечно переоформление&amp;nbsp;займет&amp;nbsp;некоторое время, но оно того стоит. Могу только сказать что предварительные эскизы я уже видел и выглядит всё это очень даже неплохо.&lt;br /&gt;
&lt;br /&gt;
К сожалению бинарников и эскизов показать не могу, и в&amp;nbsp;ближайшем&amp;nbsp;времени их&amp;nbsp;вряд ли&amp;nbsp;кто то&amp;nbsp;увидит. Buissness is buissness.&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-8009769942777604593?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/usLoKpvxkavIRPvucCoCZSpa01g/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/usLoKpvxkavIRPvucCoCZSpa01g/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/usLoKpvxkavIRPvucCoCZSpa01g/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/usLoKpvxkavIRPvucCoCZSpa01g/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/jlaDtO3CSEE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/8009769942777604593/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/07/cycloid.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/8009769942777604593?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/8009769942777604593?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/jlaDtO3CSEE/cycloid.html" title="Cycloid. Новости" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/07/cycloid.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08GQnc8fyp7ImA9WxFbGE4.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-554244853485578332</id><published>2010-07-11T11:10:00.000+03:00</published><updated>2010-07-11T11:10:23.977+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-11T11:10:23.977+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="gamedev" /><category scheme="http://www.blogger.com/atom/ns#" term="XNA" /><title>Farseer Physics и XNA</title><content type="html">Решил переделать свой арканоид и вместо собственной физики использовать 2D физический движок&lt;b&gt; Farseer Physics&lt;/b&gt;. Это наиболее распространённый физический движок для &lt;b&gt;C#&lt;/b&gt; ( в частности под &lt;b&gt;XNA&lt;/b&gt;). Подключить был довольно просто - в комплекте идёт готовый пример использования, однако сразу столкнулся с первыми трудностями.&lt;br /&gt;
&lt;br /&gt;
Основная проблема с которой я столкнулся - это появление исключения &lt;b&gt;ArithmeticException&lt;/b&gt; в методе вычисления угловой скорости (&lt;b&gt;AngularVelocity&lt;/b&gt;). Что самое обидное было - это то, что исключения возникало не сразу, а в процессе игры. Долгие поиски причины не привели к решению проблемы, однако путём тыка ( самый действенный метод ) ошибка была устранена.&lt;br /&gt;
&lt;br /&gt;
Причиной такого поведения был факт того, что я не устанавливал &lt;b&gt;MomentOfInertia&lt;/b&gt; для создаваемых тел. В результате данный параметр вычислялся автоматически движком и очевидно его значение превышало возможности движка. В результате я выставил вручную данный параметр в 1 и ошибка больше не появлялась. Данный параметр показывает насколько будет закручиваться обьект при ударении с другим обьектом. Для моей игры этот параметр не является существенным и поэтому я не сильно заботился его правильным значением.&lt;br /&gt;
&lt;br /&gt;
В общем данный движок довольно удобный. В комплект входит визуализатор физики - он конкретно упрощает жизнь в процессе дебага. Кроме того движок постоянно развивается - на данный момент стабильная версия 2.1.3, но уже в ближайщем будующем обещают появление 3-й версии движка с новыми плюшками и фишками.&lt;br /&gt;
&lt;br /&gt;
Так что если нужна физика для Silverlight, XNA или WPF - рекомендую&amp;nbsp;&lt;a href="http://farseerphysics.codeplex.com/"&gt;http://farseerphysics.codeplex.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-554244853485578332?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TENo3hwCWdKuLCc1wV5CMsdtnkY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TENo3hwCWdKuLCc1wV5CMsdtnkY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TENo3hwCWdKuLCc1wV5CMsdtnkY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TENo3hwCWdKuLCc1wV5CMsdtnkY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/eAAgCpsdRDg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/554244853485578332/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/07/farseer-physics-xna.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/554244853485578332?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/554244853485578332?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/eAAgCpsdRDg/farseer-physics-xna.html" title="Farseer Physics и XNA" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/07/farseer-physics-xna.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU8MSXcyeyp7ImA9WxFUE0w.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-8944810300555649700</id><published>2010-06-23T20:24:00.002+03:00</published><updated>2010-06-23T20:24:48.993+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-23T20:24:48.993+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="универ" /><title /><content type="html">3 по ГОСам и 5 по диплому... такое вообще бывает?)&lt;br /&gt;
Чтож, в любом случае я закончил 4-й курс и теперь я бакалавр!&lt;br /&gt;
Осталось месяц чтобы дописать диплом в Шаге - время пошло! :)&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-8944810300555649700?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6yWk86VnM4Q0syGqixC7HkgiRjA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6yWk86VnM4Q0syGqixC7HkgiRjA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6yWk86VnM4Q0syGqixC7HkgiRjA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6yWk86VnM4Q0syGqixC7HkgiRjA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/cVsIQ3sRcfE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/8944810300555649700/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/06/3-5.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/8944810300555649700?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/8944810300555649700?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/cVsIQ3sRcfE/3-5.html" title="" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/06/3-5.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQDQHk7eyp7ImA9WxFQF0U.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-4757426154732714718</id><published>2010-05-13T22:24:00.008+03:00</published><updated>2010-05-13T23:26:11.703+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-13T23:26:11.703+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="универ" /><category scheme="http://www.blogger.com/atom/ns#" term="gamedev" /><category scheme="http://www.blogger.com/atom/ns#" term="XNA" /><title>XNA - продолжая тему диплома</title><content type="html">Итак.... Я не знаю говорил ли я что я пишу 2 диплома? Если нет то теперь вы знаете.&lt;br /&gt;Один в универе и один в Шаг. Довольно весёлое занятие - попеременно забивать болт то на один, то на другой....&lt;br /&gt;&lt;br /&gt;Сегодня я хочу написать о том что у меня получается с Шаговским дипломом. В Шаге я занимаюсь разработкой игры под платформу XNA. В качестве игры я решил переделать стандартную под iPod игру - Vortex. Это аналог арканоида, с отличием в том, что бита движется по кругу,и задача игрока не выпустить мяч за пределы круга.&lt;br /&gt;&lt;br /&gt;Собственно первая часть работы - организовать процесс игры, движение шарика и биты. Она у меня прошла довольно гладко. &lt;br /&gt;&lt;br /&gt;И вот сейчас я решил взяться за вторую - рефакторинг, организация игрового движка и наконец использования шейдеров. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Небольшой тизер :)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_U9jxq5NwSC4/S-xUKzPGeDI/AAAAAAAADkM/QSJ1KaByr14/s1600/teaser.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 349px;" src="http://4.bp.blogspot.com/_U9jxq5NwSC4/S-xUKzPGeDI/AAAAAAAADkM/QSJ1KaByr14/s400/teaser.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5470840191877281842" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Основной идеей рефакторинга было создание классов для разделения функций между движком и логикой игры.&lt;br /&gt;&lt;br /&gt;Т.к игра двумерная я создал классы спрайтов,на основе которых позже создал классы анимированных спрайтов и анимаций.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Краткая диаграмма классов игры&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_U9jxq5NwSC4/S-xWOiMpA9I/AAAAAAAADkU/PF5SuwQVpO4/s1600/classes.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 373px;" src="http://2.bp.blogspot.com/_U9jxq5NwSC4/S-xWOiMpA9I/AAAAAAAADkU/PF5SuwQVpO4/s400/classes.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5470842455046292434" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;GameView &lt;/span&gt;- класс состояния игры. Т.к игра фактически состоит из дискретных состояний, то я решил написать класс StateManager который управляет состояниями. И каждый раз вызывая метод StateManager.SetView мы меняем состояние игры. Это очень удобно, т.к отдаёт большую часть работы относительно игровой логики и рисования реализациям состояний. Подобный подход не новый и используется почти во всех игровых движках в разных ипостасях.&lt;br /&gt;&lt;br /&gt;В результате после выделения состояний я очень удобно прикрутил шейдер  &lt;a target="_blank" href="http://digierr.spaces.live.com/blog/cns!2B7007E9EC2AE37B!667.entry?wa=wsignin1.0&amp;sa=599119843"&gt;Transition&lt;/a&gt; который делает слайдовый переход. Получилась очень достойная анимация смены состояний.&lt;br /&gt;&lt;br /&gt;Что касается спрайтов то - это типичное решение для помойму всех двумерных игровых движков. Скажу только что AnimatedSprite - это спрайт с нескольким числом состояний и нужен в игре чтобы отображать кирпичи ( разбитые и не разбитые)&lt;br /&gt;&lt;br /&gt;Что ещё буду делать:&lt;br /&gt;- Подсчёт очков за разбитые кирпичи,комбо&lt;br /&gt;- Пост-обработка шейдерами при попадании на кирпичи&lt;br /&gt;- При закрытии игры процесс остаётся в памяти - нужно пофиксить.&lt;br /&gt;- Иногда(довольно редко) некорректно отбивается шарик от биты или от кирпичей&lt;br /&gt;&lt;br /&gt;Вообщем не буду томить и кидаю ссылку на сборку игрушки. Пока что только 1 уровень и нету очков - но всё впереди ( я просто решил похвастатся )))&lt;br /&gt;&lt;br /&gt;Google docs:&lt;br /&gt;&lt;a href="https://docs.google.com/leaf?id=0B6h7yaggRA4pZGRjZGNlNzktYjBmNS00M2RjLWExNWYtY2I2NWY4NzhhMDli&amp;hl=en"&gt;https://docs.google.com/leaf?id=0B6h7yaggRA4pZGRjZGNlNzktYjBmNS00M2RjLWExNWYtY2I2NWY4NzhhMDli&amp;hl=en&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Google sites:&lt;br /&gt;&lt;a href="http://sites.google.com/site/jackdevolpment/files/Release.7z?attredirects=0&amp;d=1"&gt;http://sites.google.com/site/jackdevolpment/files/Release.7z?attredirects=0&amp;d=1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight:bold;"&gt;Faq:&lt;/span&gt;&lt;br /&gt;1.Для запуска необходима XNA 3.1 &lt;a target="_blank" href="http://www.microsoft.com/downloads/details.aspx?FamilyID=53867a2a-e249-4560-8011-98eb3e799ef2&amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=53867a2a-e249-4560-8011-98eb3e799ef2&amp;displaylang=en&lt;/a&gt; &lt;br /&gt;2.Пасхальные яйца - F1,F2,F3,F4 во время игры&lt;br /&gt;3.Если что-то не работает - отписываемся :)&lt;br /&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-4757426154732714718?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/1S2ST1kR_VFkpccAQU-MwiK7jts/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1S2ST1kR_VFkpccAQU-MwiK7jts/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/1S2ST1kR_VFkpccAQU-MwiK7jts/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/1S2ST1kR_VFkpccAQU-MwiK7jts/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/mXgesSSEl_Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/4757426154732714718/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/05/xna.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/4757426154732714718?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/4757426154732714718?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/mXgesSSEl_Y/xna.html" title="XNA - продолжая тему диплома" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_U9jxq5NwSC4/S-xUKzPGeDI/AAAAAAAADkM/QSJ1KaByr14/s72-c/teaser.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/05/xna.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8EQ3YyfSp7ImA9WxFQF0U.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-1582951841576023060</id><published>2010-04-25T00:34:00.008+03:00</published><updated>2010-05-14T00:06:42.895+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-14T00:06:42.895+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="универ" /><title>Севастополь. Информатика-2010</title><content type="html">Завтра уезжаю в Севастополь. Посмотрю город и заодно буду участвовать в конференции.&lt;br /&gt;Обожаю ехать куда то, особенно за казённый счёт. &lt;br /&gt;&lt;br /&gt;Как говорится на шару и уксус сладкий.&lt;br /&gt;&lt;br /&gt;Update:&lt;br /&gt;Фотоотчёт можно найти на &lt;br /&gt;&lt;a href="http://picasaweb.google.com/jack.spektor/DuYLZ?feat=directlink"&gt;http://picasaweb.google.com/jack.spektor/DuYLZ?feat=directlink&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align:center"&gt;&lt;br /&gt;&lt;embed type="application/x-shockwave-flash" src="http://picasaweb.google.com/s/c/bin/slideshow.swf" width="400" height="267" flashvars="host=picasaweb.google.com&amp;hl=ru&amp;feat=flashalbum&amp;RGB=0x000000&amp;feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2Fjack.spektor%2Falbumid%2F5465824991505444689%3Falt%3Drss%26kind%3Dphoto%26hl%3Dru" pluginspage="http://www.macromedia.com/go/getflashplayer"&gt;&lt;/embed&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-1582951841576023060?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gA_IgyOCfO3fFsikRckXRoYTTKM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gA_IgyOCfO3fFsikRckXRoYTTKM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gA_IgyOCfO3fFsikRckXRoYTTKM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gA_IgyOCfO3fFsikRckXRoYTTKM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/EzYu9MdK1xw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/1582951841576023060/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/04/blog-post.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/1582951841576023060?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/1582951841576023060?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/EzYu9MdK1xw/blog-post.html" title="Севастополь. Информатика-2010" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/04/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUNSH8_eSp7ImA9WxBbFkQ.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-7980804836772019040</id><published>2010-03-15T23:35:00.007+02:00</published><updated>2010-03-15T23:58:19.141+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-15T23:58:19.141+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="fun" /><category scheme="http://www.blogger.com/atom/ns#" term="gadget" /><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Наваял гаджет</title><content type="html">Чтото меня потянуло на гаджеты. Решил сделать небольшой гаджет для души.&lt;br /&gt;Смысл - жмём на кнопку и снизу вылетают воздушные шарики.&lt;br /&gt;Долго мучался с COM регистрацией и вызовом, но слава яйцам всё получилось.&lt;br /&gt;&lt;br /&gt;Встречайте - &lt;span style="font-weight:bold;"&gt;Bubble gadget&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_U9jxq5NwSC4/S56pllcv2jI/AAAAAAAAC64/xKkj1EmC4QY/s1600-h/screen.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 250px;" src="http://2.bp.blogspot.com/_U9jxq5NwSC4/S56pllcv2jI/AAAAAAAAC64/xKkj1EmC4QY/s400/screen.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5448979062337821234" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/leaf?id=0B6h7yaggRA4pYzI3Mjc1OGEtNWYzNy00ZThlLWIwMzAtNWU4ZmJhYTdmYzJk&amp;hl=en"&gt;https://docs.google.com/leaf?id=0B6h7yaggRA4pYzI3Mjc1OGEtNWYzNy00ZThlLWIwMzAtNWU4ZmJhYTdmYzJk&amp;hl=en&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Альтернативная ссылка на загрузку:&lt;br /&gt;&lt;a href="http://sites.google.com/site/jackdevolpment/files/gadget.gadget?attredirects=0&amp;d=1"&gt;http://sites.google.com/site/jackdevolpment/files/gadget.gadget?attredirects=0&amp;d=1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Более подробно о том как это всё было и какие мне встретились проблемы напишу позже. Сейчас спать.&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-7980804836772019040?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/JgR5UCH6ut40ic6pUoFGKR4lYrw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JgR5UCH6ut40ic6pUoFGKR4lYrw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/JgR5UCH6ut40ic6pUoFGKR4lYrw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/JgR5UCH6ut40ic6pUoFGKR4lYrw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/s66dEGiRUEo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/7980804836772019040/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/03/blog-post_15.html#comment-form" title="Комментарии: 5" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/7980804836772019040?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/7980804836772019040?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/s66dEGiRUEo/blog-post_15.html" title="Наваял гаджет" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_U9jxq5NwSC4/S56pllcv2jI/AAAAAAAAC64/xKkj1EmC4QY/s72-c/screen.png" height="72" width="72" /><thr:total>5</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/03/blog-post_15.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkYCSHg-cCp7ImA9WxBbFEo.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-6127673807004439473</id><published>2010-03-13T11:45:00.005+02:00</published><updated>2010-03-13T11:56:09.658+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-13T11:56:09.658+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="iTunes" /><title>Играемся с iTunes через Javascript</title><content type="html">Довольно классна штука - этот айТюнс. И плеер хороший, и подкасты качает и вообще красавец. Ладна, к чему это я? Случайно узнал, что оказывается у него есть API. Работает через COM и позволяет получить полный доступ к функционалу плеера. &lt;br /&gt;&lt;br /&gt;Так что например вот такой нехитрый Javascript код &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;iTunesApp = new ActiveXObject("iTunes.Application"); &lt;br /&gt;iTunesApp.NextTrack();&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;поменяет песню в плеере на следующую, а вот например&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;var iTunesApp = new ActiveXObject("iTunes.Application"); &lt;br /&gt;var currentTrackName=iTunesApp.CurrentTrack.Name;&lt;br /&gt;var currentArtist=iTunesApp.CurrentTrack.Artist;&lt;br /&gt;alert(currentArtist+" - "+currentTrackName);&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;покажет название текущей песни. У меня это например сейчас &lt;span style="font-style:italic;"&gt;"Vampire Weekend - Oxford Comma"&lt;/span&gt;. Вот такие пироги. Кстати чуть не забыл - вся это красота работает только в случае Internet Explorer. Так что имейте ввиду :)&lt;br /&gt;&lt;br /&gt;Думаю как будет скучно - сделать парочку гаджетов для рабочего стола, чтобы управлял плеером,показывал текущую песню, плейлист и т.д :)&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-6127673807004439473?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/KPZlEYQ8Ln6xgC2slc-5tU5hYH8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KPZlEYQ8Ln6xgC2slc-5tU5hYH8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/KPZlEYQ8Ln6xgC2slc-5tU5hYH8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/KPZlEYQ8Ln6xgC2slc-5tU5hYH8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/2R3M002f-9I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/6127673807004439473/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/03/itunes-javascript.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/6127673807004439473?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/6127673807004439473?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/2R3M002f-9I/itunes-javascript.html" title="Играемся с iTunes через Javascript" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/03/itunes-javascript.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0ENQXg-fCp7ImA9WxBbE0w.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-2912779572556518653</id><published>2010-03-11T16:53:00.003+02:00</published><updated>2010-03-11T17:01:30.654+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-11T17:01:30.654+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="универ" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><category scheme="http://www.blogger.com/atom/ns#" term="gamedev" /><title>Диплом. Черновик 3D рендера. Java</title><content type="html">Диплом в самом разгаре... Я не сильно писал чем я занимаюсь в рамках диплома. А занимаюсь я проблемой параллельных вычислений. А именно - системой распаралеливания алгоритмов.Так уж сложилось что занимаюсь именно этой темой, а точнее продолжаю работу студента Виктора Бурдейного. &lt;br /&gt;&lt;br /&gt;Написал небольшой черновик 3D рисования на Java - думаю внедрить поддержки 3Д визуализации в систему - это даст возможность рисовать графики, которые будут упрощать понимание результатов работы алгоритма на кластере.&lt;br /&gt;&lt;br /&gt;В принципе я уже сделал визуализацию в 2Д для фреймворка, но алгоритм, который необходимо реализовать должен будет рисовать поверхность в 3Д, так что приходится разбиратся с 3Д костылями для Джавы. Вот такие пироги.&lt;br /&gt;&lt;br /&gt;Java Opengl (использует JOGL)&lt;br /&gt;&lt;a href="https://docs.google.com/leaf?id=0B6h7yaggRA4pZGVmMDMyYmMtZTYyYi00NmE1LWI2YjQtM2E4OGRhNWI2OGI1&amp;hl=en"&gt;https://docs.google.com/leaf?id=0B6h7yaggRA4pZGVmMDMyYmMtZTYyYi00NmE1LWI2YjQtM2E4OGRhNWI2OGI1&amp;hl=en&lt;br /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-2912779572556518653?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/PuoOs1kASJyHtjQPs2qfRISw9mg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PuoOs1kASJyHtjQPs2qfRISw9mg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/PuoOs1kASJyHtjQPs2qfRISw9mg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/PuoOs1kASJyHtjQPs2qfRISw9mg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/boDlmRfNvGg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/2912779572556518653/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/03/3d-java.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/2912779572556518653?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/2912779572556518653?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/boDlmRfNvGg/3d-java.html" title="Диплом. Черновик 3D рендера. Java" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/03/3d-java.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0AESXszcCp7ImA9WxBbE0w.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-3804053407638116875</id><published>2010-03-05T20:51:00.004+02:00</published><updated>2010-03-11T17:01:48.588+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-11T17:01:48.588+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="fun" /><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Сплошная случайность</title><content type="html">Сегодня по почте случайно зашёл в папку спам.&lt;br /&gt;И там увидел письмо от некой Ирины, которая случайно меня нашла на случайном форуме и просит помочь ей с Дельфи. А конкретнее - помочь с сокетами (она хотела написать клиент-серверное рендзю). И случайно я вспомнил что писал именно подобное рендзю совсем давно, ещё тогда когда писал на Дельфи.&lt;br /&gt;&lt;br /&gt;Вот такая сплошная случайность. Забавно.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://docs.google.com/leaf?id=0B6h7yaggRA4pYmZkNWVhMzYtOTUwMC00YjMzLWJlYTItMTA3N2QzZGY5ZDEw&amp;hl=en"&gt;https://docs.google.com/leaf?id=0B6h7yaggRA4pYmZkNWVhMzYtOTUwMC00YjMzLWJlYTItMTA3N2QzZGY5ZDEw&amp;hl=en&lt;/a&gt; - для любопытных собственно само рендзю :)&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-3804053407638116875?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/OLWuU8-RCZJgdEtXEii_jMLkvF0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OLWuU8-RCZJgdEtXEii_jMLkvF0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/OLWuU8-RCZJgdEtXEii_jMLkvF0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/OLWuU8-RCZJgdEtXEii_jMLkvF0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/Nm6XogWmewI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/3804053407638116875/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/03/blog-post.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/3804053407638116875?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/3804053407638116875?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/Nm6XogWmewI/blog-post.html" title="Сплошная случайность" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/03/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0AARnY6eSp7ImA9WxBbE0w.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-8948676665532830718</id><published>2010-01-27T20:49:00.004+02:00</published><updated>2010-03-11T17:02:27.811+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-11T17:02:27.811+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="универ" /><category scheme="http://www.blogger.com/atom/ns#" term="Java" /><title>Взлом алгоритма Эль-Гамаль( с помощью алгоритма Шенкса) или ещё немного университетской фигни :)</title><content type="html">Данное задание мне выдавали по предмету криптология. Наверно один из немногих предметов, который мне кажется реально полезным и интересным. 
&lt;br /&gt;
&lt;br /&gt;Реализовывал на Java т.к боялся что числа выйдут за пределы стандартных типов данных, а  в Java для этого есть удобный тип данных BigInteger. Такто.
&lt;br /&gt;
&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Итак условие:&lt;/span&gt;
&lt;br /&gt;В следующих задачах зашифрован алгоритмом ЭльГамала текст, написанный на английском языке. Использован следующий алфавит: 
&lt;br /&gt;"A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z| |,|.|". 
&lt;br /&gt;Блок "подсказки" расположен в начале криптотекста и является общим для всех его блоков. Его длина считается неизвестной. Найти секретный ключ и расшифровать текст. 
&lt;br /&gt;
&lt;br /&gt;"5148154611033774886049492438294008383372872853501067660147906401592062201450665781876473"
&lt;br /&gt;
&lt;br /&gt;Открытый ключ: p=89981741 g=2 h=76976449
&lt;br /&gt;
&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Часть первая - решение задачи целочисленного логарифмирования ( поиск секретного ключа a)&lt;/span&gt;
&lt;br /&gt;На вход подаётся p,g,h
&lt;br /&gt;
&lt;br /&gt;&lt;blockquote&gt;package Shenks;
&lt;br /&gt;
&lt;br /&gt;import java.math.BigInteger;
&lt;br /&gt;import java.util.Hashtable;
&lt;br /&gt;import java.util.Iterator;
&lt;br /&gt;import java.util.Map.Entry;
&lt;br /&gt;
&lt;br /&gt;public final class Program {
&lt;br /&gt;
&lt;br /&gt;    /**
&lt;br /&gt;     * @param args
&lt;br /&gt;     */
&lt;br /&gt;    public static void main(String[] args) {
&lt;br /&gt;        
&lt;br /&gt;        if(args.length==3)
&lt;br /&gt;        {
&lt;br /&gt;        // TODO Auto-generated method stub
&lt;br /&gt;        System.out.println("y=a^x(mod n) x-?");
&lt;br /&gt;
&lt;br /&gt;        System.out.println("y= "+args[0]);
&lt;br /&gt;        BigInteger y=new BigInteger(args[0]);
&lt;br /&gt;        
&lt;br /&gt;        System.out.println("a= "+args[1]);
&lt;br /&gt;        BigInteger a=new BigInteger(args[1]);
&lt;br /&gt;
&lt;br /&gt;        
&lt;br /&gt;        System.out.println("n= "+args[2]);
&lt;br /&gt;        Integer n=new Integer(args[2]);
&lt;br /&gt;        
&lt;br /&gt;        Shanks(y, a, n);
&lt;br /&gt;        
&lt;br /&gt;        }else
&lt;br /&gt;        {
&lt;br /&gt;        System.out.println("Expecting 3 arguments to run");
&lt;br /&gt;        }
&lt;br /&gt;    }
&lt;br /&gt;    
&lt;br /&gt;    public static int Shanks(BigInteger y,BigInteger a,int n)
&lt;br /&gt;    { 
&lt;br /&gt;        
&lt;br /&gt;        Hashtable&lt;Integer,BigInteger&gt; babySteps=new Hashtable&lt;Integer, BigInteger&gt;();
&lt;br /&gt;        Hashtable&lt;Integer,BigInteger&gt; giantSteps=new Hashtable&lt;Integer, BigInteger&gt;();
&lt;br /&gt;        // TODO: Prepare
&lt;br /&gt;        int result=0;
&lt;br /&gt;        
&lt;br /&gt;        int s=(int)Math.floor((( Math.sqrt(n))));
&lt;br /&gt;        
&lt;br /&gt;        BigInteger N=BigInteger.valueOf(n);
&lt;br /&gt;        
&lt;br /&gt;        System.out.print("s=");
&lt;br /&gt;        System.out.println(s);
&lt;br /&gt;        
&lt;br /&gt;        
&lt;br /&gt;        
&lt;br /&gt;        // TODO: Do baby step
&lt;br /&gt;        System.out.println("Starting baby steps,baby!:)");
&lt;br /&gt;        BigInteger temp=y;
&lt;br /&gt;        for(int i=0;i&lt;s;i++)
&lt;br /&gt;        {
&lt;br /&gt;            BigInteger value=temp.mod(N);
&lt;br /&gt;            babySteps.put(i, value);
&lt;br /&gt;            temp=temp.multiply(a);
&lt;br /&gt;            //System.out.println(
&lt;br /&gt;                //    String.format("%d\\%d %s", i,s,value.toString()));
&lt;br /&gt;        }        
&lt;br /&gt;        
&lt;br /&gt;        
&lt;br /&gt;        // TODO: Do Giant steps
&lt;br /&gt;        System.out.println("Starting giant steps,oh my god!!!:)");
&lt;br /&gt;//        temp=a;
&lt;br /&gt;//        temp=temp.pow(s);
&lt;br /&gt;//        BigInteger temp2=temp;
&lt;br /&gt;        for(int i=0;i&lt;s;i++)
&lt;br /&gt;        {
&lt;br /&gt;            //System.out.println(temp2.toString());
&lt;br /&gt;            temp=a.modPow(BigInteger.valueOf(s*(i+1)), N);
&lt;br /&gt;            //BigInteger value=temp;
&lt;br /&gt;            giantSteps.put((i+1)*s,temp);
&lt;br /&gt;            
&lt;br /&gt;            //temp2=temp2.multiply(temp);
&lt;br /&gt;            //System.out.println(
&lt;br /&gt;            //        String.format("%d\\%d %s", i,s,temp.toString()));
&lt;br /&gt;        }
&lt;br /&gt;        
&lt;br /&gt;        //TODO:Check giant and baby
&lt;br /&gt;        System.out.println("Comparing giant steps and baby steps");        
&lt;br /&gt;        
&lt;br /&gt;        Iterator&lt;Entry&lt;Integer,BigInteger&gt;&gt; set1=babySteps.entrySet().iterator();
&lt;br /&gt;        
&lt;br /&gt;        Boolean loop=true;
&lt;br /&gt;        int loopN=0;
&lt;br /&gt;        while(set1.hasNext()&amp;&amp; loop)
&lt;br /&gt;        {
&lt;br /&gt;            Entry&lt;Integer,BigInteger&gt; entry1=set1.next();
&lt;br /&gt;            Iterator&lt;Entry&lt;Integer,BigInteger&gt;&gt; set2=giantSteps.entrySet().iterator();
&lt;br /&gt;            //System.out.println(
&lt;br /&gt;                //    String.format("Loop %d\\%d", loopN,s)
&lt;br /&gt;                    //);
&lt;br /&gt;            while(set2.hasNext() &amp;&amp; loop)
&lt;br /&gt;            {
&lt;br /&gt;                
&lt;br /&gt;                Entry&lt;Integer,BigInteger&gt; entry2=set2.next();
&lt;br /&gt;                //BigInteger value1=entry1.getValue();
&lt;br /&gt;                //BigInteger value2=entry2.getValue();
&lt;br /&gt;                //System.out.println(
&lt;br /&gt;                //        String.format("%s - %s", value1,value2));
&lt;br /&gt;                if(entry1.getValue().equals(entry2.getValue()))
&lt;br /&gt;                {
&lt;br /&gt;                    System.out.print("Entry found:");
&lt;br /&gt;                    //System.out.println(
&lt;br /&gt;                            //String.format("r=%d st=%d", entry1.getKey(),entry2.getKey()));
&lt;br /&gt;                    result=entry2.getKey()-entry1.getKey();
&lt;br /&gt;                    System.out.println(result);
&lt;br /&gt;                    loop=false;
&lt;br /&gt;                }
&lt;br /&gt;            }
&lt;br /&gt;            loopN++;
&lt;br /&gt;        }
&lt;br /&gt;        
&lt;br /&gt;        
&lt;br /&gt;        //TODO:Testing
&lt;br /&gt;        System.out.print("Test:");
&lt;br /&gt;        if(y.equals(a.modPow(BigInteger.valueOf(result),BigInteger.valueOf(n))))
&lt;br /&gt;            System.out.println("OK");
&lt;br /&gt;        
&lt;br /&gt;        return result;
&lt;br /&gt;    }
&lt;br /&gt;}&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Часть вторая - дешифрация&lt;/span&gt;
&lt;br /&gt;На вход подаётся найденный пароль, Р, с1, и остальные ci
&lt;br /&gt;c1 - это первые 8 цифр из зашифрованного сообщения.
&lt;br /&gt;
&lt;br /&gt;&lt;blockquote&gt;package Shenks;
&lt;br /&gt;
&lt;br /&gt;import java.math.BigInteger;
&lt;br /&gt;
&lt;br /&gt;public final class Decrypt {
&lt;br /&gt;
&lt;br /&gt;    public static String Alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ ,.";
&lt;br /&gt;    
&lt;br /&gt;    /**
&lt;br /&gt;     * @param args
&lt;br /&gt;     */
&lt;br /&gt;    public static void main(String[] args) {
&lt;br /&gt;        System.out.println(
&lt;br /&gt;                String.format("Pass:%s", args[0])                );
&lt;br /&gt;        
&lt;br /&gt;        System.out.println(
&lt;br /&gt;                String.format("c1:%s", args[2])                );
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;        
&lt;br /&gt;        System.out.println(
&lt;br /&gt;                String.format("P:%s", args[1])                );
&lt;br /&gt;
&lt;br /&gt;        
&lt;br /&gt;        Integer pass=new Integer(args[0]);
&lt;br /&gt;        
&lt;br /&gt;        BigInteger p=new BigInteger(args[1]);
&lt;br /&gt;        
&lt;br /&gt;        BigInteger c1=new BigInteger(args[2]);
&lt;br /&gt;        
&lt;br /&gt;        for(int i=3;i&lt;args.length;i++)
&lt;br /&gt;            System.out.println(
&lt;br /&gt;                    String.format("ci:%s", args[i])                );
&lt;br /&gt;
&lt;br /&gt;        System.out.println("==DECRYPTION==");
&lt;br /&gt;        for(int i=3;i&lt;args.length;i++)
&lt;br /&gt;        {
&lt;br /&gt;            BigInteger c2=new BigInteger(args[i]);
&lt;br /&gt;            BigInteger m=DecryptGamal(pass,c1,c2,p);
&lt;br /&gt;            String msg=GetMessage(m.intValue());
&lt;br /&gt;            System.out.print(msg);
&lt;br /&gt;        }
&lt;br /&gt;    }
&lt;br /&gt;
&lt;br /&gt;    private static String GetMessage(Integer m) {
&lt;br /&gt;        Integer val=m;
&lt;br /&gt;        String result="";
&lt;br /&gt;        for(int i=0;i&lt;4;i++)
&lt;br /&gt;        {
&lt;br /&gt;            int index=val%100;
&lt;br /&gt;            result=Decrypt.Alphabet.charAt(index)+result;
&lt;br /&gt;            val=val/100;
&lt;br /&gt;        }
&lt;br /&gt;        return result;
&lt;br /&gt;    }
&lt;br /&gt;
&lt;br /&gt;    private static BigInteger DecryptGamal(Integer pass, BigInteger c1,BigInteger c2, BigInteger p) {
&lt;br /&gt;        BigInteger bigpass=p.subtract(
&lt;br /&gt;                BigInteger.valueOf((long)(pass+1)));
&lt;br /&gt;                
&lt;br /&gt;        BigInteger c1pow=c1.modPow(bigpass, p);
&lt;br /&gt;        
&lt;br /&gt;        BigInteger result=((c2.mod(p)).multiply(c1pow)).mod(p);
&lt;br /&gt;
&lt;br /&gt;        return result;
&lt;br /&gt;    }
&lt;br /&gt;}&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;Нахождение разшифрованного сообщения оставляю в качестве бонуса :D&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-8948676665532830718?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/L3amqifiDDhH_WXgYh9OB0i79os/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/L3amqifiDDhH_WXgYh9OB0i79os/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/L3amqifiDDhH_WXgYh9OB0i79os/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/L3amqifiDDhH_WXgYh9OB0i79os/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/0G-yU76htD0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/8948676665532830718/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2010/01/blog-post.html#comment-form" title="Комментарии: 5" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/8948676665532830718?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/8948676665532830718?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/0G-yU76htD0/blog-post.html" title="Взлом алгоритма Эль-Гамаль( с помощью алгоритма Шенкса) или ещё немного университетской фигни :)" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2010/01/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIBQXcyeip7ImA9WxBSEEg.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-765190405973214055</id><published>2009-12-17T14:28:00.005+02:00</published><updated>2009-12-17T14:55:50.992+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-17T14:55:50.992+02:00</app:edited><title>Моя работа - скандинавский аукцион :)</title><content type="html">Всем привет :) Ни разу в блоге не писал о том, чем я занимался целых 3 месяца.&lt;br /&gt;Хотя я написал пост о интернет-коммерции, я не написал к чему он относился.&lt;br /&gt;На самом деле всё просто - я разрабатывал скандинавский аукцион.&lt;br /&gt;&lt;br /&gt;Вкратце об скандинавских аукционах:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Идея такова - есть товар. Пользователи покупают ставки допустим по рубль каждая и ставят ставки на товар. Каждый раз при ставке пользователя товар повышается в цене на 5 копеек и время до конца увеличивается на 15 секунд.Кстати начальная цена - 0 грн. Победитель аукциона - игрок, который поставил последнюю ставку. &lt;br /&gt;&lt;br /&gt;В чём выигрывает аукцион? Во первых на разнице стоимости покупки и продажи товара, как обычный магазин. Во вторых главный источник прибыли - товары, пользующие повышенным спросом. В них пользователи в сумме переплачивают за товар, т.к ставок в сумме больше, чем стоимость товара. &lt;br /&gt;&lt;br /&gt;В чём выигрывает пользователь? Во первых он не может переплатить за товар( при условии правильной игры). В случае если потрачено больше ставок, чем рыночная стоимость товара пользователь получает товар в качестве подарка. А если же пользователь выиграл - то получает товар со значительной скидкой. Так-то!&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Но теперь перейдём к тонкостям разработки. В аукционе были такие интересные мелочи как автоставки,дневной аукцион,и много чего другого. &lt;br /&gt;&lt;br /&gt;Проект был реализован на ASP.NET. Многие говорят что АСП пишет много лишнего кода в проект, но на мой взгляд это всё зависит от рук программиста. После того как я убрал Debug='true' в конфиге в сайте осталось буквально 5-6 специфических АСП строк. Зато ASP.NET значительно упрощает использование AJAX-а. А в данном случае без AJAX обойтись было просто невозможно.&lt;br /&gt;&lt;br /&gt;Конкретно без AJAX-а нельзя было бы делать ставки, постоянно проверять обновление состоянния лотов. &lt;br /&gt;&lt;br /&gt;Для визуальных эффектов( как например подмигивание лота при изменении лидера ) была использована ныне популярная и мне любимая библиотека jQuery. &lt;br /&gt;&lt;br /&gt;В качестве БД аукциона использовалась MSSQL. Аукцион работает на выделенном сервере. К сожалению функционал ASP.NET не даёт аналога CRON-а. По крайней мере насколько мне известно. &lt;span style="font-weight:bold;"&gt;Если аналог действительно существует - то очень, очень хотелось бы знать как реализовать на стандартном хостинге подобное.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Автоставка - ставка, которая выполняется автоматически если до конца аукциона осталось менее 10 секунд. Подобный функционал требовал создания скрипта, который проверял бы факт действия автоставки и делал бы автоставку автоматически. Именно изза скрипта пришлось использовать выделенный сервер.&lt;br /&gt;&lt;br /&gt;Аукцион был запущен уже 1 месяц назад,но я не хотел спешить писать в блоге. Чтоб не зглазили.:)&lt;br /&gt;Вообщем этим постом я просто хотел немного похвастатся и может услышать советы/критику по отношению к проделанной работе :)&lt;br /&gt;&lt;br /&gt;ЗЫ: Аукцион можно найти по адресу &lt;a href="http://www.tak-tik.com.ua"&gt;www.tak-tik.com.ua&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-765190405973214055?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/C3CY-y7OxcOT0fMQA1jl53JFWtE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C3CY-y7OxcOT0fMQA1jl53JFWtE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/C3CY-y7OxcOT0fMQA1jl53JFWtE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/C3CY-y7OxcOT0fMQA1jl53JFWtE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/uy8gV4oERyI" height="1" width="1"/&gt;</content><link rel="enclosure" type="text/html" href="http://www.tak-tik.com.ua" length="0" /><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/765190405973214055/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2009/12/blog-post.html#comment-form" title="Комментарии: 4" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/765190405973214055?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/765190405973214055?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/uy8gV4oERyI/blog-post.html" title="Моя работа - скандинавский аукцион :)" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>4</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2009/12/blog-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MDRXc6eip7ImA9WxFQGUw.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-8049092147985406804</id><published>2009-11-24T23:41:00.003+02:00</published><updated>2010-05-15T12:24:34.912+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-15T12:24:34.912+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="fun" /><title>Microsoft TechNet</title><content type="html">Сегодня был на бесплатном семинаре Микрософта TechNet Days. Ещё в прошлый раз хотел пойти на него, но тогда не получилось :(&lt;br /&gt;&lt;br /&gt;Что сказать? Какие впечатления? Во первых я признаюсь честно шёл только потому что слышал что там хорошо кормят. Да, звучит цинично. Но там действительно хорошо кормят. Каждые полтора часа можно было выпить кофейку с печеньками,а на обед дали шашлык.&lt;br /&gt;&lt;br /&gt;Но всё же перейдём к впечатлениям от самого семинара. Ведь как никак - но я его прослушал от начала до конца. &lt;br /&gt;&lt;br /&gt;Конечно больше всего мне понравилась презентация Windows 7. Видел я эту систему не впервые, но всё таки послушать из первых уст было очень любопытно. Благо докладчик имел отличное чувство юмора и отпускал то и дело приколы. Также порадавала презентация Windows Server 2008 R2. Сразу видно что будующее движется в сторону вычислений в облаке и тотальной веб-интерферизации.&lt;br /&gt;&lt;br /&gt;Кроме того я узнал о наличии бесплатного сервера Hyper-V, отличный от Windows Server-а отсутсвием GUI. Всё администрирование делается через командную строку.&lt;br /&gt;Интересно можно ли на нём настроить IIS? :D&lt;br /&gt;&lt;br /&gt;Ну и ещё оказывается у нас в городе есть целый клуб IT-специалистов и любителей www.it-club.od.ua. &lt;br /&gt;&lt;br /&gt;Вообщем как по мне подобные семинары - штука полезная. Позволяет отслеживать положение дел в IT-сфере и просто приятно провести время. Так что с нетерпением жду следующего семинара Микрософт по разработке ПО. :)&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-8049092147985406804?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/FEUZAHoDReHroc34V_BQYEhRF0k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FEUZAHoDReHroc34V_BQYEhRF0k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/FEUZAHoDReHroc34V_BQYEhRF0k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/FEUZAHoDReHroc34V_BQYEhRF0k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/yUbYTdeK0_M" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/8049092147985406804/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2009/11/microsoft-technet.html#comment-form" title="Комментарии: 0" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/8049092147985406804?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/8049092147985406804?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/yUbYTdeK0_M/microsoft-technet.html" title="Microsoft TechNet" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2009/11/microsoft-technet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MAQ388cCp7ImA9WxFQGUw.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-4869439374784753840</id><published>2009-11-15T14:08:00.003+02:00</published><updated>2010-05-15T12:24:02.178+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-15T12:24:02.178+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="fun" /><title>Google Wave</title><content type="html">Получил инвайт на Google Wave ^_^&lt;br /&gt;Что могу сказать? Выглядит прикольно, хотя немного нагромождено много окон и запускается к сожалению только в Mozilla ( родной гугловский хром напрочь отказался запускатся с первого раза)&lt;br /&gt;&lt;br /&gt;Так что если что - я в Google Wave jack.spektor[doggy]gmail.com :)&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-4869439374784753840?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/W881hOo368mrGb4869YvhRVNbns/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/W881hOo368mrGb4869YvhRVNbns/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/W881hOo368mrGb4869YvhRVNbns/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/W881hOo368mrGb4869YvhRVNbns/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/V2NAhoX4zhk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/4869439374784753840/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2009/11/google-wave.html#comment-form" title="Комментарии: 5" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/4869439374784753840?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/4869439374784753840?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/V2NAhoX4zhk/google-wave.html" title="Google Wave" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>5</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2009/11/google-wave.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8FQns7eip7ImA9WxJaEE4.&quot;"><id>tag:blogger.com,1999:blog-4973083673024356794.post-5855170448328082438</id><published>2009-07-20T22:44:00.008+03:00</published><updated>2009-07-31T14:13:33.502+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-31T14:13:33.502+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET" /><category scheme="http://www.blogger.com/atom/ns#" term="liqpay" /><category scheme="http://www.blogger.com/atom/ns#" term="coding" /><title>Работа с LiqPay в ASP.NET и не только</title><content type="html">Совсем недавно пришлось по работе столкнутся с сией системой.С помощью Liqpay можно   использовать в интернете карточки VISA,MasterCard для своего интернет-магазина.Система конечно классная но что меня удивило - это "обилие" документации не только для ASP, но даже для php.&lt;br /&gt;&lt;br /&gt;Её создатели любезно разместили на странице &lt;a href="https://liqpay.com/?do=static&amp;name=liqpaydev"&gt;https://liqpay.com/?do=static&amp;name=liqpaydev&lt;/a&gt;, которую можно найти долго изучая тэги на главной странице. Но не в этом суть.&lt;br /&gt;&lt;br /&gt;Начал я с создания Click&amp;Buy формы. Мы с напарником решили что раз уж работать через эту систему , то наверно нужно использовать новейщую версию АПИ - 1.2. Теперь я понимаю что наверно это было ошибкой). Об этом позже.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;В данном примере я использую Click&amp;Buy 1.0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt; &lt;span class="attr"&gt;action&lt;/span&gt;&lt;span class="kwrd"&gt;='https://liqpay.com/?do=click_n_buy'&lt;/span&gt; &lt;span class="attr"&gt;method&lt;/span&gt;&lt;span class="kwrd"&gt;='POST'&lt;/span&gt; &lt;span class="attr"&gt;accept-charset&lt;/span&gt;&lt;span class="kwrd"&gt;='utf-8'&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;='hidden'&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;='version'&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;='1.1'&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;='hidden'&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;='merchant_id'&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;='i4999913091'&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;='hidden'&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;='amount'&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;='сумма'&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;='hidden'&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;='currency'&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;='UAH'&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;='hidden'&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;='description'&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;='DESCR'&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;='hidden'&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;='order_id'&lt;/span&gt;  &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;='test'&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;='hidden'&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;='result_url'&lt;/span&gt;&lt;br /&gt;                                        &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;='тут_страничка_куда переходим после оплаты'&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;='hidden'&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;='server_url'&lt;/span&gt;&lt;br /&gt;                                        &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;='это_страничка_уведомления_о_статусе_платежа'&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;                                    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;='submit'&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;='Оплатить'&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;br /&gt;                                 &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;form&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;В принципе сам вид запроса довольно прост и тут проблем не возникло.В поле merchant_id вписывается ID который получается в LiqPay.(Кстати если не найдёте где искать регистрацию - то делать нада нажав на Вход для торговцев или LiqPay checkout).&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Кстати замечу что в поле order_id можно передать свой параметр( например номер заказа). Система его не использует.&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;result_url &lt;/span&gt;- страница которая будет отображена когда оплата будет совершена. Тут можно написать о том что оплата была успешной и поблагодарить пользователя за то что отдал денюжки. Но вот совершать какие либо действия тут ( как например увеличить баланс пользователя или чтото в этом роде) ни в коем случае не следует - данные операции следует выполнять на server_url.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;server_url &lt;/span&gt;- страница оповещения об успешном переводе денег. Это скорее даже не страница, а скрипт. В АСП её удобно создавать как .ashx страницу.&lt;br /&gt;&lt;br /&gt;Итак первая часть задачи прошла как по маслу. Запрос отправлялся и я с радостью видел страничку оплаты на Liqpay. Теперь предстояло создать result_url и server_url. И если при создании result_url не обязательно делать много проверок на безопасность, то при создании server_url очень важно проверить является ли действительно это запрос от сервера liqpay или это проделки хакера.&lt;br /&gt;&lt;br /&gt;Для этого в server_url кроме данных о статусе платежа передаётся сигнатура - строка составленная из данных торговца, данных платежа и секретного пароля. На странице server_url составляется аналогичная строка и если строки совпадают то значит всё ОК.&lt;br /&gt;Так вот именно в этой части я увяз вначале. &lt;br /&gt;&lt;br /&gt;Если читать документацию к АПИ 1.2 то можно увидеть что там сигнатура составляется по виду пароль+неупакованная хмл+пароль. Далее она хэшируется и приводится к base64_string. Но как не старайся сигнатура не совпадала. В поддержке меня ещё более удивили, дав пример с совсем другим видом сигнатуры. Но и оно не помогло. Вообщем проблема была решена, когда я решил использовать АПИ 1.0.&lt;br /&gt;&lt;br /&gt;Так вот в этом АПИ на server_url передаются след. параметры методом POST:&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;signature &lt;/span&gt;- та строка с сигнатурой, которая правильная. мы должны составить свою и если она совпадёт значит это запрос с сервера liqpay.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;merchant_id &lt;/span&gt;- не знаю зачем оно передаётся, мы его и так знаем. Но это наш id торговца&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;amount &lt;/span&gt;- цена товара&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;currency &lt;/span&gt;- валюта&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;order_id &lt;/span&gt;- наш пользовательский параметр.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;status &lt;/span&gt;- статус платежа.если success - то платёж принят. если failure - то чтото не так.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;sender_phone&lt;/span&gt; - телефон отправителя&lt;br /&gt;&lt;br /&gt;Кроме того есть параметры action,code,transaction_id,action_name,version. Они нам понадобятся для создания сигнатуры.&lt;br /&gt;&lt;br /&gt;Код создания сигнатуры(на ASP):&lt;br /&gt;&lt;blockquote&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;br /&gt;&lt;pre class="csharpcode"&gt;&lt;br /&gt;var signature_source = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Format(&lt;span class="str"&gt;"|{0}|{1}|{2}|{3}|{4}|{5}|{6}|{7}|{8}|{9}|{10}|"&lt;/span&gt;,&lt;br /&gt;version, merchant_password, action_name, sender_phone, merchant_id,&lt;br /&gt;amount, currency, order_id, transaction_id, status, code);&lt;br /&gt;var signature_hash = Convert.ToBase64String(&lt;br /&gt;SHA1.Create().ComputeHash(&lt;br /&gt;Encoding.UTF8.GetBytes(signature_source)));&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Тут мы вначале склеиваем в опред.формате данные платежа. &lt;span style="font-weight:bold;"&gt;Merchant_password&lt;/span&gt; - пароль торговца. Его можна узнать в настройках торговца на liqpay.com. Полученную строку мы вначале хэшируем, а потом конвертируем в base64string. &lt;br /&gt;&lt;br /&gt;Итак сделав сигнатуру мы бонально сравниваем её с той что нам передали в Form["signature"] и если они равны, то выполняем операцию. В моём случае это увеличение баланса пользователя.&lt;br /&gt;&lt;br /&gt;Ну вот и всё. :)&lt;br /&gt;&lt;br /&gt;PS: Я знаю, что то, что я написал - довольно простая вещь, но мне кажется это будет кому то полезно, потому что нормального примера использования liqpay, а тем более на ASP.NET я не нашёл.&lt;div class="blogger-post-footer"&gt;&lt;a href="mr-kody.blogspot.com"&gt;mr-kody.blogspot.com&lt;/a&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4973083673024356794-5855170448328082438?l=mr-kody.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nCJPNF6Jr9cHPgHIRYvqRn-5X98/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nCJPNF6Jr9cHPgHIRYvqRn-5X98/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nCJPNF6Jr9cHPgHIRYvqRn-5X98/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nCJPNF6Jr9cHPgHIRYvqRn-5X98/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/mr-kody/~4/-PcHnipvd9Q" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://mr-kody.blogspot.com/feeds/5855170448328082438/comments/default" title="Комментарии к сообщению" /><link rel="replies" type="text/html" href="http://mr-kody.blogspot.com/2009/07/liqpay.html#comment-form" title="Комментарии: 9" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/5855170448328082438?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4973083673024356794/posts/default/5855170448328082438?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/mr-kody/~3/-PcHnipvd9Q/liqpay.html" title="Работа с LiqPay в ASP.NET и не только" /><author><name>Jack Spektor</name><uri>https://profiles.google.com/117590705256409499277</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh6.googleusercontent.com/-qwy2qb1nq3c/AAAAAAAAAAI/AAAAAAAADxY/AEtcUn4g1Qw/s512-c/photo.jpg" /></author><thr:total>9</thr:total><feedburner:origLink>http://mr-kody.blogspot.com/2009/07/liqpay.html</feedburner:origLink></entry></feed>

