메뉴 건너뛰기

창작에 관련된 질문이나 간단한 팁, 예제를 올리는 곳

11편 : 적의 사망판정

일단 대미지를 입었을 때 처리를 바꿔 봅시다.
워프 하듯이 뒤로 날아가는 것은 아닌 듯 싶으니 말입니다.
일단 대미지를 입었을 때의 상태 하나를 추가합니다.

#define STATE_PAIN  5

대미지를 입었을 때는 아무 것도 못하게 컨트롤도 막습니다.

void Unit::Control()
{
     if(state==STATE_PUNCH || state==STATE_KICK || state==STATE_PAIN)return;
     ......

이제 Action 부분에서 새로운 상태를 추가해 줍니다.
상태에 따라 그림을 바꿔야 할 테니 허접하게 고친 제가 그린 그림을 일단 쓰겠습니다.
그림 잘 그리신 분들은 자연스럽게 고쳐 보시고


(밑에 첨부에서 다운 받으십시오.)

일단 이것을 받고 작업 폴더에 넣으신 후,
그림 불러 오는 곳에서 이것을 추가합니다.

jdd->LoadPicture("고통", "pain.gif", &jpi, true);

그럼 이번엔 Action에서 새로운 동작에 대한 처리를 추가합시다.

//대미지
else if(state==STATE_PAIN)
{
      if(aim == AIM_LEFT)jdd->DrawPicture(backbuffer, "고통", x, y-2, NULL);
            else jdd->DrawPictureEx(backbuffer, "고통", x, y-2, NULL, DPX_HFLIP);

      ++delay;
      if(delay >= 20)state=STATE_NORMAL;

      attack.left = -999;
}

대미지를 입은 상태에서는 '고통' 그림을 보여주면서
delay가 20까지 되면 다시 원래 상태로 돌아갑니다.
즉, 0.2초간 고통스러워 하다가 원래대로 돌아가는 겁니다.

이제 마지막으로 Damage 부분을 바꿉니다.
이전 것은 다 지워 버리고...

void Unit::Damage(bool hit_aim)
{
     state = STATE_PAIN;
}

이렇게 상태 변화만 넣어주고 실행시켜 보면...
아니? 이게 왠 일! 적이 맞아도 전혀 반응을 하지 않습니다.
어디가 잘못 된 걸까요?
그건 Control만 고치고 AI는 고치지 않았기 때문입니다.
AI에도 고통 상태에서는 아무것도 못 하게 고쳐줍시다.

void Unit::AI(int hero_x, int hero_y)
{
     if(state==STATE_PAIN)return;
     ......

AI와 주인공 캐릭터의 공통되는 사항은 나중에 하나로 묶어서 따로 분리해야 할 듯 싶습니다.
아무튼 여기까지 했다면 맞을 때마다 얼굴 색이 변하는 적을 볼 수 있습니다.



이젠 불사인 적이 지겨우니 죽도록 해봅시다.
Unit 클래스에 hp를 추가합니다.

class Unit
{
private:
      ......
      int hp;    //체력

public:
      ......
}

그리고 생성할 때 초기값은 8.

Unit::Unit(int x, int y, int speed)
{
      ......
      hp = 8;
}

그리고 맞을 때마다 1씩 깎입니다.

void Unit::Damage(bool hit_aim)
{
      state = STATE_PAIN;
      --hp;
}

hp를 알아낼 수 있는 GetHP도 추가합니다.
이건 알아서 하세요.

마지막으로 hp가 없을 때는 아무것도 처리하지 않게
메인 루프를 바꿉니다.

while(!GetKey(vkey_esc))
{
      if(!ProcessMessage())break;

      jdd->DrawPicture(backbuffer, "배경", 0, 0, NULL);

      hero.Control();
      if(enemy.GetHP()>0)enemy.AI(hero.GetX(), hero.GetY());

      hero.Action();
      if(enemy.GetHP()>0)enemy.Action();

      //충돌 검사
      if(enemy.GetHP()>0)
      {
            RECT attack = hero.GetAttackRect();
            RECT body = enemy.GetBodyRect();

            if(attack.left != -999)      //공격영역이 존재할 때
            {
                  if(attack.right >= body.left && attack.left <= body.right && attack.bottom >= body.top && attack.top <= body.bottom)
                  {
                        enemy.Damage(hero.GetAim());                                         
                  }
            }
      }

      jdd->Render();
}

곧 hp가 1이상이 되지 않으면 AI가 작동하지도 않고
움직이지도 보이지도 않는다는 것이죠.
충돌 검사도 하지 않습니다. 즉, 존재하지 않게 되는 겁니다.

한번 실행해 봅시다.
그런데 이상한 증상을 발견할 수 있습니다.
엥? 2대만 때렸는데 사라져 버리네?
분명히 hp가 8이니 8대를 맞고 사라져야 할 텐데 왜 2대에 사라져 버리는 걸까요?

그것은 중복해서 대미지를 입고 있기 때문입니다.
펀치를 내밀고 있는 동안 지속적으로 대미지를 주기 때문에 2대 정도에 적이 죽어버리고 마는 겁니다.
한번의 펀치에 한번만 대미지를 입도록 Damage 부분을 바꿔 봅시다.

void Unit::Damage(bool hit_aim)
{
      if(state != STATE_PAIN)
      {
            state = STATE_PAIN;
            --hp;
      }
}

이제 대미지 입은 상태에서 또 대미지를 입지 않을 겁니다.
다시 실행해서 테스트 해봅시다. 정확히 8대에... 8대에...
엥? 똑같이 1,2대에 죽습니다.
도대체 뭐가 잘못 된 걸까요? 으아아악!
이런 버그로 이렇게 공황상태에 빠질 수도 있습니다.
그래서 디버깅을 가르쳐 드리고 싶지만 그건 글로 적기엔 힘들 것 같군요.
아무튼 원인은 무엇이냐?
바로 Action 부분에 있습니다.
Action에서는 delay가 20이상 되면 다시 원래 상태로 돌리는데,
바로 이 delay를 대미지 입었을 때 초기화를 안 한게 문제였습니다.
펀치나 킥을 날릴 때는 확실히 초기화하고 있는데 말이죠.

추가합시다.

void Unit::Damage(bool hit_aim)
{
      if(state != STATE_PAIN)
      {
            state = STATE_PAIN;
            --hp;
            delay=0;
      }
}

이렇게 여러 트러블을 겪으면서 고쳐 나가다 보면
드디어 8대에 아름답게 사라지는 적을 볼 수 있습니다.

죽는 애니메이션을 넣고 싶으시면
새로운 STATE_DIE 같은 것을 넣고,
그 상태에서는 조종과 충돌검사가 안 되게 한 뒤
일방적으로 애니메이션을 보여준뒤 사라지게 하면 됩니다.
이건 그래픽 재료도 없고 하니 도전과제로 남기겠습니다.

조회 수 :
4647
등록일 :
2008.05.17
20:20:42 (*.239.144.2)
엮인글 :
게시글 주소 :
https://hondoom.com/zbxe/index.php?mid=study&document_srl=199799
List of Articles
번호 제목 글쓴이 조회 수 추천 수 날짜 최근 수정일sort
25 RPG Maker MV 로컬라이징 방법 file 똥똥배 927   2015-10-27 2015-10-27 05:51
 
24 김프로 이미지 맵 만들기 노루발 393   2015-11-11 2015-11-11 08:05
https://docs.gimp.org/en/plug-in-imagemap.html  
23 Love2d 게임 중간에 광고 표시 [1] 노루발 377   2015-11-12 2015-11-17 00:16
http://love2d.org/forums/viewtopic.php?f=11&t=81224  
22 Love2d DPI 이슈 해결 [3] 노루발 97   2019-06-29 2019-07-01 06:34
이런 love 프로젝트가 있다고 하자. (conf.lua) function love.conf(t) t.window.width = 640 t.window.height = 360 end 창 크기를 640*480으로 설정한 뒤 실행하면 어떻게 보일까? 당연히 창 크기가 640*480 크기로 보여야겠지만 내 컴퓨터에서는 이렇게 보...  
21 Windows To Go와 R-Studio를 이용한 손실된 데이터 복구하기 노루발 90   2020-01-30 2020-01-30 19:52
하기의 복구 방법으로 모든 자료를 100% 복구할 수는 없으므로 자료의 손실 이전에 신뢰성 있고 주기적인 백업이 선행되어야 한다. 준비물: - 부팅 USB 혹은 외장 HDD/SSD - 복구한 자료를 저장할 외부 저장장치 (옵션) - R-Studio https://www.r-studio.com/ ...  
20 Lua 인수로 nil값이 들어왔을 경우 처리하기 노루발 62   2020-11-06 2020-11-06 20:29
or 연산자를 사용한다. 예제 코드: function moveplayer(direction) direction = direction or "nowhere" print("player moved to ".. direction) end moveplayer() --> "player moved to nowhere" moveplayer("north") -- "player moved to north" 이런 코드...  
19 Lua 테이블 안에 함수 저장하기 노루발 28   2020-11-06 2020-11-06 21:07
테이블 안에 함수를 저장할 수 있다. function move(object, direction) print(object .. " moved to ".. direction) end scheduler = {} scheduler.queue = {} function scheduler.newentry(action, args) scheduler.queue[#scheduler.queue + 1] = {} schedu...  
18 Lua 클래스 만들고 활용하기 노루발 24   2020-11-06 2020-11-06 22:43
------------------------ stairs.lua ------------------------ Stairs = {} function Stairs:new(x, y, floor, direction, locked) local newStairs = {x = x, y = y, floor = floor, direction = direction, locked = locked} self.__index = self retur...  
17 특정좌표를 기준으로 zoom in/zoom out하기 노루발 59   2020-11-11 2020-11-11 01:22
-- x,y - 줌인/줌아웃시 기준점 (좌표 이동이나 scale에 영향받지 않는 순수한 화면 좌표) -- scale - 현재 scale(1:그대로 0.5:1/2 사이즈 2:2배 사이즈) -- scaleinc - 얼마나 scale을 변화시킬것인가 (I usually use 0.1 or -0.1) -- camx - 카메라의 x좌표...  
16 love2d에서 안드로이드 터치 제스처 인식하기 노루발 20   2020-11-12 2020-11-12 00:38
-- 안드로이드/iOS 등등의 터치스크린 입력을 받는 기기에서는 총 3가지의 콜백 함수를 사용한다: -- love.touchpressed / love.touchmoved / love.touchreleased -- 다만 위 3가지 함수는 마우스 클릭으로는 발생하지 않으므로 추가적인 처리가 필요하다. -- ...  
15 이쁜 눈나가 유니티 개발 알려주는 재생목록 노루발 37   2020-11-12 2020-11-12 05:59
https://www.youtube.com/watch?v=Ur2jN6_si6c&list=PLi-ukGVOag_1lNphWV5S-xxWDe3XANpyE https://www.youtube.com/watch?v=sJClf9S7AMA&list=PLi-ukGVOag_0HR09oTs966Wt81IYYXlFH 유니티를 배우고 있는 건 아닌데 만들어진 라이브러리를 다루는게 아...  
14 턴 기반 시스템 구현에 대한 글 [4] 노루발 440   2020-11-14 2020-11-18 05:49
플레이어와 NPC들의 모든 행동에 1턴이 소요된다면 턴 기반 시스템의 구현이 쉽겠지만 (사실 엄청 쉽지는 않다... 게임엔진은 실시간으로 돌아가는데 행동은 턴으로 제약해야 하니) 전략성을 요구하기 위해 행동에 소모되는 턴을 다르게 설정한다면 다소 생각...  
13 루아 스타일 가이드 노루발 34   2020-11-19 2020-11-19 00:58
http://lua-users.org/wiki/LuaStyleGuide https://github.com/Olivine-Labs/lua-style-guide  
12 Love2d 이미지 하얗게 그리기 노루발 42   2020-11-23 2020-11-23 04:11
아래와 같은 코드를 사용해 이미지에 색상을 적용할 수 있다. hamster = love.graphics.newImage("hamster.png") love.graphics.setColor(1, 0, 0) -- 빨간색으로 그리기 love.graphics.draw(hamster) love.graphics.setColor(1, 1, 1) 하지만 이미지를 하얗게...  
11 Love2d로 만든 로그라이크 예제 노루발 253   2020-11-30 2020-11-30 22:54
https://gitlab.com/Jalexander39/roguelikedev-does-the-complete-roguelike-tutorial 이걸 왜 여태 몰랐지...  
10 Oracle cloud에 Nginx/MariaDB 설치하기 노루발 93   2020-12-06 2020-12-06 20:19
https://itreport.tistory.com/624  
9 리캡챠 적용 [1] 노루발 11   2021-01-08 2021-01-11 12:15
XE 회원가입 시 구글 리캡챠 인증 추가하기 : 네이버 블로그 (naver.com)  
8 자동화된 Lua 스크립트의 문서화 - LDoc 노루발 43231   2021-01-11 2021-01-11 11:53
다운로드 https://github.com/lunarmodules/LDoc penlight 설치가 필요 luarocks install penlight 프로젝트가 있는 폴더에서 아래의 명령행을 실행 lua /path/to/ldoc/ldoc.lua $* https://stevedonovan.github.io/ldoc/manual/doc.md.html 문서 코멘트라는걸...  
7 Love2d 게임 안드로이드로 패키징하기 노루발 49   2021-01-11 2021-02-21 01:45
http://hondoom.com/zbxe/index.php?mid=study&document_srl=797993 버전이 바뀌면서 빌드 방법이 바뀌었기에 다시 정리한다. 1. Android studio 설치 https://developer.android.com/studio/index.html SDK 플랫폼 - Android 11.0 [API 30] SDK 버전 - An...  
6 certbot을 이용한 HTTPS 인증서 발급 및 적용 노루발 18   2021-01-12 2021-01-12 16:57
snap 설치 및 업데이트 sudo snap install core; sudo snap refresh core certbot 설치 sudo snap install --classic certbot 심볼릭 링크 생성 sudo ln -s /snap/bin/certbot /usr/bin/certbot nginx에 맞춰 자동 설정 sudo certbot --nginx 알아서 다 해주기...