조회 수 1466 추천 수 2 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

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

단축키

Prev이전 문서

Next다음 문서

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

2007년이 됬으니


접었던 커뮤니티 생활(다모임, 창도, 마비노기 등등)을 다시 복귀하며


제 전투시스템에 쓰이고 있는 최소값&최대값 설정을 올려봅니다.


 


최대값은 지정할수 있지만, 여기선 9999로 설정되는것을 설명할 것이며


최소값 역시 지정할수 있지만 여기선 1로 설정되는 것을 설명하겠습니다.


물론 턴알이지요. RXP를 쓰면서 턴알을 FFX 처럼 재밌게 만들면


재밌을수 있다는 생각에 여러가지 턴알 관련 스크립트를 개발중입니다.


이건 잡소리고 하여튼, 최대값=9999라는 것은 FFX의 아이디어를 훔친(?)것이고,


최소값=1이라는것은 마비노기의 아이디어를 훔친것입니다.


 


 


우선 원리 부터 설명하겠습니다아.


 


[Game_Battler3 를 참조하세요.]


기본적으로 RXP의 데미지 공식을 보면, 힘과 공격력을 사용한 기본 데미지 계산후


상대 방어력에 의해 감소됨, 속성에 의해 감소/증가, 에다가 크리티컬, 분산까지


완료한후 적의 HP로부터 빼는 식으로 사용합니다


 


데미지 = 어쩌고 저쩌고


~~~~~~~~~~~~~


self.hp -= self.damage 이런식으로


 


(스킬은 기본 데미지 공식 및 속성 보정치 등이 다르긴 하지만, 결과적으로 비슷비슷합니다.)


 


하여튼!


HP로부터 감소 하기 직전에 최대/최소를 걸어주는 것입니다.


그렇지 않으면 최대 9999제한의 의해 데미지가 9999로 설정됬는데 크리티컬 판정때문에


19998이 되기 때문입니다.


 


그런고로, HP직전에 이러한 식을 쓰면 됩니다.


 


self.damage = [self.damage, 9999].min


 


뜻은 대괄호 안에 있는 수들중 최소값을 뺀다 라는 것입니다.


데미지가 9999보다 크면 9999가 최소값이니 9999로 설정이 되고


데미지가 9999보다 작으면 데미지가 최소값이니 데미지 그대로 설정되는 것입니다.


데미지가 정의된후, HP로 부터 감소하면 되는것입니다.


 


이렇게 하면 어떠한 데미지든 아무리 커봤자 9999가 나옵니다. (물론 스킬에서 hp감소되는 부분에도


해줘야겠죠)


 


이렇게 함으로써, 조건 없이 최대값이 지정이 되었습니다.


 


1차적으로 정리 한번 해보겠습니다.


 


  #--------------------------------------------------------------------------
  # ● 통상 공격의 효과 적용
  #     attacker : 공격자 (버틀러)
  #--------------------------------------------------------------------------
   def attack_effect(attacker)
    # 위기 플래그를 클리어
    self.critical = false
    # 제일 명중 판정
    hit_result = (rand(100) < attacker.hit)
    # 명중의 경우
    if hit_result == true
      # 기본 데미지를 계산
      atk = [attacker.atk - self.pdef / 2, 0].max
      self.damage = atk * (20 + attacker.str) / 20
      # 속성 수정
      self.damage *= elements_correct(attacker.element_set)
      self.damage /= 100
      # 데미지의 부호가 정의 경우
      if self.damage > 0
        # 위기 수정
        if rand(100) < 4 * attacker.dex / self.agi
          self.damage *= 2
          critical_damage = self.damage
          critical_rate = critical_damage * (attacker.dex / self.agi) / 100
          self.damage += critical_rate
          self.critical = true
        end
        # 방어 수정
        if self.guarding?
           atk = [attacker.atk - self.pdef, 0].max
           self.damage = atk * (20 + attacker.str) / 20
        end
      end
      # 분산
      if self.damage.abs > 0
        amp = [self.damage.abs * 15 / 100, 1].max
        self.damage += rand(amp+1) + rand(amp+1) - amp
      end
      # 제2 명중 판정
      eva = 8 * self.agi / attacker.dex + self.eva
      hit = self.damage < 0 ? 100 : 100 - eva
      hit = self.cant_evade? ? 100 : hit
      hit_result = (rand(100) < hit)
    end
    # 명중의 경우
    if hit_result == true
      # 스테이트 충격 해제
      remove_states_shock
