Пятница, 15.12.2017, 07:14
Приветствую Вас Ополченец | RSS

Записки советского радиолюбителя

Каталог статей

Главная » Статьи » Эврика

PureBasic: таракан на рабочем столе в Ubuntu

PureBasic: таракан на рабочем столе в Ubuntu

Заводим таракана(ов) на рабочем столе :)

Утилита собрана на PureBasic, с использованием GTK и Cairo.

В системе необходима поддержка прозрачности окон, иначе "стасик" будет бегать в черном оконце.

Roach PB

Внимание! Программа скомпилирована на 64-bit Ubuntu (на 32-битной возможны проблемы).

Выход из программы: ЛКМ - раздавить, второй раз ЛКМ или Esc - удалить.

Исходник

 

UsePNGImageDecoder()
Global
FixedBox
Global support_alpha_channel=#False
Global *window1
Global x1.l
Global y1.l
Global x2.l
Global x3.l
Global y3.l
Global y2.l
Global Ld.l
Global d
Global invert
Global invert2
Global anglerad.f
Global CairoContext
Global image
Global mon_w
Global mon_h
Global s
Global kill
Global image1
Global image_id
Global quit
; Начальные параметры
quit = 0
s = 1
kill = 0
x1.l = 500 ; появление таракана по координате x
y1.l = 500 ; появление таракана по координате y
x2.l = Random(50) + x1 ; координата x конечной точки маршрута
y2.l = Random(50) + y1 ; координата y конечной точки маршрута
Ld.l = Sqr((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1)) ; Длина пути между [x1,y1] и [x2,y2]
; Возведение в степень можно было записать и так Pow((x2-x2),2) или (x2-x2)^2, но для производительности лучше перемножать!
d = 1 ; шаг движения
invert = 1 ; ключ для смены направления движения ( 1 - движение влево-вверх, 0 - вправо-вниз)
invert2 = 1 ; ключ для смены направления движения ( влево-вниз, 0 - вправо-вверх)

#CAIRO_OPERATOR_SOURCE = 1

Enumeration
#Window_0
#Image
#Image1
#Image2

EndEnumeration

ImportC ""

gdk_cairo_create(*Drawable.GdkDrawable)
gdk_screen_get_rgba_colormap(*Screen.GdkScreen)
gtk_window_set_skip_taskbar_hint(*Window, setting)


gdk_cairo_set_source_pixbuf(*cr, *pixbuf, pixbuf_x.d, pixbuf_y.d)
gdk_pixbuf_new_from_file.i(filename.p-utf8, _gerror.i=0)
gtk_image_set_from_pixbuf(*image_, *pixbuf)

EndImport

ImportC
"-lcairo"
cairo_destroy(*CairoContext)
cairo_paint(CairoContext)
cairo_set_operator(*CairoRegion, CairoOperator.I)
cairo_set_source_rgba(*CairoRegion, Red.D, Green.D, Blue.D, Alpha.D)
cairo_translate(CairoContext, width.d, height.d)
cairo_rotate(CairoContext, angle.d)
cairo_rectangle(*CairoContext, x.D, y.D, Width.D, Height.D)

EndImport

