⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctank.cpp

📁 坦克大战小游戏 控制说明: 玩家1相关控制: A/W/S/D:控制方向 F:开火 1 :玩家1复活 玩家2相关控制: UP/LEFT/RIGHT/DOWN:控制方
💻 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 + -