#-------------------------------------------------------------------#
# 여길 주목해야지!!!


      self.damage = [self.damage, 9999].min
#-------------------------------------------------------------------#
      # HP 로부터 데미지를 감산
      self.hp -= self.damage
      # 스테이트 변화
      @state_changed = false
      states_plus(attacker.plus_state_set)
      states_minus(attacker.minus_state_set)
    # 미스의 경우
    else
      # 데미지에 "Miss" 를 설정
      self.damage = "Miss"
      # 위기 플래그를 클리어
      self.critical = false
    end
    # 메소드 종료
    return true
  end


 


(def skill_effect 의 경우도, 아까 말한 HP감소 부분 바로 위에다가 "여길 주목해야지!!!"부분을


복사해 넣으시면 됩니다.)


 


위에서도 말했듯이, 무 조 건 9999이상은 넘지 못합니다.


때문에, 궁극기 등을 사용해도 9999의 상한선은 넘지 못합니다.


FFX의 경우, '데미지 한계 돌파'라는 것을 사용해서 그것을 넘을수 있는데요,


우리도 한번 그런것을 만들어 봅시다.


 


self.damage = [self.damage, 9999].min


 


이 부분이 있으므로써, 데미지의 최대값에 제한이 받는 것입니다.


그렇다면 이 부분이 시행되는데 조건을 걸어주면 되겠죠?


 


조건을 거는 방법은 여러가지가 있습니다.


제한에 필요한 것이 x라고 할때,


 


1. 공격자의 속성(=장착된 무기의 속성)x 가 있냐?


2. 사용하는 스킬의 속성x 가 있냐?


3. 스위치x 가 on 이냐?


4. 아이템x 를 회득했냐? (=1개 이상 소지)


 


음....변수의 방법도 있겠지만 귀찮음으로...


일단 4가지의 방법을 소개해 보겠습니다.


(x라는 무기/방어구/악세 를 장비중일때 라는 것도 있지만, 아직 미구현입니다.)


그 중에서도, 속성과 관련된건 번호로 지정하는 방법, 이름으로 지정하는 방법이있으니....


모르는 부분이 있다면 댓글로 달아주세요.


 


 


1-1. 공격자가 20번째 속성이 없을때 데미지 한계 제한


 


  if not (attacker.element_set).include?(20) # 속성 번호를 매겨 주세요.
    self.damage = [self.damage, 9999].min
  end


 


1-2. 공격자가 '연금술사' 속성이 없을때 데미지 한계 제한


 


  if not (attacker.element_set).include?(($data_system.elements).index("연금술사")) # 속성 이름을 적어주세요.
    self.damage = [self.damage, 9999].min
  end


 


2-1. 사용 스킬이 20번째 속성이 없을때 데미지 한계 제한


 


  if not (skill.element_set).include?(20) # 속성 번호를 매겨 주세요.
    self.damage = [self.damage, 9999].min
  end


 


2-2. 사용 스킬이 '연금술사'속성이 없을때 데미지 한계 제한


 


  if not (skill.element_set).include?(($data_system.elements).index("연금술사")) # 속성 이름을 적어주세요.
    self.damage = [self.damage, 9999].min
  end


 


3. 20번째 스위치가 on이 아닐때 데미지 한계 제한


 


  if not $game_switches[20] == true # 스위치 번호를 매겨 주세요.
    self.damage = [self.damage, 9999].min
  end


 


