조회 수 2081 추천 수 0 댓글 3
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 수정 삭제
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 수정 삭제
뮤's 실전 스크립팅 강좌

[4. 실전! 플래싱 메시지를 만들어보자]


실전 강좌인 4강부터는 그동안 연습한 기초 부분을 응용하여 몇 가지 스크립트를 만들어보도록 하겠습니다.
물론 앞에서 미처 설명하지 못한 부분도 많기 때문에 새로운 개념도 나올 겁니다. 이건 하면서 설명하겠습니다.
일단 강의에 사용되는 파일을 받아서(첨부파일 보세요) 프로젝트 폴더의 Graphics/Pictures에 넣습니다.

* 예제는 홈페이지(www.unis.kr)에서 다운로드 받을 수 있습니다.


#1. 비트맵과 스프라이트

이번에 만들 스크립트는 "플래싱 메시지" 입니다.
플래싱 메시지가 무엇인가! 사진을 보시면 아실겁니다.

1.png 

2.png

(사진출처 - 티뮤리티 온라인 공식 카페)

이제 뭔지 대강 짐작이 가시나요?
자, 자런 메시지를 만드려면 어떻게 해야 할까요~?
쉽게 설명하자면 '그림을 그릴 공간' 이 필요합니다.
스프라이트와 비트맵은 그런 개념입니다.

스프라이트는 '화판' 이고 비트맵은 '도화지' 입니다.

즉 스프라이트라는 화판에는 비트맵이라는 도화지가 올려지는 것이고, 우리가 그림을 그릴 때는 비트맵에 그리는 거죠.
그럼 간단한 예제로 이해를 도와보겠습니다.


-----------------------------------------------------------
def draw_picture
@sprite = Sprite.new
@sprite.bitmap = Bitmap.new(640, 480)
pic = RPG::Cache.picture("test.png")
@sprite.bitmap.blt(0, 0, pic, Rect.new(0, 0, pic.width, pic.height))
end
-----------------------------------------------------------


일단 @sprite 라는 변수에 Sprite 클래스를 선언합니다.
다음 @sprite.bitmap 에 Bitmap을 선언하는데, 이 bitmap은 다른 것으로 바꿀 수 없습니다.
스프라이트 이름은 @sprite나, @mu나, $ee 등 이름에 상관이 없으나, bitmap은 불변입니다.
(예외 - Window를 상속하는 경우 bitmap이 아니라 contents 입니다.)

다음으로 비트맵 선언 방법에는 두가지가 있습니다.
하나는 제가 예제에 적은 것처럼 Bitmap.new(가로, 세로) 입니다.
다른 하나는 Bitmap.new(그림파일 경로) 입니다.
후자로 선언할 경우, 따로 blt를 쓰지 않아도 그림이 표시됩니다.
예제를 살펴볼까요?


-----------------------------------------------------------
def draw_picture2
@sprite = Sprite.new
@sprite.bitmap = Bitmap.new("Graphics/Pictures/test")
end
-----------------------------------------------------------


하지만 이 경우에는 문제가 있습니다.
이 문제에 대해서는 나중에 UI 스크립트를 만들며 알아볼게요!

다시 본론으로 돌아가서, RPG::Cache는 뭘까요?
일일이 파일 경로를 지정하지 않아도, 캐시에 저장된 비트맵을 불러온다고 하는군요.
아래는 도움말에서 가져온 목록입니다.


-----------------------------------------------------------
RPG::Cache.animation(filename, hue) 
애니메이션 그래픽을 취득합니다.
hue 로 색상 변화값을 지정합니다. 

RPG::Cache.autotile(filename) 
오토 타일 그래픽을 취득합니다. 

RPG::Cache.battleback(filename) 
배틀 백 그래픽을 취득합니다. 

RPG::Cache.battler(filename, hue) 
butler 그래픽을 취득합니다.
hue 로 색상 변화값을 지정합니다. 

RPG::Cache.character(filename, hue) 
캐릭터 그래픽을 취득합니다.
hue 로 색상 변화값을 지정합니다. 

RPG::Cache.fog(filename, hue) 
fog 그래픽을 취득합니다.
hue 로 색상 변화값을 지정합니다. 

RPG::Cache.gameover(filename) 
게임 오버 그래픽을 취득합니다. 

RPG::Cache.icon(filename) 
아이콘 그래픽을 취득합니다. 

RPG::Cache.panorama(filename, hue) 
파노라마 그래픽을 취득합니다.
hue 로 색상 변화값을 지정합니다. 

RPG::Cache.picture(filename) 
픽쳐 그래픽을 취득합니다. 

RPG::Cache.tileset(filename) 
타일 세트 그래픽을 취득합니다. 

