PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » SpiderBasic » Клик на спрайте существует?


Клик на спрайте существует?

Сообщений 1 страница 12 из 12

1

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

Кажется понял, надо функции TouchScreen задействовать.

Код:
; AZJIO
EnableExplicit

#Font = 0
#Window = 0
#FontName$ = "Arial"

Global s = 80, x, y, i, evg, bRefresh = #True
Global Dim aXY(16, 4)
Global DspHeight, DspWidth, tmp

Global BCtxt2 = $c7c7c7
Global BCbg2 = $424242
Global BCbg3 = $111111
Global BCbg4 = $002123
Global BCbg4 = $333333
Global isLFont
Global indentX, indentY

Declare SetFont(BtnSize)

DspWidth = 240
DspHeight = 240
s = DspWidth / 4

;- Lang
Global lang0$
Global Dim Lng.s(2)
Lng(1) = "Пятнашки"
Lng(2) = "Перемешать"
Lng(0) = "Отлично!"


Procedure Update()
; 	Размещаем спрайты
	y = 0
	x = 0
	For i = 1 To 16
    aXY(i, 0) = i
    Select i
    	Case 1 To 4
        y = 0
        x = 1
    	Case 5 To 8
        y = 1
        x = 5
    	Case 9 To 12
        y = 2
        x = 9
    	Case 13 To 16
        y = 3
        x = 13
    EndSelect
    aXY(i, 2) = i - x
    aXY(i, 3) = y
    
    DisplaySprite(aXY(i, 1), aXY(i, 2) * s, aXY(i, 3) * s)
	Next
	FlipBuffers()
EndProcedure

