XzzzX 496 Posted January 6 Share Posted January 6 (edited) Немного необычный формат открытки. Я так до конца и не понял как её лучше представить. Дело в том, что открытка сделана в виде программы. Это анимация, в которой можно менять режимы гирлянды! На видео демонстрация каждого режима Combo.mp4 Программа не полноэкранная, поэтому вот так поместил все режимы на 1 видео, чтобы не страдало качество при просмотре на полный экран Ещё я хотел сделать gif, но формат похоже не осилил такую динамику. Были сильные фризы и дёрганья Небольшой обзор того, что понадобилось для создания Спойлер Новогодняя ёлка из таверны Вырезал её около часа, а затем подкрутил экспозицию, тк правая часть в тени Скриншот с Предела 2020-2021 До сих пор это моё самое любимое событие в игре. Мы практически с самого начала Предела заняли 20 рб, не оставив ни единого шанса Хранителям. Порой выбивали даже небольшие группы высокоуровневых персонажей, рассчитывавших легко закрыть рб для собы ги! Тут я достаточно быстро вырезал основных участников сего действа Пол из Цитадели Белоборода Вырезал квадратики в качестве бэкграунда 300+ строчек кода Может быть я не важный художник, за то умею программировать. "Так почему бы и нет", подумал я? Edited January 7 by XzzzX EugeneBlack, Инженер, Enot and 5 others 6 1 1 Quote Link to comment Share on other sites More sharing options...
FCKNZS 1309 Posted January 6 Share Posted January 6 На чём писал программу? Quote Link to comment Share on other sites More sharing options...
XzzzX 496 Posted January 6 Author Share Posted January 6 Только что, Nebaluika сказал: На чём писал программу? PascalABC.NET Я вот сейчас как раз думаю как бы дать возможность форумчанам запустить это дело @Dr Strange знаю, что на форум нельзя вот так просто выложить exe, но может быть как-то можно сделать исключение? Или мне лучше полностью расписать как собрать программу самостоятельно? Там не слишком сложно и думаю все разберутся, но вероятно это слишком муторно для людей вне IT Quote Link to comment Share on other sites More sharing options...
FCKNZS 1309 Posted January 6 Share Posted January 6 Только что, XzzzX сказал: PascalABC.NET В первые слышу Quote Link to comment Share on other sites More sharing options...
Enot 428 Posted January 6 Share Posted January 6 Весьма интересно и необычно, лайк за что-то новое) Quote Link to comment Share on other sites More sharing options...
XzzzX 496 Posted January 6 Author Share Posted January 6 (edited) Инструкция по запуску Спойлер Понадобится Windows (желательно 10 или 11) и PascalABC.NET StandardPack с официального сайта Скачайте следующие картинки Спойлер background.png rogues.png tree.png Создайте 2 файла в той же папке, что и скачанные картинки. Содержимое файлов: WarspearPostcard.pas Цитата uses System.Windows; uses GraphWPF, GraphWPFBase, WPFObjects, SceneUnit; begin Invoke( ()-> (MainWindow.ResizeMode:= ResizeMode.CanMinimize) ); Window.SetSize(495, 279); Window.Title:= 'Письмо от XzzzX'; //заполнение фона for var i:= 0 to 3 do for var j:= 0 to 1 do new PictureWPF(i*216, j*216, 'background.png'); //статические картинки new PictureWPF(40, 150, 'rogues.png'); new PictureWPF(350, 130, 192*0.5, 288*0.5, 'tree.png'); //коллекция лампочек гирлянды var radius:= 20; var bulbs:= new List<Bulb>; bulbs.AddRange( | new Bulb(67, 170, radius), new Bulb(117, 245, radius), new Bulb(164, 170, radius), new Bulb(210, 245, radius), new Bulb(262, 170, radius), new Bulb(40, 40, radius), new Bulb(80, 100, radius), new Bulb(120, 30, radius), new Bulb(440, 30, radius), new Bulb(250, 35, radius), new Bulb(470, 200, radius), new Bulb(340, 190, radius), new Bulb(320, 250, radius) | ); //цветовая схема var colorMap:= new Dictionary<GColor, GColor>; colorMap[Colors.Red]:= Colors.Green; colorMap[Colors.Green]:= Colors.Yellow; colorMap[Colors.Yellow]:= Colors.Blue; colorMap[Colors.Blue]:= Colors.Red; var garland:= new Garland( bulbs, new ColorScheme(colorMap) ); var scaleFactor:= 1.08; var warspearText:= new AnimatedText( new Point(340, 55), 'Warspear Online', 20, Colors.Yellow, 500, text-> begin text.AnimScale(scaleFactor, 0.5); scaleFactor:= 1/scaleFactor; end ); warspearText.Rotate(25); var progress:= 0.0; var newYearText:= new AnimatedText( new Point(110, 70), 'С Новым Годом и', 35, Colors.Yellow, 40, text-> begin text.Color:= SmootchColorTransition(Colors.Yellow, Colors.Cyan, progress); progress+= 0.03; if progress >= 1 then progress:= 0; end ); var ChristmasText:= new AnimatedText( new Point(153, 105), 'Рождеством', 35, Colors.Yellow, 40, text-> begin text.Color:= SmootchColorTransition(Colors.Yellow, Colors.Cyan, progress); end ); var scene:= new Scene( garland, warspearText, newYearText, ChristmasText ); OnKeyUp:= k-> begin case k of Key.D1: scene.Garland.Mode:= GarlandMode.Fast; Key.D2: scene.Garland.Mode:= GarlandMode.Slow; Key.D3: scene.Garland.Mode:= GarlandMode.PWM; end; end; end. SceneUnit.pas Цитата unit SceneUnit; interface uses System, System.Windows.Threading; uses GraphWPF, GraphWPFBase, WPFObjects; type ColorScheme = class private _map: Dictionary<GColor, GColor>; public function FirstColor: GColor; function NextColor(current: GColor): Gcolor; constructor(map: Dictionary<GColor, GColor>); end; AnimatedText = class (TextWPF) private _timer: DispatcherTimer; public constructor(pos: Point; text: string; size: real; color: GColor; time: integer; callback: Action<AnimatedText>); end; Bulb = class private _circle: CircleWPF; public property Color: GColor read _circle.Color write _circle.Color:= value; constructor(x, y: real; radius: real); end; GarlandMode = (Fast, Slow, PWM); Garland = class private _bulbs: List<Bulb>; _mode: GarlandMode; _colorScheme: ColorScheme; _timer: DispatcherTimer; _timerCallback: EventHandler; procedure SetColorScheme(value: ColorScheme); procedure SetGarlandMode(value: GarlandMode); procedure RestoreColors; public property ColorScheme: SceneUnit.ColorScheme read _colorScheme write SetColorScheme; property Mode: GarlandMode read _mode write SetGarlandMode; property Item[i: integer]: Bulb read _bulbs; constructor(bulbs: sequence of Bulb; colorScheme: SceneUnit.ColorScheme); end; Scene = class public Garland: Garland; WarspearText: AnimatedText; NewYearText: AnimatedText; ChristmasText: AnimatedText; constructor(garland: SceneUnit.Garland; warspearText, newYearText, ChristmasText: AnimatedText); end; function SmootchColorTransition(current, target: GColor; progress: real): GColor; implementation ///Плавное переливание одного цвета в другой function SmootchColorTransition(current, target: GColor; progress: real): GColor; begin result:= GColor.FromArgb( integer(current.A*(1-progress) + target.A * progress), integer(current.R*(1-progress) + target.R * progress), integer(current.G*(1-progress) + target.G * progress), integer(current.B*(1-progress) + target.B * progress) ); end; {$region ColorScheme} function ColorScheme.FirstColor: GColor; begin result:= _map.First.Value; end; function ColorScheme.NextColor(current: GColor): Gcolor; begin result:= _map[current]; end; constructor ColorScheme.Create(map: Dictionary<GColor, GColor>); begin _map:= map; end; {$endregion} {$region AnimatedText} constructor AnimatedText.Create(pos: Point; text: string; size: real; color: GColor; time: integer; callback: Action<AnimatedText>); begin inherited Create(pos.X, pos.Y, size, text, color); _timer:= new DispatcherTimer(DispatcherPriority.Normal, MainWindow.Dispatcher); _timer.Interval:= TimeSpan.FromMilliseconds(time); _timer.Tick+= (sender, ea)-> begin callback(self) end; _timer.Start; end; {$endregion} {$region Bulb} constructor Bulb.Create(x, y: real; radius: real); begin _circle:= new CircleWPF(x, y, radius, RandomColor); end; {$endregion} {$region Garland} procedure Garland.RestoreColors; begin _timer.Stop; var color:= ColorScheme.FirstColor; foreach var item in _bulbs do begin item.Color:= color; color:= ColorScheme.NextColor(color); end; _timer.Start; end; procedure Garland.SetColorScheme(value: SceneUnit.ColorScheme); begin _colorScheme:= value; RestoreColors; end; procedure Garland.SetGarlandMode(value: GarlandMode); begin _mode:= value; _timer.Stop; _timer.Tick-= _timerCallback; RestoreColors; if value = GarlandMode.Fast then begin _timer.Interval:= TimeSpan.FromMilliseconds(750); _timerCallback:= (sender, ea)-> begin foreach var item in _bulbs do item.Color:= ColorScheme.NextColor(item.Color); end; _timer.Tick+= _timerCallback; end else if value = GarlandMode.Slow then begin _timer.Interval:= TimeSpan.FromMilliseconds(30); var currentColors:= _bulbs.Select(s-> s.Color).ToArray; var targetColors:= currentColors.Select( s-> _colorScheme.NextColor(s) ).ToArray; var progress:= 0.0; var skipCount:= 20; _timerCallback:= (sender, ea)-> begin if skipCount > 0 then begin skipCount-= 1; exit; end; foreach var item in _bulbs index i do item.Color:= SmootchColorTransition(currentColors, targetColors, progress); progress+= 0.05; if progress >= 1 then begin currentColors:= targetColors; targetColors:= currentColors.Select( s-> _colorScheme.NextColor(s) ).ToArray; progress:= 0; skipCount:= 20; end; end; _timer.Tick+= _timerCallback; end else if value = GarlandMode.PWM then begin _timer.Interval:= TimeSpan.FromMilliseconds(40); var currentColors:= _bulbs.Select(s-> s.Color).ToArray; var targetColors:= ArrGen( _bulbs.Count, i-> GColor.FromArgb(0, currentColors.R, currentColors.G, currentColors.B) ); var progress:= 0.0; var skipCount:= 20; _timerCallback:= (sender, ea)-> begin if skipCount > 0 then begin skipCount-= 1; exit; end; foreach var item in _bulbs index i do item.Color:= SmootchColorTransition(currentColors, targetColors, progress); progress+= 0.05; if progress >= 1 then begin swap(currentColors, targetColors); progress:= 0; skipCount:= 20; end; end; _timer.Tick+= _timerCallback; end; _timer.Start; end; constructor Garland.Create(bulbs: sequence of Bulb; colorScheme: SceneUnit.ColorScheme); begin _bulbs:= new List<Bulb>(bulbs); _timer:= new DispatcherTimer(DispatcherPriority.Normal, MainWindow.Dispatcher); self.ColorScheme:= colorScheme; Mode:= GarlandMode.Fast; end; {$endregion} {$region Scene} constructor Scene.Create(garland: SceneUnit.Garland; warspearText, newYearText, ChristmasText: AnimatedText); begin self.Garland:= garland; self.WarspearText:= warspearText; self.NewYearText:= newYearText; self.ChristmasText:= ChristmasText; end; {$endregion} begin end. Откройте WarspearPostcard.pas в PascalABC.NET и нажмите кнопку запуска (зелёная стрелка) Режимы гирлянды переключаются цифрами 1, 2 и 3 Edited January 6 by XzzzX Dr Strange 1 Quote Link to comment Share on other sites More sharing options...
nth 1187 Posted January 6 Share Posted January 6 38 минут назад, XzzzX сказал: Инструкция по запуску На следующем конкурсе будет ссылка на торрент с пробелами? XzzzX 1 Quote Link to comment Share on other sites More sharing options...
XzzzX 496 Posted January 7 Author Share Posted January 7 (edited) Переделал видео. Теперь качество практически как в исходном варианте Edited January 7 by XzzzX Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.