4. 아이템 No.20 이 없을때 데미지 한게 제한


 


  if not $game_party.item_number(20) >= 1 # 아이템 번호를 매겨 주세요.
    self.damage = [self.damage, 9999].min
  end


 


 


위에서 말했듯이, 변수를 이용한 방법은 생략합니다.


사용법은, 위에 있는 1차정리의 '여길 주목해야지!!!'부분에 있는


self.damage = [self.damage, 9999].min에다가 덮어 씌우면 됩니다.


그러면 if조건에 의해 조건이 만족하지 않으면 데미지 한계가 제한되는 것이죠.


 


::: 여기서 '조건이 만족하지 않으면'이란 말을 사용한건, if not 을 썼기 때문입니다. :::


 


 


그럼 2차적으로 정리를 해봅시다.


'데미지 한계 돌파' 라는 속성이 있는 무기를 들면 데미지가 9999를 넘을 수 있는


스크립트 입니다(def attack_effect(attacker) 만).


 


  #--------------------------------------------------------------------------
  # ● 통상 공격의 효과 적용
  #     attacker : 공격자 (버틀러)
  #--------------------------------------------------------------------------
  def attack_effect(attacker)
    # 위기 플래그를 클리어
    self.critical = false
    # 제일 명중 판정
    hit_result = (rand(100) < attacker.hit)
    # 명중의 경우
    if hit_result == true
      # 기본 데미지를 계산
      atk = [attacker.atk - self.pdef / 2, 0]. max
      self.damage = atk * (20 + attacker.str) / 20
      # 속성 수정
      self.damage *= elements_correct(attacker.element_set)
      self.damage /= 100
      # 데미지의 부호가 정의 경우
      if self.damage > 0
        # 위기 수정
        if rand(100) < 4 * attacker.dex / self.agi
          self.damage *= 2
          self.critical = true
        end
        # 방어 수정
        if self.guarding?
          self.damage /= 2
        end
      end
      # 분산
      if self.damage.abs > 0
        amp = [self.damage.abs * 15 / 100, 1]. max
        self.damage += rand(amp+1) + rand(amp+1) - amp
      end
      # 제2 명중 판정
      eva = 8 * self.agi / attacker.dex + self.eva
      hit = self.damage < 0 ?  100 : 100 - eva
      hit = self.cant_evade?  ?  100 : hit
      hit_result = (rand(100) < hit)
    end
    # 명중의 경우
    if hit_result == true
      # 스테이트 충격 해제
      remove_states_shock


#-------------------------------------------------------------------#
# 여길 주목해야지!!!


      if not (attacker.element_set).include?(($data_system.elements).index("데미지 한계 돌파"))


        self.damage = [self.damage, 9999].min


      end
#-------------------------------------------------------------------#
      # HP 로부터 데미지를 감산
      self.hp -= self.damage
      # 스테이트 변화
      @state_changed = false
      states_plus(attacker.plus_state_set)
      states_minus(attacker.minus_state_set)
    # 미스의 경우
    else
      # 데미지에 "Miss" 를 설정
      self.damage = "Miss"
      # 위기 플래그를 클리어
      self.critical = false
    end
    # 메소드 종료
    return true
  end


 


공격자(의 무기)의 속성에 '데미지 한계 돌파'가 존재치 아니하면(?) 데미지 한계 제한을


시행하도록 하는 원리입니다.


 


 


모르는 것이 있다면 언제나 댓글을 달아주소서.


바꿀수 있는 부분이나, 더 좋은 방법이 있다면 역시나 댓글을 달아주세요,


 


 


 


그럼 이번엔 최소값을 설정해 봅시다.


원리는 최대값과 비슷하게, HP로부터 감산하는 부분 바로 위에다가 쓰며,


조건 등을 걸수도 있습니다;;;;; 조건을 걸어봤자 지만..


 


위의 '여길 주목해야지!!!'부분에다가 최대값을 집어 넣었다면


그 바로 아래, HP로부터 감산 하는 부분 바로 위에다가


 