RPG::Cache.title(filename) 
타이틀 그래픽을 취득합니다. 

RPG::Cache.windowskin(filename) 
윈도우 스킨 그래픽을 취득합니다. 
-----------------------------------------------------------


그럼 똑똑하신 분은 의문이 생길겁니다.
왜 방금 예제에서는 "Graphics/Pictures/test" 라고 썼나요?
RPG::Cache.picture("test") 라고 해도 되지 않나요?
라고 말입니다.

하지만 잘 보면 둘은 다릅니다.
전자는 단순히 그림 파일의 경로이고 
후자는 그림 파일의 경로에서 그림을 읽어온 것, 즉 그림파일 자체입니다.
즉 RPG::Cache.picture("test") 는 경로가 아니라 그림이죠.

다시 첫번째 예제를 분석해 보겠습니다.
@sprite.bitmap.blt(0, 0, pic, Rect.new(0, 0, pic.width, pic.height))
blt(x좌표, y좌표, 그림파일, Rect) 입니다.
이중 Rect가 이해가 힘들것이라고 생각되네요.
Rect는 해당 이미지의 어느 부분을 출력할 것인가를 나타냅니다.
순서대로 Rect(x좌표, y좌표, 가로, 세로) 를 말하죠.
이건 예제로 이해하는게 가장 빠릅니다.


-----------------------------------------------------------
def rect_test
@sprite = Sprite.new
@sprite.bitmap = Bitmap.new(640, 480)
pic = RPG::Cache.picture("rect_test")
@sprite.bitmap.blt(0, 0, pic, Rect.new(0, 0, 100, 100))
end


def rect_test2
@sprite = Sprite.new
@sprite.bitmap = Bitmap.new(640, 480)
pic = RPG::Cache.picture("rect_test")
@sprite.bitmap.blt(0, 0, pic, Rect.new(300, 300, 100, 100))
@sprite.y = 200
end
-----------------------------------------------------------


두 함수를 동시에 실행시켜 보시면
그림의 일부분만 출력되는 것을 알 수 있습니다.
또한 스프라이트는 .x와 .y로 위치를 변경할 수 있습니다.

자, 기본 개념이 끝났습니다. 이제 본격적으로 만들어 볼까요?


#2. 플래싱 메시지를 만들자!

자, 바로 플래싱 메시지 만들기로 들어갑니다!
일단 아래와 같이 틀을 잡아 줍니다.


-----------------------------------------------------------
class FlashMessage
def initialize
end

def change_color
end

def refresh
end

def update
end

def text(new_text)
@text = new_text
end
end
-----------------------------------------------------------


initialize가 생성자라는 것은 지난 시간에 이야기했습니다.
change_color에서는 플래싱 메시지의 글씨 색상을 바꿀 것이고
refresh에서 메시지를 쓸 겁니다.
그리고 update에서 페이드 인/아웃을 하겠습니다.

일단 initialize에서 스프라이트를 선언합니다.


------------------------------------------------------------
def initialize
@sprite = Sprite.new
@sprite.bitmap = Bitmap.new(640,20)
@sprite.x = 0
@sprite.y = 100
@sprite.z = 999999
@sprite.opacity = 0
@text = ""
@fade_in = false
@fade_out = false
@wait_count = 40
end

-----------------------------------------------------------



어차피 글씨를 쓰는 곳이니 세로 크기는 작게 20으로 잡았습니다.

@sprite.z는 스프라이트의 우선순위를 말합니다. 

('이벤트 - 그림의 표시 - 번호' 와 같은 역할)

또 다른 모든 것들보다 위에 떠야 하기 때문에 999999로 잡았습니다.

opacity는 불투명도를 말합니다.

0 ~ 255까지 설정이 가능한데, 수치가 작아질수록 투명해집니다.

다음 @text에는 플래싱 메시지에 들어갈 글자를 저장합니다.

@wait_count와 @fade_in/out은 페이드 인/아웃을 위한 변수들입니다.


다음으로 change_color 메소드를 만들어봅시다.



-----------------------------------------------------------

def change_color(new_color)

@sprite.bitmap.font.color = new_color

end

-----------------------------------------------------------



Bitmap 클래스에는 폰트 이름과 사이즈, 색상에 관한 함수도 있습니다.

bitmap.font.name = "폰트이름"

bitmap.font.size = 크기

bitmap.font.color = Color.new(R,G,B)

여기서 RGB는 Red,Green,Blue의 약자입니다.

각각의 색이 얼마나 들어가느냐에 따라 전체 색이 달라지죠!

또 Color.new(R,G,B,불투명도) 로 사용할 수도 있습니다.

불투명도는 위에서 말한 opacity입니다.


그리고 가장 중요한 refresh 메소드입니다.



