현재 캐릭터의 좌표는 x,y로 관리하고 있다.
점프를 하기 위해서는 z축이 필요하다.
하지만 없으므로 가상 z축을 만들기로 하겠다.
물론 가상 z축은 실제로는 y축이다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 |
class Hero : public Object{
private:
HDC hDC;
CGPoint m_srcPos;
CGPoint m_srcSize;
CGPoint m_offset;
int m_iDirection;
int m_iPrevState;
int m_iState;
int m_nFreame;
float m_dFrameDelay;
float m_MoveSpeed;
float m_JumpPower;
float m_fz;
public:
virtual void Init( HBITMAP _m_hResource );
virtual void Render();
virtual void Update( float _dt );
void Animation( float _dt );
void Action( float _dt );
static Hero *Create( HBITMAP _Hero );
}; |
cs |
히어로 클래스의 맴버 변수를 2가지 추가 하도록 하겠다
하나는 가상z축과 또 하나는 점프하는 파워다.
변수명 |
설명 |
m_JumpPower |
점프 하는 힘. |
m_fz |
가상 z축 |
그리고 헤더에 2가지를 정의하겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 |
void Hero::Render()
{
HDC m = ST::Call()->g_hMemDC;
HDC b = ST::Call()->g_hBackBuffer;
CGPoint pos = this->GetPos();
pos.x -= m_offset.x + m_srcPos.x / 2;
pos.y -= m_srcPos.y + m_fz;
SelectObject(m, m_hResource);
BitBlt(b,
pos.x, pos.y,
m_srcPos.x, m_srcPos.y,
m,
m_srcSize.x + m_srcPos.x * m_nFreame, m_srcSize.y + m_srcPos.y,
SRCAND);
BitBlt(b,
pos.x, pos.y,
m_srcPos.x, m_srcPos.y,
m,
m_srcSize.x + m_srcPos.x * m_nFreame, m_srcSize.y,
SRCPAINT);
} |
cs |
가상 z축이지만 실제로는 y축을 이용해야 하기 때문에
점프 키를 누르면 y값이 +됐다가 다시 -되야 한다.
그렇기 때문에 pos.y에 m_fz을 + 해준다. (pos.y -= m_srcPos.y + m_fz;)
이제 상태에 따른 애니메이션을 주도록 하겠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 |
void Hero::Animation( float _dt )
{
if(m_iPrevState != m_iState)
{
m_iPrevState = m_iState;
m_dFrameDelay = 0;
m_nFreame = 0;
}
switch(m_iState)
{
case IDLE:
{
m_srcPos = MakePoint(54,144);
m_srcSize = MakePoint(m_iDirection == RIGHT ? 0 : 610, 10);
m_offset = MakePoint(-m_srcPos.x / 2, -m_srcPos.y);
m_dFrameDelay += _dt;
if(m_dFrameDelay > 0.1f)
{
m_dFrameDelay = 0;
m_nFreame++;
if(m_nFreame >= 4) m_nFreame = 0;
}
break;
}
case WALK:
{
m_srcPos = MakePoint(75,143);
m_srcSize = MakePoint(m_iDirection == RIGHT ? 0 : 610, 310);
m_offset = MakePoint(-m_srcPos.x / 2, -m_srcPos.y);
m_dFrameDelay += _dt;
if(m_dFrameDelay > 0.1f)
{
m_dFrameDelay = 0;
m_nFreame++;
if(m_nFreame >= 8) m_nFreame = 0;
}
break;
}
case JUMP:
{
m_srcPos = MakePoint(85,135);
m_srcSize = MakePoint(m_iDirection == RIGHT ? 0 : 610, 610);
m_offset = MakePoint(-m_srcPos.x / 2, -m_srcPos.y);
m_dFrameDelay += _dt;
if(m_dFrameDelay < 0.1f)
{
m_JumpPower = JUMP_POWER;
m_nFreame = 0;
break;
}
m_fz += m_JumpPower * _dt;
m_JumpPower -= GRAVITY * _dt;
if(m_dFrameDelay > 0.1f) m_nFreame = 1;
if(m_dFrameDelay > 0.2f) m_nFreame = 2;
if(m_dFrameDelay > 0.3f) m_dFrameDelay = 0.1f;
if(m_JumpPower <= 0)
{
m_iState = DROP;
m_JumpPower = 0;
}
break;
}
case DROP:
{
m_srcPos = MakePoint(85,135);
m_srcSize = MakePoint(m_iDirection == RIGHT ? 0 : 610, 610);
m_offset = MakePoint(-m_srcPos.x / 2, -m_srcPos.y);
m_fz -= m_JumpPower * _dt;
m_JumpPower += GRAVITY * _dt;
m_dFrameDelay += _dt;
if(m_fz <= 0)
{
m_fz = 0;
if(m_dFrameDelay > 0.2f) m_nFreame = 5;
if(m_dFrameDelay > 0.3f) m_nFreame = 6;
if(m_dFrameDelay > 0.4f) m_iState = IDLE;
}
else
{
m_nFreame = 3;
if(m_dFrameDelay > 0.1f) m_nFreame = 4;
}
break;
}
}
} |
cs |
점프 상태로 들어왔을 때
1
2
3
4
5
6
7 |
m_dFrameDelay += _dt;
if(m_dFrameDelay < 0.1f)
{
m_JumpPower = JUMP_POWER;
m_nFreame = 0;
break;
} |
cs |
딜레이 시간이 0.1보다 작으면
점프 파워를 700으로 대입해주고 프레임을 0으로 대입시켜준다.
딜레이 시간때문에 이 if문은 다음부터는 실행되지 않게 된다.
1
2 |
m_fz += m_JumpPower * _dt;
m_JumpPower -= GRAVITY * _dt; |
cs |
z값이 = 점프파워(700) * 시간(0.1)
점프파워 = 중력(1500) * 시간(0.1)
시간이 지남에 따라 점프파워는 점점 감소하게 된다.
1
2
3 |
if(m_dFrameDelay > 0.1f) m_nFreame = 1;
if(m_dFrameDelay > 0.2f) m_nFreame = 2;
if(m_dFrameDelay > 0.3f) m_dFrameDelay = 0.1f; |
cs |
처음 점프를 뛰었을때에 프레임이라 생각하면 된다.
1
2
3
4
5 |
if(m_JumpPower <= 0)
{
m_iState = DROP;
m_JumpPower = 0;
} |
cs |
점프 파워가 점점 감소하므로 결국 0보다 작아진다.
0보다 작아지면 점프의 상태를 DROP로 바꿔주어 떨어주는 모션을 준다.
DROP같은 경우는 점프와 비슷하므로 자세한 설명은 생략하겠다.
키를 눌렀을때 점프를 해야되는데 그 키 값을 정해주도록 하자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 |
void Hero::Action( float _dt )
{
CGPoint pos = GetPos();
m_MoveSpeed = 300.0f * _dt;
if( m_iState != JUMP && m_iState != DROP )
m_iState = IDLE;
if(GetAsyncKeyState(VK_RIGHT))
{
pos.x += m_MoveSpeed;
m_iDirection = RIGHT;
if( m_iState != JUMP && m_iState != DROP ) m_iState = WALK;
}
if(GetAsyncKeyState(VK_LEFT))
{
pos.x -= m_MoveSpeed;
m_iDirection = LEFT;
if( m_iState != JUMP && m_iState != DROP ) m_iState = WALK;
}
if(GetAsyncKeyState(VK_UP))
{
pos.y -= m_MoveSpeed;
if( m_iState != JUMP && m_iState != DROP ) m_iState = WALK;
}
if(GetAsyncKeyState(VK_DOWN))
{
pos.y += m_MoveSpeed;
if( m_iState != JUMP && m_iState != DROP ) m_iState = WALK;
}
if(GetAsyncKeyState('C'))
{
if(m_iState != DROP) m_iState = JUMP;
}
this->SetPos(pos.x, pos.y);
} |
cs |
1 |
if( m_iState != JUMP && m_iState != DROP ) |
cs |
모든 키값에 if문 추가.
이 if문을 추가 시켜주면 점프중이나 드롭중일때 상태가 변하지 않으므로
2단 이상의 점프가 불가능 해진다.
1
2
3
4 |
if(GetAsyncKeyState('C'))
{
if(m_iState != DROP) m_iState = JUMP;
} |
cs |
점프 키는 C가 되시겠다.
결과
'API > 이론' 카테고리의 다른 글
캐릭터 이동제한, y축 점프이동거리 감소, 홀드 (0) | 2016.05.02 |
---|---|
메모리 생성을 각 클래스 안으로 넣기. (0) | 2016.04.30 |
싱글턴을 이용한 메인함수의 메모리 버퍼 정리 (0) | 2016.04.30 |
싱글턴 패턴 (0) | 2016.04.30 |
이미지 깜박거림 없앰. (0) | 2016.04.29 |