단   편

<77ER의 알만툴 스킬> 알만툴에서 픽쳐를 많이 사용하는 스크립트 사용자들의 렉 고민을 풀어보자. (나름 고급자용?)

by 77이알 posted Aug 31, 2012
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄



음 이 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 방식으로 사용 하였을 경우

1.png








수정된 방식으로 사용 하였을 경우

2.png

3.png



///////////////////////////////////////////////////////////////////////////////////////////////////////////////////



다음 번에는 단 한개의 변수를 사용하여 무한 변수를 생성하여 사용하는 방법을 설명해 보겠습니다. 관심도를 봐서 ㅋ