-----------------------------------------------------------

def refresh

@sprite.bitmap.clear

@sprite.bitmap.fill_rect(Rect.new(0,0,640,20), Color.new(0, 0, 0, 100))

@sprite.bitmap.draw_text(1, 3, 640, 12, @text, 1)

@sprite.bitmap.draw_text(1, 4, 640, 12, @text, 1)

@sprite.bitmap.draw_text(1, 5, 640, 12, @text, 1)

@sprite.bitmap.draw_text(-1, 3, 640, 12, @text, 1)

@sprite.bitmap.draw_text(-1, 4, 640, 12, @text, 1)

@sprite.bitmap.draw_text(-1, 5, 640, 12, @text, 1)

@sprite.bitmap.draw_text(0, 3, 640, 12, @text, 1)

@sprite.bitmap.draw_text(0, 5, 640, 12, @text, 1)

@sprite.bitmap.font.color = Color.new(255, 255, 255)

@sprite.bitmap.draw_text(0, 4, 640, 12, @text, 1)

@sprite.visible = true

@fade_in = true

end

-----------------------------------------------------------



일단 bitmap을 클리어합니다. 이전에 쓰여진 글자가 있을 수도 있으니까요.

다음 fill_rect 함수는 처음 스크린샷의 뒷배경입니다.

비트맵을 기준으로 rect 값을 정하고, 그만큼을 지정된 색상으로 채우는 겁니다.

다음은 draw_text 메소드입니다.

draw_text(x좌표, y좌표, 가로, 세로, 텍스트, 정렬방식) 입니다.

정렬방식은 적지 않아도 무방합니다.

기본은 좌측 정렬이며, 1을 입력하면 중앙 정렬, 2를 입력하면 우측 정렬이 됩니다.

(글자도 그림 취급을 하기 때문에 그릴 공간을 입력해야 하죠.)


draw_text가 왜이리 많이 쓰였냐, 물어보신다면 대답해 드리는게 인지상정!

바로 테두리 효과를 위해서입니다.

테두리는 지정한 색으로, 중앙은 흰색으로 출력합니다. 그러면 한층 깔끔하게 나오겠죠?

다음으로 @sprite.visible은 스프라이트가 보여지는지 여부를 설정합니다.

그리고 @fade_in 변수를 참으로 바꾸어 페이드 인 시작을 알립니다.


그 뒤, 업데이트 부분에서는!



-----------------------------------------------------------

def update

if @fade_in

if @sprite.opacity < 255

@sprite.opacity += 10

return

elsif @wait_count > 0

@wait_count -= 1

return

else

@fade_out = true

@fade_in = false

end

end

if @fade_out

if @sprite.opacity > 0

@sprite.opacity -= 10

return

else

@wait_count = 40

@fade_out = false

@fade_in = false

@text = ""

@sprite.visible = false

end

end

end

-----------------------------------------------------------



저는 돌아가는 원리만 설명합니다.

일단 fade_in이 참일 경우, opacity를 검사합니다.

opacity가 255보다 작으면(약간이라도 투명하면) 불투명하게 만듭니다.

그리고 처리를 중단(return) 합니다.

이런 식으로 계속 불투명하게 만들면 결국에는 불투명해지겠죠?

그럼 이제 wait_count를 검사합니다.

왜 검사하냐! 바로 불투명한 상태로 조금은 남아있어야 하기 때문입니다.

1프레임에 1씩 빼는 것이고 wait_count가 40이니 1초동안 불투명한 상태로 보여집니다.

자, wait_count까지 0이 되면 어떻게 할까요?

fade_in은 false로 바꾸고 fade_out을 true로 바꿉니다.

그럼 페이드 아웃이 시작되죠.

다시 opacity를 검사해서, 0보다 크면 (완전히 투명하지 않으면) 투명하게 만듭니다.

그리고 완전히 투명해지면 (opacity <= 0) wait_count를 다시 40으로 바꾸고,

fade_out과 fade_in을 거짓으로 만든 뒤, text를 비우고 visible을 false로 합니다.

이제 텍스트도 없고, 페이드 인/아웃 효과도 없고, 보이지도 않습니다.

다시 refresh를 해야 보이겠죠.


자, 그럼 이제 이걸 사용하는 함수를 만들어 봅시다.

FlashMessage 클래스 내에 선언하지 마세요!



-----------------------------------------------------------

def 메시지(msg, new_color = Color.new(0, 0, 0))

$flash_message.text(msg)

$flash_message.change_color(new_color)

$flash_message.refresh

end

-----------------------------------------------------------


이제 힘들여 만든 FlashMessage 스크립트를 선언해야겠죠?

