총알을 발사 할 때 생기는 애니메이션이 있다고 가정하겠습니다. 애니메이션이 끝날 때 총알이 어떻게 표시됩니까? 내가 알아낼 수있는 유일한 것은 애니메이션의 시간 길이를 알고 총알 위치 설정을 지연시키고 해당 시간이 지날 때까지 활성화하는 것입니다. 이것이 최선의 접근 방법인지 궁금합니다. 다른 사람들이 어떻게 이것을 처리합니까?
편집 : 질문을 올바르게 표현하는 데 문제가 있다고 생각합니다.
총알을 발사 할 때 생기는 애니메이션이 있다고 가정하겠습니다. 애니메이션이 끝날 때 총알이 어떻게 표시됩니까? 내가 알아낼 수있는 유일한 것은 애니메이션의 시간 길이를 알고 총알 위치 설정을 지연시키고 해당 시간이 지날 때까지 활성화하는 것입니다. 이것이 최선의 접근 방법인지 궁금합니다. 다른 사람들이 어떻게 이것을 처리합니까?
편집 : 질문을 올바르게 표현하는 데 문제가 있다고 생각합니다.
답변:
근본적으로 당신은 올바른 길을 가고 있습니다-이런 종류의 일을하기 위해 애니메이션이 얼마나 오래 지속되는지 알아야합니다. 애니메이션은 단순한 프레임 모음이 아니라 필요한 모든 종류의 다른 정보가 있습니다. 예를 들어 얼마나 많은 프레임이 있고 애니메이션 루프가 얼마나 빨리 재생됩니까 (예 : 초당 10 개의 애니메이션 프레임 또는 25 또는 60?). 모든 애니메이션은 몇 가지 데이터로 정의 할 수 있으며, 일부 일반화 된 애니메이션 코드는보고 재생할 수 있습니다. 애니메이션 부분을 자체 코드 비트로 캡슐화해야합니다. 이러한 애니메이션 정의와 개별 이미지 프레임을 표시하는 방법 외에는 아무것도 알지 못합니다. 즉,로드, 재생 시작, 재생 중지 및 화면의 특정 위치에서 렌더링하도록 지시 할 수있는 애니메이션 개체가 있어야합니다.
유연한 접근 방식은 일종의 애니메이션 정의를 사용하여 이러한 종류의 정보를 캡슐화하는 것입니다. 따라서 "애니메이션 X는이 프레임들 전부입니다. 프레임을 통해 재생하십시오"라고 말하는 것이 아니라 좀 더 복잡한 것을 얻게됩니다.
예를 들어 일종의 모형 데이터 형식
애니메이션 = { {name = "walk", files = "walk * .png", frameCount = "12", loop = "true"}, {name = "fire"files = "fire * .png"frameCount = "6", 이벤트 = { {name = "bulletLeavesGun", frame = "4", param1 = "43", param2 = "30"} } } }
따라서 코드는 다음과 같이 말합니다.
currentAnimation = animations.Get("fire");
currentAnimation.Play();
이벤트를 감지하는 방법은 다시 호출하는 애니메이션 코드 (예 : 애니메이션이 특정 프레임에서 재생되어 새 이벤트를 감지 한 경우 새 이벤트에 대해 알려주기 위해 게임 코드를 호출 함)를 사용하거나 다음과 같은 애니메이션 :
List<Event> events = currentAnimation.EventsSinceLastCheck();
foreach (AnimationEvent event in events)
{
if (event.name == "bulletLeavesGun")
{
Vector2 bulletPosition = new Vector2(event.param1, event.param2);
Vector2 actualBulletPosition = new Vector2(
character.x + bulletPosition.x,
character.y + bulletPosition.y);
CreateBulletAt(actualBulletPosition);
}
}
참고 사항 :
애니메이션 내에서 총알 발사가 필요하지 않지만 일단 완료되면 이벤트 개념없이 훨씬 덜 복잡한 시스템으로 도망 갈 수 있습니다. 그러나 애니메이션이 자체적으로 재생되고 시간이 얼마인지 알고 애니메이션이 완료되면 게임 코드를 다시 호출 할 수있는 시스템이 여전히 필요합니다.
어떤 식 으로든 애니메이션이 완료 될 때까지 기다렸다가 해당 지점에서 글 머리 기호를 만들어야합니다.
애니메이션 속도가 고정되어 있다면 타이머를 설정하기 만하면됩니다. 약간의 변형으로, 총알 내부에 코드가 나타나서 보이지 않고 잠시 나타나서 움직일 수 있습니다.
개발 플랫폼에 따라, 애니메이션이 원하는 지점에 도달하는 순간을 정확하게 응답 할 수있는 일종의 애니메이션 업데이트 기능 또는 콜백이있을 수 있습니다. 예를 들어 Flixel을 사용하는 방법입니다.
addAnimationCallback
방법은 소성 엔티티에서 사용될 수 있습니다. 콜백 함수에서, 발사 애니메이션의 현재 프레임이 글 머리 기호 엔티티를 생성해야하는 프레임인지 확인할 수 있습니다. 그렇다면 화면에 글 머리 기호를 추가 할 수 있습니다.
정답 : 플레이어가 '화재'버튼을 눌렀을 때 재생하고 싶은 애니메이션이 있고 재생이 완료된 후 총알이 나오고 있다고 가정합니다. 이상적으로는 애니메이션 시간을 하드 코딩하지 말고 애니메이션이 완료 될 때 (플랫폼에 따라 콜백 함수 등을 사용하여) 글 머리 기호를 발사해야합니다. 지나치게 복잡하지 않은 다른 방법으로는 생각할 수 없습니다.
대체 게임 디자인 답변 : 실제로, 정말 좋은 이유가 없다면, 'fire'버튼을 누르고 총알이 나타나는 것을 지연시키지 않을 것입니다. 애니메이션이 실제로 짧지 않으면 (기본적으로 1 ~ 2 프레임, 최대, 기본적으로 총구 플래시) 발사 버튼 응답이 느리게 느껴지고 일반적인 플레이어에게는 성가 시게됩니다. 글 머리 기호가 나오기 전에 애니메이션을 사용하기로 결정한 경우에도 (턴 기반 RPG 및 전술 게임이이를 허용 할만한 이유가 될 수 있음) "어딘가에 애니메이션 끄기"옵션을 포함하여 플레이어가 원하는 경우 더 빠르게 움직입니다.
MrCranky가 말했듯이; 애니메이션과 논리를 분리하십시오.
그러나 가장 중요한 것은 논리가 마스터 부분으로 남아 있어야한다는 것 입니다.
로직에서 UI를 제어하는 것이 나중에 로직을 유지, 재사용 및 공유 할 수있는 유일한 방법입니다 (렌더러가없는 새 렌더러, 새 게임, 서버 버전 ...).
먼저 이벤트 시스템 (관찰자 패턴?)을 사용하여 코드 조각을 분리합니다. 이것은 애니메이션에만 국한된 것이 아니라 확실히 적용됩니다. 그런 다음 애니메이션 코드는 dispatchEvent (event)라고 간단히 말할 수 있으며 코드의 다른 부분은 코드의 어느 부분도 서로를 알 필요없이 해당 이벤트를 수신합니다.
이제 애니메이션 코드에는 실제로 이벤트 디스패처에 대한 참조가 필요하며 (종속성 주입으로 쉽게 수행됨) 실제로 애니메이션을 정의하는 XML 또는 JSON이 필요합니다. 다음과 같은 것 :
{
animation: {
name: shoot,
length: 12,
spritesheet: shoot.png
event: {
frame: 4,
name: bulletLeavesGun,
},
},
}
애니메이션을로드 할 때 데이터를 읽고 재생 중에 해당 프레임에있을 때 애니메이션 코드가 이벤트를 전달하도록합니다.