self.damage = [self.damage, 1].max


 


이것을 집어 넣으면 되겠습니다.


데미지가 1보다 크면 데미지를,


데미지가 1보다 작으면 1을


채택하는 방법입니다.


이렇게 함으로써 최소 데미지는 1이 되죠.


 


 


중1 수학에서 나오는 '정수'파트를 공부(복습)해 봅시다.


-100 이 클까요, -1 일 클까요?


네, -1이 큽니다. 참 잘해써여^^


 


이것이 왜 중요하냐!


공격에 대해서 회복이 되는 경우가 있어야 되기 때문이죠!


물론 기본 공격으로 회복하는 일은 없겠지만, 있습니다!!!!


 


상대 캐릭터의 속성 유효도가 F일때, 그 속성으로 공격하면 - 처리가 되어


데미지를 입지 않고, 오히려 회복되게 하는 것이 정상적인 F인데,


 


self.damage = [self.damage, 1].max


 


라는 식을 썼는데, 유효도 F 에 의하여 데미지가 음수가 되면


1이 최대값이기 때문에, 회복이 되지 않고 1의 데미지가 답니다.


 


예를 들면 이런거죠.


 


1. 스켈렌톤한테 암흑 공격을 가했는데 100의 데미지가 아니라 100의 회복이 이루어 졌다! 제길!


2. 스켈렌톤한테 암흑 공격을 가했는데 1의 데미지가 떴다?


 


1번은 원래 그런거고


2번은 저의 최소값 제한 식이 있기 때문에 일어난 현상입니다.


즉, 회복되어야할 공격인데, 회복은 음수 데미지 임으로, 1이 더 커서 1로 설정된다, 라는 것입니다.


(최소값 설정인데 왜 자꾸 최대값, 큰 값 이라고 하냐, 라고 질문 하는사람은 없겠죠;)


 


 


물론, 여기까지 했다면 데미지를 주는 공격에는 최대값, 최소값이 설정됬을 것입니다.


최대값은 조건에 따라서 제한이 되는 것이 됬을터이고,


최소값은 결과적으로 0인 데미지(방어가 심해서)를 1로 바꾸는 것으로 됬을터입니다.


 


음수 데미지 관련은 잠깐 제쳐두고, 여기까지 실행했을때의 예제 전투를 한번 보시겠습니다.


 


[전투 진입]


알키르 공격!


스켈렌톤1은(는) 9999의 데미지를 받았다!


스켈렌톤1 공격!


알키르은(는) 회피했다


알키르 스킬[필살기] 사용!


스켈렌톤1은(는) 29380의 데미지를 받았다!


스켈렌톤1은(는) 죽었다.


스켈렌톤2 슈퍼 가드 시전!


알키르 공격!


스켈렌톤2은(는) 1의 데미지를 받았다!


스켈렌톤2 공격!


알키르은(는) 319의 데미지를 받았다!


알키르 스킬[썬더] 사용!


스켈렌톤2은(는) 9999의 데미지를 받았다!


스켈렌톤2은(는) 죽었다.


[전투 종료]


 


RPG2000의 추억을 생각하면서 써봤습니다(....)


알키르가 공격을 했지만 데미지 제한 때문에 9999의 데미지를 입혔고


필살기를 사용하여 그 제한을 넘었습니다.


한편, 스켈렌톤2는 슈퍼 가드로 인해 방어력이 급상승 하여


알키르의 데미지를 0으로 만들었지만


데미지 최소값 설정으로 인해 1의 데미지를 입혔습니다.


....가 되겠습니다.


 


여기 까지는 문제 없으리라 생각합니다.


 


그럼 잠시 ctrl+a ctrl+c 를 한 후....


 


 


다시 음수 데미지 예기로 넘어가겠습니다.


 


최소값 설정으로, 회복에 대해선 어떤 값이 됬든 양수 1로 전환되는 결과를 일으켰습니다.


1980을 회복해야 되는데 1의 데미지가 입혀진거죠.


