음 이 77ER,
뜬금없이 나타나서 글을 쓰는 것이지만..
중간 중간 끊기는 렉을 줄여보고자 생각을 하고 적용 해 본 바.
적용이 되어 정리 차원에서 여기에 글을 남겨 봅니다.
렉의 원인은 여러가지가 있겠지만
그 중에서 가장 쉽게 만날 수 있는 그리고 가장 큰 영향을 미치는 것은..
에니메이션 렉, 픽쳐 렉. (코딩은 아무리 아무리 아무리 길어도 어지간해 길지 않는 이상 사람이 체감할 수 없는 것 같습니다.)
에니메이션 렉은 그 렉을 줄여주는 스크립트도 있고 뭐 조금만 손 보고 여차여차 하면 줄일 수 있는데
에니메이션의 렉의 주 요 원 인중에 하나가 픽쳐를 불러오는 방식 때문입니다.
에니메이션을 실행하기 위해서 해당 에니메이션 폴더의 픽처를 불러오는데
그때 픽쳐의 프래임이 한 장에 많이 포진되어 있거나 픽쳐가 생각 이상으로 크다면
불러오는 도중에 렉이 생기고 에니메이션 한 프레임 한 프레임을 불러 올 때마다 전체를 반복해서 불러오기 때문에
만약 30개의 프레임을 가진 에니메이션을 연결해서 불러 온다면 30번을 그 해당 픽쳐파일을 반복해서 불러오는 것이고
그 한 프레임 프레임마다 불러오며 끊기기에 30번이나 끊기는 화면이 이어지고 그래서 육안으로 프레임이 끊기는 현상이 나타나는 것 입니다.
그렇다고 에니메이션 각각의 프레임 따로 파일을 만들어 저장시킬 수도 없는 노릇이고 그래서..
해결 방법이 있습니다.
결론부터 말 씀 드리면 실행할 픽쳐 파일을 전부 module에 불러와서 저장시켜버리는 것 이지요.
픽쳐를 불러오는 함수의 예를 하나 보이면,
def draw_picture(pic_name, x, y, enabled = true)
bitmap = Cache.picture(pic_name)
rect = Rect.new(0, 0 , 272, 288)
contents.blt(x, y, bitmap, rect, enabled ? 255 : translucent_alpha)
bitmap.dispose
end
저기서 문제의 원인인 bitmap = Cache.picture(pic_name)가 보입니다. 저 부분때문에 매번 픽쳐를 새로 불러올 때 다시금 생으로
픽쳐파일을 캐싱해서 느려지게 되는 것 이지요.
이제 방법을 설명드리면..
(초급자 분들은 이해하기 여러울 수도.. 제 실력으로 너무 자세히는 설명은 못합니다.)
(아래 부분은 그냥 예시일 뿐입니다. 포인트를 잡는데 신경을 ㅋ)
만들려는 게임의 스테이지 1에서 필요한 픽쳐 파일이 A B C D라고 가정해 보겠습니다.
일단
module Picload
temp = [nil,nil,nil,nil]
end
을 만든 후에
스테이지 1이 시작되기 바로 전 단계(게임 로딩화면 정도..)에
Picload::temp[0] = Cache.picture("A") #픽쳐 A의 주소는 0
Picload::temp[1] = Cache.picture("B") #픽쳐 A의 주소는 1
Picload::temp[2] = Cache.picture("C") #픽쳐 A의 주소는 2
Picload::temp[3] = Cache.picture("D") #픽쳐 A의 주소는 3
를 해 준 후
픽쳐 불러오는 함수 부분을
def draw_picture(pic_num, x, y, enabled = true)
rect = Rect.new(0, 0 , 272, 288)
contents.blt(x, y, Picload::temp[pic_num], rect, enabled ? 255 : translucent_alpha)
end
로 바꾸어 줍니다. (원래 픽쳐를 불러오는 함수는 해당 픽쳐의 이름으로 불러왔는데 이제는 저장을 시켰으니 주소(번호)로 불러오게 합니다)
그리고 스테이지 1일 끝나는 부분에 있는 def terminate 함수 부분에
for i in 0..3
Picload::temp[0].dispose
end
를 추가시켜 주는 것 이지요.
위의 rect = Rect.new(0, 0 , 272, 288) 부분은 불러오는 사진의 어떤 부분을 잘라내 보여주는지 해당되는 것이기에 그 부분도 따로
module Picload
temp_r = [nil,nil,nil,nil]
end
이렇게 만들어서 스테이지 1이 시작되기 바로 전 단계(게임 로딩화면 정도..)에 각각의 사진의 크기의 맞게
Picload::temp_r[0] = Rect.new(0, 0 , 272, 288)
Picload::temp_r[1] = Rect.new(0, 0 , 50, 50)
Picload::temp_r[2] = Rect.new(96, 96 , 96, 96)
Picload::temp_r[3] = Rect.new(0, 0 , 100, 100)
이렇게 해 주고
def draw_picture(pic_num, x, y, enabled = true)
contents.blt(x, y, Picload::temp[pic_num], Picload::temp_r[pic_num] , enabled ? 255 : translucent_alpha)
end
위에처럼 해 버려도 됩니다.
근데 module은 임시캐쉬같은 것이니 때문에 세이브하고 로딩하면 다 날아가버린다는게 문제 입니다.
하지만 이것의 해결 방법은 또한 간단합니다. 각각의 스테이지별로 로딩할 때 그 부분에 필요한 픽쳐를
Picload::temp[0] = Cache.picture("A") #픽쳐 A의 주소는 0
Picload::temp[1] = Cache.picture("B") #픽쳐 A의 주소는 1
Picload::temp[2] = Cache.picture("C") #픽쳐 A의 주소는 2
Picload::temp[3] = Cache.picture("D") #픽쳐 A의 주소는 3
위의 식으로 다시 불러오는 코드를 입력하면 됩니다.
아마 세이브 전에
for i in 0..3
Picload::temp[0].dispose
end
이 필요할 지도 모르겠군요.
놀랍게 부분 부분 끊기고 렉이 생기던 것이 싹 사리집니다.
별로 어렵지 않은 방법이지만 어렵지 않은 방법을 생각해 내는데 참 오래도 걸리더군요.
에니메이션에서 사용되는 방법은 좀 조작이 필요하지만 위 의 방법으로 수정을 잘 하면 동일하게 수행이 가능 합니다.
위의 방법은 픽쳐를 쓰는 어느 곳이던 간에 응용이 가능 합니다. 렉 때문에 짜증나던 것이 사라지니 알만툴의 신세계를 경험하는 느낌이 들더군요...
또 다른 렉의 문제점 하나는 픽쳐를 너무 많이 사용해서 입니다. 그것을 줄이는 방법으로는 여러 픽쳐를 통일시켜 버리는 겁니다. 화면에 두 개의 픽쳐를 표시하려고 하는데 그냥 한 개의 픽쳐에 두개의 픽쳐를 붙여넣어 두개의 픽쳐가 보이게 해 버리는 것 이지요.
생각나는데로 막 썼기 때문에 이해하기 어려울지 모르나 제가 말하고자 하는 포인트를 잡을 수 있으리라 보여집니다.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
VVV위 방법을 사용했을 때와 하지 않았을 때 비교 동영상VVV
(여타 다른 코딩 등에는 전혀 변화를 주지 않음.)
(캡쳐한 동영상이라 실제로는 더 부드러움. 확연한 차이를 비교하는게 주요.)
기존의 draw_picture 방식으로 사용 하였을 경우
수정된 방식으로 사용 하였을 경우
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
다음 번에는 단 한개의 변수를 사용하여 무한 변수를 생성하여 사용하는 방법을 설명해 보겠습니다. 관심도를 봐서 ㅋ