Tutorial:Cameras (Polski)
Ten poradnik jestłumaczeniem artykułów "Cameras in Love2D" napisanym przez BlackBulletIV.
Oryginalne artykuły (po angielsku):
Contents
Część 1. Podstawy
This part will deal with the fundamentals of creating a camera. Part two will deal with parallax scrolling and creating layers. So, let's get to it!
W pierwszej części zajmiemy się podstawami tworzenia kamer.
Funkcje z których będziemy korzystać
- love.graphics.pop
- love.graphics.push
- love.graphics.translate -- translacja/przesunięcie
- love.graphics.rotate -- obrót
- love.graphics.scale -- skalowanie
LÖVE posiada stos przekształceń (geometrycznych), a dokładniej stos [b]informacji o danym przekształczeniu[/b]. love.graphics.push
pozwala odłożyć aktualne przekształcenie na stos (pozwala to zapamiętać przekształcenie na później), natomiast love.graphics.pop zdejmuje przekształcenie ze stosu (nadpisując tym samym aktualne przewształceni, tym zdjętym przed chwilą ze stosu).
Na [b]informację o przekształceniu[/b], składają się trzy elementy: przesunięcie, skalowanie i obrót. W trakcie każdej operacji rysowania:
- argumenty x i y przekazywane do funkcji translate są dodawane do współrzędnych x i y,
- obie współrzędne są mnożone przez argument funkcji scale
- każdy punkt jest obracany względem lewego górnego rogu o kąt podany jako argument do funkcji rotate (w radianach).
Mając te wiedzę możemy stworzyć naszą pierwszą kamerę
function love.draw()
love.graphics.translate(-x, -y)
-- właściwe rysowanie poniżej
end
Tutaj funkcja translate modyfikuje aktualne przekształcenie. Stos intormacji o przekształceniach (jak również aktualne przekształcenie) jest resetowany z każdą ramką, więc w każdej ramce, będziemy ustawiać kamerę.
Bardziej kompletna implementacja kamery wygląda następująco:
function love.draw()
love.graphics.rotate(-obrot) -- w radianach
love.graphics.scale(1 / skala, 1 / skala)
love.graphics.translate(-x, -y)
end
zmienne -obrot i -x oraz -y, będą mieć takie wartości, że obiekty, które nie poruszają się wraz z kamerą, zostaną w tyle. (Najczęściej kamera będzie podążać za graczem). Wartości zmiennej skala powyżej 1 będą oddalały kamerę, podczas gdy mniejsze od 1, będą ją przybliżały.
moduł kamery
Uporządkujmy kod do obsługi kamery w moduł
camera = {}
camera.x = 0
camera.y = 0
camera.scaleX = 1
camera.scaleY = 1
camera.rotation = 0
function camera:set()
love.graphics.push()
love.graphics.rotate(-self.rotation)
love.graphics.scale(1 / self.scaleX, 1 / self.scaleY)
love.graphics.translate(-self.x, -self.y)
end
function camera:unset()
love.graphics.pop()
end
function camera:move(dx, dy) -- przesuniecie kamery o deltę
self.x = self.x + (dx or 0)
self.y = self.y + (dy or 0)
end
function camera:rotate(dr) -- obrot kamery o deltę
self.rotation = self.rotation + dr
end
function camera:scale(sx, sy) -- zmiana skali (względna)
sx = sx or 1
self.scaleX = self.scaleX * sx
self.scaleY = self.scaleY * (sy or sx)
end
function camera:setPosition(x, y) -- zmiana pozycji absolutnej kamery
self.x = x or self.x
self.y = y or self.y
end
function camera:setScale(sx, sy) -- zmiana skali (bezwzględnda)
self.scaleX = sx or self.scaleX
self.scaleY = sy or self.scaleY
end
Moduł kamery jest tablicą, która zawiera informację gdzie ma być umiejscowiona kamera. Kluczowe są funkcje set i unset. set
zmienia aktualne przekształcenie, na informacje zawarte w module kamery (ale wcześniej zapisuje bieżący stan, dzięki czemu moduł kamery będzie w stanie obsługiwać kilka widokow w jednej ramce. unset
po prostu przywraca poprzednie ustawienie, korzystając z wspomnianej funkcji pop. Pozostałe funkcje stanowią pomoc przy przemieszczaniu kamery.
Kamery można użyć poprzez następujący kod w callbacku love.draw (Polski):
function love.draw()
camera:set() -- zaapliwowanie ustawień kamery
-- właściwe rysowanie
camera:unset()
end
Natomiast w callbacku love.update (Polski), można zmieniać położenie kamery.
camera.x = 50
camera:scale(3)
mysz
Jeśli chcesz znać pozycję myszy w świecie (czyli względem kamery), będzie trzeba odpowiednio przekształcić współrzędne zwracane przez love.mouse.getX/love.mouse.getY. Mając gotowy moduł kamery, można to prosto zrobić dodając do niego następującą funkcję.
function camera:mousePosition()
-- przelicza pozycję myszy na ekranie, na współrzędne 'w świecie gry'
return love.mouse.getX() * self.scaleX + self.x, love.mouse.getY() * self.scaleY + self.y
end
Funkcja ta koryguje pozycję myszy tylko względem przesunięcia i skalowania kamery. W przypadku obrotu, należy uwzględnić przemnożenie przez odpowiedni vector. Zobacz implementacje wektora bibliotece [1], by zobaczyć jak to zrobić.
Część 2. Wielowarstwowe przewijanie (parallax scrolling)
"W szczególności paralaksa odnosi się do jednoczesnego obserwowania obiektów leżących w różnych odległościach od obserwatora lub urządzenia obserwującego," - Wikipedia, paralaksa
W efekcie czego, przy poruszaniu się, odnosi się wrażenie, że obiekty położone dalej, poruszają się wolniej.
W tej części zajmiemy się przewijaniem paralakatycznym. Użyta metoda, nie jest najpiękniejsza, ma jedynie stanowić podstawę, dla prób na własną rękę.
Czym jest przewijanie paralakatyczne? To sposób na uzyskanie efektu pseudo-3d, podczas gay cała gra i grafiki są oparet na 2d. To popularna metoda w grach 2d, na dodanie wrażenia głębi, chociaż de facto jej tam nie ma.
Technika którą wykorzystamy by osiągnąć ten efekt nazywana jest metodą warstwową (tłum: stąd bardziej właściwy tytuł części: Przewijanie wielowarstwowe). To co musimy zrobić, to wyrenderować kilka warstw grafik, na które ruch kamery ma wpływ w różnym stopniu. Normalnie na pole gry (tam gdzie znajduje się gracz i gdzie będzie odbywać się cała rozgrywka) ruch kamery będzie miał wpływ w stosunku 1:1 (czyli teren PO którym gracz chodzi i sam gracz będzie się poruszać z taką prędkością z jaką porusza się kamera). Warstwy bliżej kamery niż pola gracza, będą poruszać się szybciej niż kamera, natomias warstwy dalej niż kamera, będą poruszać się welniej (góry w tle, chmury itp.)
Część 3. Ograniczenia ruchu
Dansk –
Deutsch –
English –
Español –
Français –
Indonesia –
Italiano –
Lietuviškai –
Magyar –
Nederlands –
Polski –
Português –
Română –
Slovenský –
Suomi –
Svenska –
Türkçe –
Česky –
Ελληνικά –
Български –
Русский –
Српски –
Українська –
עברית –
ไทย –
日本語 –
正體中文 –
简体中文 –
Tiếng Việt –
한국어
More info