Main 섹션의 begin 아래에 $flash_message = FlashMessage.new 를 넣어주시고

Scene_Map 섹션의 def update 아래에 $flash_message.update 를 넣어주세요.


사용법은 이벤트 - 스크립트에

메시지("할말", Color.new(R,G,B)) 입니다.

R,G,B는 숫자인거 아시죠?

추가로 색상코드 대강 알려드리자면~


검정색 : Color.new(0, 0, 0)

흰색 : Color.new(255, 255, 255)
빨간색 : Color.new(255, 0, 0)
초록색 : Color.new(50, 150, 50) < 요게 낫더군요

마지막으로 한마디 하자면 스크립트는 최대한 깔끔하게 써주세요.
완성본 예제 보시면 알겠지만, 저는 들여쓰기 꼭 지킵니다.
이건 누구에게나 필수적인 사항입니다. 
다른 사람이 못알아보면 나중에 본인은 알아볼까요?
그리고 스크립트 위쪽에 이름, 기능, 날짜 등 표시하는 습관을 들이세요!


#3. 숙제

주석에 함수별로 기능과 사용법을 써보세요.
이 스크립트에 기능을 추가하여 자료실에 올려 보세요.
file.zip < 예제 다운로드

NateOn : mu29_nateon@nate.com
E - Mail : mu29@unis.kr
Homepage : www.unis.kr
?

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수 추천 수
공지 초급강의실 게임제작강좌 A-Z 색인 (2016.1.24 ver) 2 file 천무 2016.01.12 7373 1
32 고급강의실 RGSS 스크립트 강좌 입문 13 - 클래스(Class) 5 마니아 2013.09.16 2317 2
31 고급강의실 RGSS 스크립트 강좌 입문 12 - 연상 배열(Associative Array) 4 마니아 2013.09.16 1600 1
30 고급강의실 RGSS 스크립트 강좌 입문 11 - 배열(Array) 6 마니아 2013.09.16 1701 1
29 고급강의실 RGSS 스크립트 강좌 입문 10 - 그래픽 표시 4 마니아 2013.09.16 2183 0
28 고급강의실 RGSS 스크립트 강좌 입문 9 - 오브젝트(Object) 4 마니아 2013.09.16 1642 0
27 고급강의실 RGSS 스크립트 강좌 입문 7 ~ 8 - 함수(Function) 3 마니아 2013.09.16 1924 0
26 고급강의실 RGSS 스크립트 강좌 입문 6 - 루프(Loop) 2 마니아 2013.09.16 1586 0
25 고급강의실 RGSS 스크립트 강좌 입문 5 - 조건분기 4 마니아 2013.09.16 2131 0
24 고급강의실 RGSS 스크립트 강좌 입문 4 - 캐릭터 라인 4 마니아 2013.09.16 2274 1
23 고급강의실 RGSS 스크립트 강좌 입문 3 - 메서드(Method) 4 마니아 2013.09.16 1876 0
22 고급강의실 RGSS 스크립트 강좌 입문 2 - 수 3 마니아 2013.09.16 2256 0
21 고급강의실 RGSS 스크립트 강좌 입문 1 - 기초 개념 8 마니아 2013.09.16 4351 0
20 고급강의실 뮤's 실전 스크립팅 강좌 [5. 실전! 반복문을 응용하자!] 2 마니아 2013.09.16 1411 0
» 고급강의실 뮤's 실전 스크립팅 강좌 [4. 실전! 플래싱 메시지를 만들어보자] 3 마니아 2013.09.16 2081 0
18 고급강의실 뮤's 실전 스크립팅 강좌 [3. 기초 문법 다지기 (하)] 6 마니아 2013.09.16 1145 0
17 고급강의실 뮤's 실전 스크립팅 강좌 [2. 기초 문법 다지기 (중)] 3 마니아 2013.09.16 1371 0
16 고급강의실 뮤's 실전 스크립팅 강좌 [1. 기초 문법 다지기 (상)] 6 마니아 2013.09.16 2351 0
15 고급강의실 RGSS2 강좌 1 비형랑 2012.10.01 2528 0
14 중급강의실 [RPGVX ACE] 소재규격과 강의수록 1 2 비형랑 2012.10.01 3273 0
13 초급강의실 [RPG VX ACE] 초심자강의 1 1 비형랑 2012.10.01 3168 2
Board Pagination Prev 1 ... 4 5 6 7 8 9 10 Next
/ 10






[개인정보취급방침] | [이용약관] | [제휴문의] | [후원창구] | [인디사이드연혁]

Copyright © 1999 - 2016 INdiSide.com/(주)씨엘쓰리디 All Rights Reserved.
인디사이드 운영자 : 천무(이지선) | kernys(김원배) | 사신지(김병국)