📄 ctank.cpp
字号:
//----------------------------------------------------------------------------
// 文件名: CTank.cpp
//
// 描述:用于坦克对象实现
//
// 作者:朱波 创建日期:2007-03-19
//----------------------------------------------------------------------------
#include <windows.h> // include important windows stuff
#include <windowsx.h>
#include <mmsystem.h>
#include <iostream.h> // include important C/C++ stuff
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>
#include <sys/timeb.h>
#include <time.h>
#include <vector>
#include <string>
using namespace std;
#include <ddraw.h>
#include <dsound.h>
#include "dxtools.h"
#include "CTank.h"
CTank::CTank()
{
m_lpMapRegion = NULL;
m_lpGeometryVec = NULL;
m_draw_width = 0;
m_draw_hight = 0;
m_draw_lppSurface = NULL;
m_curDirect = 0;
m_tankKind = 0;
m_mySlugID = 0;
m_myGeometryID = 0;
m_moveStep = 2;
}
CTank::~CTank()
{
}
int CTank::Create(int kind, int direct, POINT pos,
LPDIRECTDRAWSURFACE7 lpSurface[], const RECT * lpMapRegion,
vector<GEOMETRY> *lpGeometryVec)
{
int width;
int height;
if ( kind < 0 || kind > TANK_KIND_NUM - 1 )
{
kind = abs(kind)%TANK_KIND_NUM;
}
if ( direct < 0 || direct > TANK_PIC_CELL_COUNT - 1 )
{
direct = abs(direct)%TANK_PIC_CELL_COUNT;
}
width = (direct%2 == 0) ? TANK_WIDTH : TANK_HEIGHT;
height = (direct%2 == 0) ? TANK_HEIGHT : TANK_WIDTH;
m_tankKind = kind;
m_curDirect = direct;
if ( !CanPutThere(pos, lpMapRegion, lpGeometryVec) )
{
return(0);
}
if ( pos.x - TANK_PIC_CELL_WIDTH/2 < 0 )
{
pos.x = TANK_PIC_CELL_WIDTH/2;
}
if ( pos.x + TANK_PIC_CELL_WIDTH/2 > SCREEN_WIDTH-1)
{
pos.x = SCREEN_WIDTH - TANK_PIC_CELL_WIDTH/2 - 1;
}
if ( pos.y - TANK_PIC_CELL_HEIGHT/2 < 0)
{
pos.y = TANK_PIC_CELL_HEIGHT/2;
}
if ( pos.y + TANK_PIC_CELL_HEIGHT/2 > SCREEN_HEIGHT-1)
{
pos.y = SCREEN_HEIGHT - TANK_PIC_CELL_HEIGHT/2 - 1;
}
MakeBoundingBox( direct, pos, m_boundingBox );
if ( NULL != lpMapRegion )
{
m_lpMapRegion = (RECT *) lpMapRegion;
if ( m_boundingBox.left < lpMapRegion->left )
{
m_boundingBox.left = lpMapRegion->left + 1;
pos.x = m_boundingBox.left + width/2 + 1;
}
if ( m_boundingBox.right > lpMapRegion->right)
{
m_boundingBox.right = lpMapRegion->right - 1;
pos.x = m_boundingBox.right - width/2 + 1;
}
if ( m_boundingBox.top < lpMapRegion->top )
{
m_boundingBox.top = lpMapRegion->top + 1;
pos.y = m_boundingBox.top + height/2 + 1;
}
if ( m_boundingBox.bottom > lpMapRegion->bottom )
{
m_boundingBox.bottom = lpMapRegion->bottom - 1;
pos.y = m_boundingBox.bottom - height/2 + 1;
}
MakeBoundingBox( direct, pos, m_boundingBox );
}
m_draw_start.x = pos.x - TANK_PIC_CELL_WIDTH/2;
m_draw_start.y = pos.y - TANK_PIC_CELL_HEIGHT/2;
if ( NULL != lpGeometryVec )
{
m_lpGeometryVec = lpGeometryVec;
}
m_position.x = pos.x;
m_position.y = pos.y;
m_draw_lppSurface = lpSurface;
return(1);
}
int CTank::Draw( void )
{
DDraw_Draw_Surface(m_draw_lppSurface[m_tankKind*TANK_PIC_CELL_COUNT+m_curDirect],
m_draw_start.x, m_draw_start.y, TANK_PIC_CELL_WIDTH, TANK_PIC_CELL_HEIGHT, lpddsback,1);
return(1);
}
int CTank::MakeBoundingBox( int direct, POINT pos, RECT & box )
{
int width = (direct%2 == 0) ? TANK_WIDTH : TANK_HEIGHT;
int height = (direct%2 == 0) ? TANK_HEIGHT : TANK_WIDTH;
box.left = pos.x - width/2;
box.right = pos.x + width/2;
box.top = pos.y - height/2;
box.bottom = pos.y + height/2;
return(1);
}
int CTank::Move()
{
switch (m_curDirect)
{
case 0:
m_position.x += m_moveStep;
break;
case 1:
m_position.y += m_moveStep;
break;
case 2:
m_position.x -= m_moveStep;
break;
case 3:
m_position.y -= m_moveStep;
break;
default:
return(0);
break;
}
MakeBoundingBox( m_curDirect, m_position, m_boundingBox );
m_draw_start.x = m_position.x - TANK_PIC_CELL_WIDTH/2;
m_draw_start.y = m_position.y - TANK_PIC_CELL_HEIGHT/2;
return(1);
}
int CTank::SetDirect( int direct )
{
RECT test_boundingBox;
if ( direct < 0 || direct > TANK_PIC_CELL_COUNT - 1 )
{
direct = abs(direct)%TANK_PIC_CELL_COUNT;
}
MakeBoundingBox( direct, m_position, test_boundingBox);
if ( test_boundingBox.left <= m_lpMapRegion->left
|| test_boundingBox.right >= m_lpMapRegion->right
|| test_boundingBox.top <= m_lpMapRegion->top
|| test_boundingBox.bottom >= m_lpMapRegion->bottom )
return(0);
int src_left = test_boundingBox.left;
int src_right = test_boundingBox.right;
int src_top = test_boundingBox.top;
int src_bottom = test_boundingBox.bottom;
int dest_left, dest_right, dest_top, dest_bottom;
for (vector<GEOMETRY>::iterator it=m_lpGeometryVec->begin();
it!=m_lpGeometryVec->end(); it++)
{
if (it->m_lpBoundingBox != &m_boundingBox)
{
dest_left = it->m_lpBoundingBox->left;
dest_right = it->m_lpBoundingBox->right;
dest_top = it->m_lpBoundingBox->top;
dest_bottom = it->m_lpBoundingBox->bottom;
if ( ( (src_left >= dest_left && src_left <= dest_right)
|| (src_right >= dest_left && src_right <= dest_right) )
&& ( (src_top >= dest_top && src_top <= dest_bottom)
|| (src_bottom >= dest_top && src_bottom <= dest_bottom) ) )
{
return(0);
}
}
}
m_curDirect = direct;
MakeBoundingBox( m_curDirect, m_position, m_boundingBox );
return(1);
}
int CTank::GetDirect( void )
{
return m_curDirect;
}
int CTank::SetTankKind( int kind )
{
if ( kind < 0 || kind > TANK_KIND_NUM - 1 )
{
kind = abs(kind)%TANK_KIND_NUM;
}
m_tankKind = kind;
return(1);
}
int CTank::GetTankKind( void )
{
return m_tankKind;
}
int CTank::TestMoving( void )
{
POINT test_pos;
RECT test_boundingBox;
test_pos.x = m_position.x;
test_pos.y = m_position.y;
test_boundingBox.bottom = m_boundingBox.bottom;
test_boundingBox.left = m_boundingBox.left;
test_boundingBox.right = m_boundingBox.right;
test_boundingBox.top = m_boundingBox.top;
switch (m_curDirect)
{
case 0:
test_pos.x += m_moveStep;
break;
case 1:
test_pos.y += m_moveStep;
break;
case 2:
test_pos.x -= m_moveStep;
break;
case 3:
test_pos.y -= m_moveStep;
break;
default:
return(0);
break;
}
MakeBoundingBox( m_curDirect, test_pos, test_boundingBox );
if ( NULL != m_lpMapRegion )
{
if ( test_boundingBox.left <= m_lpMapRegion->left
|| test_boundingBox.right >= m_lpMapRegion->right
|| test_boundingBox.top <= m_lpMapRegion->top
|| test_boundingBox.bottom >= m_lpMapRegion->bottom )
{
return(0);
}
}
if ( NULL != m_lpGeometryVec )
{
int src_left = test_boundingBox.left;
int src_right = test_boundingBox.right;
int src_top = test_boundingBox.top;
int src_bottom = test_boundingBox.bottom;
int dest_left, dest_right, dest_top, dest_bottom;
for (vector<GEOMETRY>::iterator it=m_lpGeometryVec->begin();
it!=m_lpGeometryVec->end(); it++)
{
if (it->m_lpBoundingBox != &m_boundingBox &&
it->m_style != GS_PLAYER_SLUG && it->m_style != GS_COMPUTER_SLUG )
{
dest_left = it->m_lpBoundingBox->left;
dest_right = it->m_lpBoundingBox->right;
dest_top = it->m_lpBoundingBox->top;
dest_bottom = it->m_lpBoundingBox->bottom;
if ( ( (src_left >= dest_left && src_left <= dest_right)
|| (src_right >= dest_left && src_right <= dest_right) )
&& ( (src_top >= dest_top && src_top <= dest_bottom)
|| (src_bottom >= dest_top && src_bottom <= dest_bottom) )
|| ( (dest_left >= src_left && dest_left <= src_right)
|| (dest_right >= src_left && dest_right <= src_right) )
&& ( (dest_top >= src_top && dest_top <= src_bottom)
|| (dest_bottom >= src_top && dest_bottom <= src_bottom) ) )
{
return(0);
}
}
}
}
return(1);
}
RECT & CTank::GetBoundingBox( void )
{
return m_boundingBox;
}
int CTank::Fire( CSlug **lppSlug, LPDIRECTDRAWSURFACE7 slug_surface[] )
{
int time;
int temp_direct;
POINT pos;
int width, height;
m_cur_time=GetTickCount()%100000;
if(m_cur_time - m_pre_time_fire<0)
time = 100000 - m_pre_time_fire + m_cur_time;
else
time = m_cur_time - m_pre_time_fire;
if ( time > 1000)
{
m_pre_time_fire = m_cur_time;
*lppSlug = new CSlug();
if ( NULL == *lppSlug )
{
PostMessage(main_window_handle,WM_QUIT,0,0);
return(0);
}
switch (m_curDirect)
{
case 0:
pos.x = m_position.x + TANK_WIDTH/2;
pos.y = m_position.y;
break;
case 1:
pos.x = m_position.x;
pos.y = m_position.y + TANK_WIDTH/2;
break;
case 2:
pos.x = m_position.x - TANK_WIDTH/2;
pos.y = m_position.y;
break;
case 3:
pos.x = m_position.x;
pos.y = m_position.y - TANK_WIDTH/2;
break;
default:
delete *lppSlug;
*lppSlug = NULL;
return(0);
break;
}
(*lppSlug)->Create( m_curDirect, pos, slug_surface,
(const RECT *)m_lpMapRegion, m_lpGeometryVec);
return(1);
}
else
{
*lppSlug = NULL;
return(0);
}
}
BOOL CTank::CanPutThere( POINT pos, const RECT *lpMapRegion,
vector<GEOMETRY> * lpGeometryVec )
{
RECT temp_box;
MakeBoundingBox( m_curDirect, pos, temp_box );
if ( temp_box.left <= lpMapRegion->left ||
temp_box.right >= lpMapRegion->right ||
temp_box.top <= lpMapRegion->top ||
temp_box.bottom >= lpMapRegion->bottom )
return FALSE;
int src_left = temp_box.left;
int src_right = temp_box.right;
int src_top = temp_box.top;
int src_bottom = temp_box.bottom;
int dest_left, dest_right, dest_top, dest_bottom;
for (vector<GEOMETRY>::iterator it=lpGeometryVec->begin();
it!=lpGeometryVec->end(); it++)
{
dest_left = it->m_lpBoundingBox->left;
dest_right = it->m_lpBoundingBox->right;
dest_top = it->m_lpBoundingBox->top;
dest_bottom = it->m_lpBoundingBox->bottom;
if ( ( (src_left >= dest_left && src_left <= dest_right)
|| (src_right >= dest_left && src_right <= dest_right) )
&& ( (src_top >= dest_top && src_top <= dest_bottom)
|| (src_bottom >= dest_top && src_bottom <= dest_bottom) )
|| ( (dest_left >= src_left && dest_left <= src_right)
|| (dest_right >= src_left && dest_right <= src_right) )
&& ( (dest_top >= src_top && dest_top <= src_bottom)
|| (dest_bottom >= src_top && dest_bottom <= src_bottom) ) )
{
return FALSE;
}
}
return TRUE;
}
POINT & CTank::GetPosition( void )
{
return m_position;
}
int CTank::SetPosition( POINT & pos )
{
if ( ! CanPutThere( pos, m_lpMapRegion, m_lpGeometryVec ) )
{
return(0);
}
m_position.x = pos.x;
m_position.y = pos.y;
MakeBoundingBox( m_curDirect, m_position, m_boundingBox );
m_draw_start.x = m_position.x - TANK_PIC_CELL_WIDTH/2;
m_draw_start.y = m_position.y - TANK_PIC_CELL_HEIGHT/2;
return(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -