adsense



[JAVA/slick2d] 2D 슈팅게임 위치즈 스크램블 제작강좌 -step 6-

step 6. 적 캐릭터를 만들겠습니다.

기본은 지금까지 GameObject 상속 클래스를 만드는 것과 동일하며, 적 캐릭터에게 필요한 추가적인 정보를 추가합니다.



img : 캐릭터 이미지
hp : 내구력. 플레이어 총알에 충돌할 때마다 감소합니다.
degree : 이동 각도
speed : 이동 속도
moving : 무빙 스타일
step : 현재 스텝

GameObject를 상속한 Neuroi1 클래스를 만들고, 생성자에서 rsc/game/enemy0.png 파일로 img를 만듭니다.



enemy0.png 이미지에는 7컷의 이미지가 합쳐져 있습니다.
이후 render에서 그려줄 때, 클리핑하여 한 컷씩 그려주면 됩니다.

적 캐릭터의 움직임을 제어하기 위한 기본적인 시나리오를 설정해 보겠습니다.

무빙 1


스텝 1 : x좌표가 190이하가 될 때 까지 일직선으로 왼쪽으로 진행
스텝 2 : x좌표가 350이상이 될 때 까지 대각선으로 후퇴. 발생 y좌표가 240 이하였던 캐릭터는 아래로, 초과인 캐릭터는 위로
스텝 3 : x좌표가 350 이상이 되면 다시 일직선으로 왼쪽으로 진행해 화면 왼쪽 밖으로

무빙 2


스텝 1 : x좌표가 플레이어 x 좌표 이하가 될 때 까지 왼쪽으로 진행. 이때 발생 y좌표가 240 이하면 약간 아래를, 초과면 위를 향한 완만한 사선이다.
스텝 2 : 플레이어 x 좌표 이하가 되었다면 스피드가 0 이하가 될 때 까지 속적으로 스피드를 감속한다.
스텝 3 : 스피드가 0이 되면 degree를 360-degree 값으로 바꾸고(y플립된 사선이 된다), 스피드를 지속적으로 가속하여 오른쪽으로 사라진다.


적캐릭터를 최초 생성하면 무빙 타입을 세트해주고, 그에 맞춰 이동 정보(degree, speed)를 만들어줍니다.
생성자로 받아들이는 방법도 있지만, 가독성을 위해 별개의 setInit 함수를 만들어 지정합니다.


또, 이 정보가 세팅되기 전에는 적 캐릭터가 동작하면 안되므로 isLive라는 변수를 만들어 setInit를 거치기 전에는 render와 update가 동작하지 않도록 막아줍니다.

update에서는 앞에서 설정한 시나리오대로 이동 정보를 변경해줍니다.
시나리오로 보면 복잡해보이지만 결국 조건제어문과 상태변수의 조합일 뿐인데요,


제어문의 설계만 잘 해주면 쉬운 작업이지만, 실수하면 제대로 스텝을 진행하지 못한다던가..

예를 들면

if(step==1 && posX<=190){
step = 2;
}
으로 해 줘서 '스텝 1일 때, x좌표가 190 이하이면'이라는 조건을 만들어야 하는데,

if(posX<=190){
step = 2;
}
이렇게 '스텝 1일 때'를 빼먹어서, 계속해서 step2를 반복하게 됩니다.


매우 흔한 실수인데, 로직을 따라가야 찾을 수 있기 때문에 은근히 찾기 힘들기도 합니다.



이번에 사용하는 이미지가 한 장의 이미지에 모든 프레임이 들어가 있기 때문에 render에서는 클리핑으로 한 장씩 보여줘야 합니다.
기존 awt에서 사용하던 클리핑과 같은 것으로,

- 현재 이미지가 보여야 할 부분에만 클리핑 영역을 설정
Rectangle rect = new Rectangle((int)posX-18, (int)posY-18, 36,36);
g.setClip(rect);


- 전체 이미지 중에서 보여줘야 할 프레임이 있는 부분이 클리핑 영역에 오도록 이미지를 그린다 (18은 프레임 한 장의 가로 세로 폭인 36의 1/2)
g.drawImage(img, posX - ((cnt%21)/3)*36 - 18, posY - 18);

- 클리핑 영역을 화면 전체로 복구한다
g.setClip(0,0, 640,480);

이상의 순서입니다.


이번에는 이렇게 일일이 기술했지만, 클리핑이 필요할 때마다 이 과정을 모두 재코딩하면 낭비가 되니 차후에 범용 함수로 통합할 것입니다.

참고로 drawCenter의 경우, 클리핑된 이미지의 중심점이 아니라 이미지 전체의 중심점에 맞추는 방식이기 때문에 이런 경우에는 쓸 수 없습니다.

slick2d에는 Image 객체로부터 클리핑된 Image를 얻어오는 api가 있습니다.
최종적으로는 클리핑 부분도 이것으로 모두 통합될 것입니다.
step6 소스의 해석에 관해서만 이 부분을 참고해주세요.



이제 GameScene에서 적 캐릭터를 등장시켜보겠습니다.

최종적으로는 적 캐릭터를 등장시키는 일종의 '시나리오'도 별개의 클래스로 만들게 될 것입니다만,(GameObject 만능론)
현재는 update에 임시로 코딩하겠습니다.


적 캐릭터를 등장시키고 싶을 때 Neuroi1 객체를 생성하고, GameScene에 addChild 한 후, y좌표와 무빙 스타일을 지정해서 Neuroi1 객체의 setInit를 호출해주면 됩니다.

생성 테스트에 코딩된 내용을 해설하겠습니다.

//적 캐릭터 생성 테스트
if(cnt%240==150){ cnt가 약 1/60초마다 1씩 카운트되므로 %240은 약 4초 간격이 됩니다.
enemyY = rand.nextFloat()*384.0f + 48; 우선 적을 생성하기 전에 생성에 쓸 y좌표를 준비합니다.
}

if(cnt%240==160||cnt%240==175||cnt%240==190||cnt%240==205||cnt%240==220){
cnt%240이 160, 175, 190... 이 될 때마다 적을 생성합니다. 시간 간격이 짧기 때문에 5개를 줄줄이 생성하게 됩니다.

Neuroi1 enemy = new Neuroi1(this, 680, 0, 0);
addChild(enemy);
enemy.setInit(enemyY, 1); 이때 동일한 y좌표를 사용하므로, 5개가 일렬로 등장하는 효과를 얻게 됩니다. 일종의 편대공격이죠.
}
if(cnt%600==595){
%600이면 10초에 1회의 효과가 있습니다.

Neuroi1 enemy = new Neuroi1(this, 680, 0, 0);
addChild(enemy);
enemy.setInit(rand.nextFloat()*384.0f + 48, 2); 편대 공격에 섞여서 무빙 2를 하는 적이 하나 등장해 변화를 주게 됩니다.
y좌표를 공통 좌표를 쓰지 않으므로 '의표를 찌르는' 공격이 될 수 있습니다.

}


그럼 실행해 봅니다.




핑백

덧글

댓글 입력 영역


Books

Geek라이프

메가 드라이브 퍼펙트 카탈로그
마에다 히로유키 저/조기현 역

미소녀 일러스트 테크닉
B-은하, pen스케, 카와이 저/정유진 역

핵심강좌! Cocos2d-x
이재환 저

피규어의 교과서 레진 키트 & 도색 입문 편
후지타 시게토시 저/김정규 역
예스24 | 애드온2
일본서적 전문사이트 NEPIC