;- GUI
If OpenWindow(#Window, 0, 0, 4*s, 4*s, Lng(1),  #PB_Window_ScreenCentered)
	If InitSprite() And Not OpenWindowedScreen(WindowID(#Window), 0, 0, 4*s, 4*s)
    End
	EndIf

	SetFrameRate(1)
	ClearScreen($3f3f3f)

	If LoadFont(#Font, "Arial", s / 2.5)
    isLFont = 1
	EndIf

	; 	Создаём спрайты
	For i = 1 To 16
    aXY(i, 1) = CreateSprite(#PB_Any, s, s)
    If StartDrawing(SpriteOutput(aXY(i, 1)))

    	If isLFont
        DrawingFont(FontID(#Font))
    	EndIf
    	If Not indentY
        indentY = (s - TextHeight("1")) / 2
    	EndIf

    	If i < 16
        Box(1, 1, s - 2, s - 2, BCbg2)
    	Else
        Box(1, 1, s - 2, s - 2, BCbg4)
    	EndIf
    	indentX = (s - TextWidth(Str(i))) / 2
    	If i < 16
        DrawText(aXY(i, 2) * s + indentX, aXY(i, 3) * s + indentY, Str(i), BCtxt2, BCbg2)
    	EndIf
    	StopDrawing()
    EndIf
	Next
	
	FlipBuffers()
	BindEvent(#PB_Event_RenderFrame,@Update())
EndIf

PureBasic

Код:
; AZJIO
EnableExplicit

#Font = 0
#Window = 0
#FontName$ = "Arial"

Global s = 80, x, y, i, evg, bRefresh = #True
Global Dim aXY(16, 4)
Global DspHeight, DspWidth, tmp

Global BCtxt2 = $c7c7c7
Global BCbg2 = $424242
Global BCbg3 = $111111
Global BCbg4 = $002123
Global BCbg4 = $333333
Global isLFont
Global indentX, indentY

DspWidth = 240
DspHeight = 240
s = DspWidth / 4

;- Lang
Global lang0$
Global Dim Lng.s(2)
Lng(1) = "Пятнашки"
Lng(2) = "Перемешать"
Lng(0) = "Отлично!"


;- GUI
If OpenWindow(#Window, 0, 0, 4*s, 4*s, Lng(1), #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_ScreenCentered)
	If InitSprite() And Not OpenWindowedScreen(WindowID(#Window), 0, 0, 4*s, 4*s)
    End
	EndIf

	SetFrameRate(1)
	ClearScreen($3f3f3f)

	If LoadFont(#Font, "Arial", s / 2.5)
    isLFont = 1
	EndIf

	; 	Создаём спрайты
	For i = 1 To 16
    aXY(i, 1) = CreateSprite(#PB_Any, s, s)
    If StartDrawing(SpriteOutput(aXY(i, 1)))

    	If isLFont
        DrawingFont(FontID(#Font))
    	EndIf
    	If Not indentY
        indentY = (s - TextHeight("1")) / 2
    	EndIf

    	If i < 16
        Box(1, 1, s - 2, s - 2, BCbg2)
    	Else
        Box(1, 1, s - 2, s - 2, BCbg4)
    	EndIf
    	indentX = (s - TextWidth(Str(i))) / 2
    	If i < 16
        DrawText(aXY(i, 2) * s + indentX, aXY(i, 3) * s + indentY, Str(i), BCtxt2, BCbg2)
    	EndIf
    	StopDrawing()
    EndIf
	Next
	
; 	Размещаем спрайты
	y = 0
	x = 0
	For i = 1 To 16
    aXY(i, 0) = i
    Select i
    	Case 1 To 4
        y = 0
        x = 1
    	Case 5 To 8
        y = 1
        x = 5
    	Case 9 To 12
        y = 2
        x = 9
    	Case 13 To 16
        y = 3
        x = 13
    EndSelect
    aXY(i, 2) = i - x
    aXY(i, 3) = y
    DisplaySprite(aXY(i, 1), aXY(i, 2) * s, aXY(i, 3) * s)
	Next
	FlipBuffers()
	Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

Отредактировано AZJIO (12.03.2023 18:08:48)

0

2

Я ответил на основном.
Не существует, это идеологически другой случай. существует только событие #PB_Event_RenderFrame
А функция SetFrameRate(XXX) задаёт частоту их генерации.

0

3

По крайней мере на телефоне я протестировал пример из справки. Клика нет, но проверка нажатия пальцем есть, координаты тоже есть. Пока тестировать тяжело, в браузере не работает, а значит каждый минуту компилируешь, и потом скопировать на телефон и там установить.

Код:
EnableExplicit

Procedure RenderFrame()
	Protected k
	Static SpriteFinger = -1
	Static x, y
	
	; 	ClearScreen($3f3f3f)
	
	If ExamineTouchScreen() ; Сенсорный экран обнаружен и доступен
    
    For k = 0 To 4 ; До 5 возможных пальцев одновременно. Нужно проверить их все, так как между ними может быть удален некоторый палец
    	If TouchScreenPushed(k) And SpriteFinger = -1 ; Обнаружено нажатие одним пальцем, используйте его для перемещения спрайта
        SpriteFinger = k
    	EndIf
    Next
    
    If SpriteFinger <> -1 And TouchScreenPushed(SpriteFinger) ; Убедитесь, что палец, использованный для перемещения спрайта, все еще нажат
    	x = TouchX(SpriteFinger) - SpriteWidth(0) / 2      ; Мы хотим, чтобы наш палец был центрирован в спрайте
    	y = TouchY(SpriteFinger) - SpriteHeight(0) / 2
    Else
    	SpriteFinger = -1
    EndIf
    
    DisplaySprite(0, x, y)
    FlipBuffers(); // продолжить визуализацию
	Else
;     ClearScreen($3f3f3f)
;     DisplaySprite(0, 0, 0)
;     FlipBuffers()    ; // начать рендеринг
    Debug "Cенсорный экран не обнаружен"
	EndIf
	
EndProcedure 

Procedure Loading(Type, Filename$, ObjectId)
	Static NbLoadedElements
	
	NbLoadedElements+1
	If NbLoadedElements = 1 ; Загрузка всех изображений и звуков завершена, мы можем начать рендеринг
;     ClearScreen($3f3f3f)
;     DisplaySprite(0, 0, 0)
    FlipBuffers()    ; // начать рендеринг (возможно это вызывает событие #PB_Event_RenderFrame)
	EndIf
EndProcedure

Procedure LoadingError(Type, Filename$, ObjectId)
	Debug Filename$ + ": ошибка загрузки спрайта"
EndProcedure

OpenScreen(340, 540, 32, "Тест")
SetFrameRate(10)
ClearScreen($3f3f3f)

; Зарегистрируйте событие загрузки перед вызовом любой команды загрузки ресурса
BindEvent(#PB_Event_Loading, @Loading())
BindEvent(#PB_Event_LoadingError, @LoadingError())
BindEvent(#PB_Event_RenderFrame, @RenderFrame())

LoadSprite(0, "./data/sprite.png")

0

4

Отзывчивость клика плохая. Что на примере выше, надо удерживать пол-секунды палец, чтобы спрайт перепрыгнул, что водишь палец кругами, а шарик с подёргиванием пытается догнать. Аналогично на криво собранных пятнашках нажатие пальцем реагирует не так быстро как хотелось бы, также удерживаешь палец пол-секунды, только тогда происходит обмен спрайтов. Цель была не доделать, а посмотреть как работает, прежде чем продолжать. Аналогично пятнашки на кнопках, которые были ранее тоже имели плохую отзывчивость. А вот календарь на канвасе, там я сделал выбор дня смены кликом в календаре, там срабатывает от малейшего касания. Остаётся пробовать сделать на канвасе.

0

5

В итоге сделал используя Canvas

0

6

useful написал(а):

А функция SetFrameRate(XXX) задаёт частоту их генерации.

Я не стал отвечать на английском.
Я не понимаю, как это можно не понимать.
Английским по белому написано, нужно чаще проверять, ставьте более высокую частоту XXX
Т.е. мы не можем организовать цикл проверки, его организуют за нас, а мы указываем с какой частотой дать нам возможность выполнить проверки местоположения кликов/нажатий.
Анимация тут абсолютно не причём. XXX определяет частоту вызова нашей функции @RenderFrame() И ВСЁ!!!!!!!
SetFrameRate(XXX)
BindEvent(#PB_Event_RenderFrame, @RenderFrame())

Отредактировано useful (14.03.2023 10:55:17)

0

7

useful
Это понятно, когда я сам уже себе ответил на англ. форуме. Задним числом всегда понятно. Нигде же не написано что SetFrameRate() задаёт частоту событий #PB_Event_RenderFrame, несмотря на то что слово "Frame" присутствует в обоих. Я вчера загуглил спрайты и высветился видеоурок по питону с библиотекой спрайтов. И там анимация как раз завязана на частоте, с чего я должен думать что события "мыши" тоже определяются этой частотой. Грубо говоря у меня игра без движений, я нажал фишку, она сдвинулась в новую позицию. И получается в теории мне достаточно частота 10, то есть фишка на 0.1 секунду появится в новой позиции, зачем мне лишние 50 раз перерисовывать окно. А тестировать тоже время не вагон, пример из справки не заработал у меня на телефоне и я начал эксперименты. На каждый эксперимент 1 минкута 45 сек только компилирование, стараюсь телефон подключить заранее, потому что 1 минуту он определяется в системе, после отключения 30 сек память возвращается телефону, открываю папку, устанавливаю, открываю. В общем раз 5-10 перекомпилируешь и час улетит только на одном тесте примера из справки.

0

8

useful написал(а):

Я ответил на основном.
Не существует, это идеологически другой случай. существует только событие #PB_Event_RenderFrame
А функция SetFrameRate(XXX) задаёт частоту их генерации.

Вот здесь написано!
Это настолько очевидно, что писать не о чем.

p.s. главная ошибка в том, что на то, что делает sb нельзя смотреть как на программу работающую на железе под управлением ОС.
результирующий js живёт в строго огороженной объектной модели браузера. И на Андроиде webview это тот же браузер, просто cordova немного добавляет слоя по ниже, как когда то activX в iE.

Отредактировано useful (14.03.2023 19:51:35)

0

9

Уточню почему я считаю себя правым, да, вы можете снимать с экрана 10, 20, 30 кадров, но почему я должен думать, что опрос сенсоров нажатия происходит с той же частотой. Я вполне могу представить, что я начал на экран, сенсор словил событие, рендер поймал событие с указанной частотой. То есть я не должен давить пальцем дожидаясь пока рендер захватит, что в текущее время чей-то палец стремительно держит дожидаясь прихода рендера. Событие может поставиться в очередь, что между опросами рендера произошло нажатие. Ведь можно так это предположить. Только обратным методом выявления проблемы мы понимаем что это работает не так. Но не зная этого, с чего я должен угадать именно так? Мои предыдущие знания работы ОС Windows и Linux говорят об обратном.

Едем дальше. Фред сказал, что можно тестировать в браузере не функциями Touch, а Mouse. Да, опять у меня всё заработало, но я же действую методом тыка, нет у меня нужных спрайтов на экране, я возьми да в рендер напихал перерисовку спрайтов, внимание вопрос: у нас есть функция ClearScreen для очистки экрана, тогда нафиг мне рисовать спрайты 60 раз в секунду? Разве нельзя использовать уже нарисованный кадр как в канвасе, нарисовал и ждёшь реакцию, пришла реакция, перерисовал нужную площадь или весь канвас, так и в спрайте, зачем мне 60 раз в секунду с помощью DisplaySprite размещать 16 спрайтов, то есть 60-90 таких перерисовок пустые, тогда теряется смысл ClearScreen, зачем мне очищать окно, если оно и так очистится если я не нарисую очередной кадр. Если ClearScreen это заливка цветом, то можно было и назвать не очисткой, а заливкой типа FillArea или FillScreen. Может я ошибаюсь и можно как то заморозить кадр до очередного события? Но глядя на функции я не вижу этого, и работает у меня только с формированием каждого кадра. Если это так, то для спрайтов подходит только динамическая игра, в которой постоянно что-то движется и нет смысла использовать предыдущий кадр.

Отредактировано AZJIO (17.03.2023 23:26:09)

0

10

AZJIO написал(а):

Мои предыдущие знания работы ОС Windows и Linux говорят об обратном.

Я уже писал. Забыть!!!
Пусть на минимальном уровне, но изучить работу javascript в браузере и потом всё, что происходит на уровне "препроцессора" под названием Spider Basic станет понятнее.

0

11

useful
А причём тут javascript? Пускай он запускает свой опрос событий с любой частотой, но браузер и ос работают с комфортной частотой.

useful написал(а):

Пусть на минимальном уровне, но изучить работу javascript в браузере

У меня 16 скриптов написаны для AkelPad на js и там не 5 строк, некоторые доходят до 1000 строк, а также я в Greasemonkey для некоторых сайтов использую скрипты подсветки и другие модули. Внимание вопрос, как это относится к угадываю движка работы SpiderBasic?

0

12

useful написал(а):

javascript в браузере

js встраиваемый язык и каждый раз он живёт по законам среды в которую встроен.
А sb ещё и свой взгляд добавляет.

Есть только один выход в случае вопросов: смотреть на генерируемый javascript код а не сыпать странными вопросами в разные стороны.

FlipBuffers()
Flip the back and front buffers of the current screen. The invisible area is now visible and vice versa, which allowss to do a 'double-buffering' effect (flicker free graphical displays). A screen must have been opened with OpenScreen() or OpenWindowedScreen(). The way the buffer are flipped (with or without synchronization) is set by OpenScreen() or OpenWindowedScreen().
Перевернуть задний и передний буферы текущего экрана. Невидимая область становится видимой и наоборот, что позволяет сделать эффект "двойной буферизации" (графические дисплеи без мерцания). Экран должен быть открыт с помощью OpenScreen() или OpenWindowedScreen(). Способ переворачивания буфера (с синхронизацией или без) задается OpenScreen() или OpenWindowedScreen().

Это единственное, что управляет появлением изображения на экране, т.е. дело даже не в частоте событий а в частоте вызова этой функции. Мне лень пробовать, но допускаю, что вместо SetFrameRate(FrameRate) можно задействовать таймер с тем же эффектом.
p.s. и про синхронизацию это из PB, в SB не поддерживается.

Отредактировано useful (18.03.2023 19:31:04)

0


Вы здесь » PureBasic - форум » SpiderBasic » Клик на спрайте существует?