ProcedureC RedrawWidget
(*Widget.GtkWidget)
; ----- Нарисовать прозрачный фон
CairoContext = gdk_cairo_create(*Widget\window)
;cairo_set_source_rgba(CairoContext, 1.0, 1.0, 1.0, 0.5)
cairo_set_operator(CairoContext, #CAIRO_OPERATOR_SOURCE) ; прозрачность

image_w = 50
image_h = 50


cairo_translate(CairoContext, 0.5*image_w, 0.5*image_h) ; для вращения вокруг центра изображения
cairo_rotate(CairoContext, anglerad*(#PI/180)) ; поворот изображения
cairo_translate(CairoContext, -0.5*image_w, -0.5*image_h) ; для вращения вокруг центра изображения

image = gdk_cairo_set_source_pixbuf(CairoContext, image_id, 0.0, 0.0) ; загрузка изображения
cairo_paint(CairoContext);

cairo_destroy(CairoContext) ; от утечки памяти
EndProcedure

ProcedureC movie()

sqrt.l = Sqr((x2-x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))
;***Вычисление угла движения***
;угол между отрезком и осью ОX по координатам вершин отрезка

If y2 < y1
anglerad.f = 360 - ACos((x2 - x1)/sqrt)*180/#PI ; вычисление угла поворота
gtk_widget_queue_draw_(*window1) ; при выходе из программы использовать g_source_remove () для g_timeout_add
Else
anglerad.f = ACos((x2 - x1)/sqrt)*180/#PI
gtk_widget_queue_draw_(*window1)
EndIf
; ****Цикл движения по прямой****
While d < Ld
;***Убийство таракана***
If kill = 1
CatchImage(#image1, ?Image1, #PB_Image_DisplayFormat) ; загружаем изображение из памяти
image_id = ImageID(#Image1)
anglerad.f = anglerad + 5 ; угол первого кадра
gtk_widget_queue_draw_(*window1)
quit = 1
ProcedureReturn #True ; выход из процедуры
Else
EndIf

x3 = x1 + d * (x2-x1) / sqrt ; вычисление коорд.Х, после очередного шага d
y3 = y1 + d * (y2-y1) / sqrt ; вычисление коорд.Y, после очередного шага d

;***Анимация по углу**
;угол между отрезком и осью ОX по координатам вершин отрезка
If s = 1
anglerad.f = anglerad + 5 ; угол первого кадра
gtk_widget_queue_draw_(*window1) ; при выходе из программы использовать g_source_remove () для g_timeout_add
s = 0
Else
anglerad.f = anglerad - 5 ; угол второго кадра
gtk_widget_queue_draw_(*window1)
s = 1
EndIf

;***Сдвиг окна***
gtk_window_move_(*window1, x3, y3) ; при выходе из программы использовать g_source_remove () для g_timeout_add
d = d + 10 ; увеличиваем расстояние от начала пути
;Delay(1)
ProcedureReturn #True ; выход из цикла, пока условие d < Ld выполняется
Wend
; ***Задаем конец маршрута как начало нового пути***
d = 1 ; опять начинаем с первого шага
x1 = x3
y1 = y3
; ***Задаем конечную точку нового маршрута***
If invert = 1 ; меняем направление движения прав/лев
If invert2 = 1 ; меняем направление движения вниз/вверх
x2 = x1 + Random(mon_w - x1)
y2 = y1 + Random(mon_h - y1)
invert2 = 0
Else
x2 = x1 - Random(x1)
y2 = y1 + Random(mon_h - y1)
invert = 0
invert2 = 1
EndIf
Else
If invert2 = 1
x2 = x1 - Random(x1)
y2 = y1 - Random(y1)
invert2 = 0
Else
x2 = x1 + Random(mon_w - x1)
y2 = y1 - Random(y1)
invert = 1
invert2 = 1
EndIf
EndIf
; ***Вычисляем длину нового маршрута***
Ld.l = Sqr((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))
ProcedureReturn #True ; выход из процедуры при новых координатах
EndProcedure

;*****Основное окно*****
If OpenWindow(#Window_0, 500,500,52,52, "", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_Invisible) ; отрисовываем окно
CatchImage(#image, ?Image, #PB_Image_DisplayFormat) ; загружаем изображение из памяти
image_id = ImageID(#Image)
monitor = gdk_screen_get_default_() ; экран по умолчанию
mon_w = gdk_screen_get_width_(monitor) ; ширина экрана
mon_h = gdk_screen_get_height_(monitor) ; высота экрана
*window1 = WindowID(#Window_0)
StickyWindow(#Window_0, 1) ; окно поверх всех открытых окон
gtk_window_set_skip_taskbar_hint(WindowID(#Window_0), #True) ; не отображается в панели задач
gtk_window_set_decorated_(WindowID(#Window_0), #False) ; окно без рамки

FixedBox = g_list_nth_data_(gtk_container_get_children_(gtk_bin_get_child_(WindowID(#Window_0))), 0) ; виджет привязанный к окну
g_signal_connect_(FixedBox, "expose-event", @RedrawWidget(), 0) ; обработчик сигнала
time = g_timeout_add_(60, @movie(), #Null) ; таймер движение окна
gtk_widget_set_app_paintable_(FixedBox, #True) ; разрешаем отрисовку в виджете

; ----- Удалить GdkWindow ресурсы, чтобы иметь возможность изменить цветовую гамму
gtk_widget_unrealize_(WindowID(#Window_0))

; ----- Поддержка альфа канала
Screen = gtk_widget_get_screen_(WindowID(#Window_0))
Colormap = gdk_screen_get_rgba_colormap(Screen)

If Colormap
gtk_widget_set_colormap_(WindowID(#Window_0), Colormap)
Else
MessageRequester("Error", "Your current system configuration doesn't support transparency!")
End
EndIf
; ----- показываем окно и все в нем
gtk_widget_show_all_(WindowID(#Window_0))

; Отслеживаем нажатие Esc в указанном окне (пока окно/таракан находится в фокусе, т.е. активно)
AddKeyboardShortcut(0, #PB_Shortcut_Escape, 0)
;*****Выход из программы*****
Repeat
Select WaitWindowEvent()
Case #PB_Event_Menu
If EventMenu() = 0
Break
EndIf
Case #PB_Event_LeftClick ; клик ЛКМ по таракану
kill = 1
If quit = 1
g_source_remove_(time) ; блокируем работу таймера (для корректной работы с Delay)
Delay(300) ; задержка закрытия окна
Break
Else
EndIf
EndSelect
ForEver
EndIf

DataSection
Image: IncludeBinary "roach000.png" ; IncludeBinary - упаковываем изображение "внутрь" откомпилированного файла
Image1: IncludeBinary "roach_kill.png"
EndDataSection

 PNG:

 

 

 



Источник: http://airvikar.ru
Категория: Эврика | Добавил: Soliton (26.03.2015) | Автор: Airvikar W
Просмотров: 1077 | Теги: Roach, Ubuntu, purebasic | Рейтинг: 0.0/0
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
...
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0