메뉴 건너뛰기

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

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 Lua 소코반 EX: 포팅: 3 (머나먼 여행길 안녕 친구여) 노루발 913   2013-09-18 2013-09-18 08:05
안녕하세요, 노루발입니다. 오늘로 그래픽 소코반을 끝내기로 했습니다. 아쉽지만 끝내야죠. 일단 걸음수와 이것저것을 뿌려주기로 합니다. 그런데 이미 화면이 꽉 차버려서 뿌려줄 공간이 없네요... 없으면 만들면 되지. 창을 늘립시다. conf.lua를 수정. fun...  
24 CCTextFieldTTF 0바이트 메모리 누수 버그 해결법 똥똥배 692   2014-01-13 2014-01-13 10:38
CCTextFieldTTF::textFieldWithPlaceHolder("", FONT_NAME, FONT_SIZE); 이런 식으로 텍스트필드를 생성하면 ""가 0바이트라서 해체를 못하고 0바이트 누수가 발생한다. 그냥 스페이스(" ")라도 넣어주면 누수는 발생하지 않는다. 이 버그가 발생하는 버전은 2...  
23 Cocostudio의 ActionNode 메모리 누수 해결법(cocos2d-x 2.2.2) [2] 똥똥배 776   2014-03-09 2014-05-31 19:26
Cocostudio로 액션을 만들고 액션매니저를 이용해서 ActionManager::shareManager()->playActionByName 아래와 같이 실행을 해주면 액션이 실행되는 경우 메모리 누수가 발생한다. (액션을 실행하지 않았을 때는 메모리 누수 없음) 이 메모리 누수를 없애려면 ...  
22 cocos2d-x 2.2.2 윈도우 환경 기본 메모리 누수 똥똥배 640   2014-03-10 2014-03-11 03:51
cocos2d-x 2.2.2를 윈도우에서 실행시키고 나서 종료하면 기본으로 4바이트의 메모리 누수가 발생한다. 이건 CCScriptEngineManager가 원인인데 CCObject들은 delete를 실행할 때마다 CCScriptEngineManager의 sharedManager를 호출하기 때문이다. 결국 모든 C...  
21 cocos2d-x 2.2.2 UILabelBMFont 메모리 누수 해결법 [2] 똥똥배 783   2014-03-10 2014-05-31 19:30
만약 CocoStudio로 UI를 만든 후 GUIReader를 써서 지정 폰트를 불러오면 엔진 버그로 인해서 메모리 누수가 생긴다. 이걸 고치려면 LabelBMFont.cpp를 아래와 같이 수정해야 한다. void LabelBMFont::setFntFile(const char *fileName) { if (!fileName || st...  
20 cocos2d-x 2.2.2 문자열 출력 버그 [2] 똥똥배 602   2014-06-10 2014-08-23 22:35
cocos2d-x 2.2.2, 맥에서만 나타는 문제다. 윈도우, 안드로이드에서는 아무 이상 없다. 줄 수가 꽤 긴 문자열을 출력할 경우, 문자가 전부 다 나오지 않고 잘린다. 잘리는 기준은 줄이다. 문자 수가 어떻든 간에 줄 수에 따라서 잘려버린다. 아마 문자열의 줄 ...  
19 Love2d 게임 중간에 광고 표시 [1] 노루발 377   2015-11-12 2015-11-17 00:16
http://love2d.org/forums/viewtopic.php?f=11&t=81224  
18 구글 인앱 구매 Soomla로 구현해본 후 팁 똥똥배 577   2014-09-20 2014-09-20 18:45
1. 일단 알파 테스트라도 앱을 출시시켜야 인앱이 작동한다. 그리고 APK 업로드 후에 바로 인앱이 적용되지 않는다. 구글에 게시되는 데, 시간이 걸리므로 인앱 등록 - APK 등록을 마친 후 다음날부터 구현하는 게 깔끔하다. 이걸로 모르고 하루종일 왜 안되나...  
17 Love2d 여러 플랫폼으로 빌드 자동화 노루발 470   2014-11-12 2014-11-12 17:35
https://github.com/MisterDA/love-release/blob/master/README.md http://www.ambience.sk/lua-love2d-game-distribution/  
16 Love2d 안드로이드 빌드하기 노루발 575   2014-12-15 2014-12-15 00:59
Love2d의 안드로이드 포트는 알파 단계입니다. 차차 개선되어 나가긴 하겠지만 아직 불안정한 부분이 많으며, 일어날 수 있는 오작동과 그로 인한 결과는 일절 책임지지 않습니다.   이 문서는 Windows 사용자 기준입니다. Linux나 Mac을 사용할 정도의 내공...  
15 Love2d 안드로이드 게임 패키징하기 [3] 노루발 550   2014-12-15 2021-01-11 12:11
이 문서는 개발 환경이 갖추어져 있는 상태이고, 빌드를 무사히 마친 뒤라고 가정합니다. 또한 이 문서는 https://bitbucket.org/MartinFelis/love-android-sdl2/wiki/Game%20Packaging#markdown-header-how-to-package-the-apk-with-your-own-love-090-game ...  
14 [번역] gamedev레딧의 Getting Started 문서 번역 [5] priling 1893   2014-12-26 2018-07-24 10:33
처음인 분들을 위한 '게임만들기' 가이드이 글은 [레딧 게임개발 커뮤니티의 /u/LordNed님의 포스팅]을 베이스로 작성한 것입니다. 이 글의 목적은 게임을 만들고 싶어하는 분들이 어떻게 시작할 수 있을지에 대해 명확한 가이드라인을 보여드리는 것입니다.  ...  
13 김프로 이미지 맵 만들기 노루발 393   2015-11-11 2015-11-11 08:05
https://docs.gimp.org/en/plug-in-imagemap.html  
12 RPG Maker MV 로컬라이징 방법 file 똥똥배 927   2015-10-27 2015-10-27 05:51
 
11 리캡챠 적용 [1] 노루발 11   2021-01-08 2021-01-11 12:15
XE 회원가입 시 구글 리캡챠 인증 추가하기 : 네이버 블로그 (naver.com)  
10 자동화된 Lua 스크립트의 문서화 - LDoc 노루발 43235   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 문서 코멘트라는걸...  
9 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...  
8 certbot을 이용한 HTTPS 인증서 발급 및 적용 노루발 20   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 알아서 다 해주기...  
7 PHP로 웹게임 만드는 영상 [1] 노루발 490   2021-06-25 2022-01-28 03:40
Simple PHP Strategy Game - YouTube  
6 Lua-love2d TCP 통신 [1] 노루발 25   2023-07-14 2023-07-22 16:19
서버: Lua 클라이언트: Love2d(Lua) 서버 구동에는 luasocket 라이브러리가 필요하며, luarocks로 설치할 수 있음. 별도 패키지 관리자가 있는 리눅스 시스템에서는 apt-get install lua-socket 등의 패키지 관리자 명령어로 설치 가능하며 Windows에서 구동시...