이것은 다음과 같은 방법을 쓰면 됩니다.


 


  if self.damage > 0 
    self.damage = [self.damage, 9999].min
    self.damage = [self.damage, 1].max
  elsif self.damage < 0
    self.damage = [self.damage, -9999].max
    self.damage = [self.damage, -1].min
  end


 


데미지가 양수 일때는 그대로 적용되고,


데미지가 음수일때는 1의 회복 최소값과 9999의 회복 최대값이 나오는 것입니다.


왜 그런지 모르시는 분들은 댓글 달아주시기 바랍니다.


 


9999(혹은 -9999) 부분에만 특별한 조건을 붙여주면 완성! 입니다.


물론 스킬 파트에서 HP로부터 감소 하기 직전에 붙여주셔야 합니다;;


 


 


언제나 그렇듯, 이해 안가시는 분들은 그 부분만 댓글 달아주시기 바랍니다.


 


 


 


 


끗~


이렇게 함으로써, FFX 처럼 칠요의 무기라도 있지 않으면 데미지/회복량 이 9999를 넘지


못하는 것이 됬습니다.


 


 


 


 


댓글로 원하시는 조건등을 말해주시면


그 조건에 의해 데미지 한계 제한이 되는 스크립트를 메일 등으로 보내 드리겠습니다.


물론 Game_Battler3에다가 덮어 씌우는 것이며


전투 관련 스크립트가 있다면 안되는 것입니다.


 


 


그 외 기타 등등 필요하신것들, 모르는 것들 전부 댓글로 달아주세요.


 


 


 


Lecture ver 1.0


(1.1 에는 장비의 조건을 구현시키겠습니다.)

?

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
784 언어/기타 blitz basic 리닥터즈 2007.01.11 1201
783 언어/기타 소개글 [산타클로스~수해와 수영] Vermond 2007.01.10 1303
782 RPG Maker 범위 공격 : [y >= x^2] 을 이용 1 file Spegel 2007.01.10 2048
781 언어/기타 [C++] WinAPI를 이용한 GUI 프로그래밍 Zeprod 2007.01.08 1202
780 언어/기타 대기 가다없는 2007.01.08 992
779 RPG Maker [RMXP] 펫 소환 강좌 file 연필군 2007.01.07 635
778 언어/기타 도박 시스템 file 연필군 2007.01.07 566
777 언어/기타 잠입 게임 아이디어 아르킨 2007.01.07 1302
» RPG Maker 데미지의 최소값, 최대값을 설정해보자! ver 1.0 『연금술사』 2007.01.07 1466
775 RPG Maker [RMXP] 벽 소환 이벤트를 만들자 file 연필군 2007.01.06 476
774 RPG Maker 플레이어의 건강을 배려하는 세심한 NPC[용도는...모르겠음-_-] file EverSmileMan 2007.01.02 1293
773 언어/기타 [C++] 객체 지향 프로그래밍 (OOP) -3- Zeprod 2007.01.02 949
772 언어/기타 이번에도 잡담입니다만-_-;; 아란 2007.01.01 1014
771 언어/기타 스크립트를 이용하여 텍스트색상과 갯수를 바꿔보자 ! file 준돌 2006.12.30 575
770 언어/기타 원형 거리 측정 Zeprod 2006.12.30 1206
769 언어/기타 [자료구조] Binary Search Tree Zeprod 2006.12.29 1181
768 언어/기타 [C++] 객체 지향 프로그래밍 (OOP) -2- Zeprod 2006.12.28 901
767 언어/기타 그저 비주얼 베이직에 낚인 것에 대한 잡담 아란 2006.12.27 992
766 RPG Maker 스크립트 실행여부를 알아보거나 스크립트를 봉인시켜보자 1 A. 미스릴 2006.12.26 774
765 언어/기타 스타포지의 추가 설명 다크세이버™ 2006.12.26 441
Board Pagination Prev 1 ... 7 8 9 10 11 12 13 14 15 16 ... 51 Next
/ 51






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

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