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

📄 gamewnd.c

📁 brew中有关sprite的应用,典型碰撞的方法,适合初学者.
💻 C
字号:
#include "GameWnd.h"

#include "AEEStdLib.h"
#include "AEEAppGen.h"

#include "fruit_res.h"
#include "fruit.h"
#include "commondef.h"





#define SCORE_START_X		9
#define DIGIT_WEIGHT		7
#define PIC_WIDTH           8

//rgCmds中各种对象的索引
#define SPRITE_DIGIT		25
#define SPRITE_FRUIT        0
#define SPRITE_BAR          4
//各种对象的源图像贴索引
#define PIC_START_DIGIT	    6
#define PIC_START_FRUIT     0
#define PIC_START_BAR       16


static  uint8  FRUIT_NUM=2;

static  uint16 speedTableX[]={2,-2,3,-3,2,-2,1,-1,2,-2,2,-2}; //水果X方向上的速度
static  uint16 speedTableY[]={-2,2,-3,3,-2,2,-3,3,-1,1,2,2};//水果Y方向上的速度


static int GameWnd_LoadResources(GameWnd *pthis);
static void GameWnd_UnloadResources(GameWnd *pthis);
static boolean GameWnd_HandleKeyEvent(GameWnd *pthis, AEEEvent eCode, uint16 wParam);
static void GameWnd_NextFrame(GameWnd *pthis);

static void GameWnd_LoadSprites(GameWnd *pthis, const char * pszFile, 
				uint16 resID, uint8 unSpriteSize, boolean isTile);
static int16 Random(int16 range);
static int16 abs(int16 range);
static void checkIfInBar(GameWnd * pthis);
static void collideWithWall(GameWnd *pthis);
static void collideWithBar(GameWnd *pthis);

boolean GameWnd_New(GameWnd *pthis, pfruitApp* pMe)
{
	pthis->pMe = pMe;

	return TRUE;
}

boolean GameWnd_HandleEvent(GameWnd * pthis, AEEEvent eCode, uint16 wParam, uint32 dwParam)
{
		
	switch (eCode) {
	case EVT_APP_SUSPEND:
		if(pthis->pIMedia)
		{
			IMEDIA_RegisterNotify(pthis->pIMedia,NULL,NULL);
			IMEDIA_Stop(pthis->pIMedia);
			IMEDIA_Release(pthis->pIMedia);
			pthis->pIMedia=NULL;

		}
		
		CALLBACK_Cancel(&pthis->cbTimer);
		return TRUE;
		
	case EVT_APP_RESUME:
	

		ISHELL_SetTimerEx(pthis->pMe->a.m_pIShell, 0, &pthis->cbTimer);
		return TRUE;
		
	case EVT_APP_NO_SLEEP:
		// catching this event prevent BREW from going to "sleep"
		return TRUE;
		
	default:
		return GameWnd_HandleKeyEvent(pthis, eCode, wParam);		 
	}
}

boolean GameWnd_Open(GameWnd *pthis)
{

	
	AEEDeviceInfo di;
	int i;
	int8 gridCntX;

	int8 gridCntXSprite;
	int8 gridCntYSprite;
	
	//添加音乐
	
	AEEMediaData Info;
	Info.clsData=MMD_FILE_NAME;
	Info.pData="midi.mid";
	Info.dwSize=0;

		

	//

		//添加音乐
	
		if(SUCCESS == ISHELL_CreateInstance(pthis->pMe->a.m_pIShell,AEECLSID_MEDIAMP3,&pthis->pIMedia))
		{
			IMEDIA_SetMediaData(pthis->pIMedia,&Info);
			IMEDIA_Play(pthis->pIMedia); 
		}

		//
	pthis->isDetach=FALSE;
	pthis->keyLeft=FALSE;
	pthis->keyRight=FALSE;
	pthis->layer=50;
	
	ISHELL_GetDeviceInfo(pthis->pMe->a.m_pIShell,&di);
	
	gridCntX=((di.cxScreen+18)/32 >4) ? 4:(di.cxScreen+18)/32;
	gridCntXSprite=di.cxScreen/PIC_WIDTH;
	gridCntYSprite=di.cyScreen/PIC_WIDTH;
//	gridCntXBar=((di.cyScreen+18)/8)>18 ? 18:(di.cxScreen+18)/8;


	//init background
	MEMSET(pthis->BackGroundLayer,0,sizeof(pthis->BackGroundLayer));

	pthis->BackGroundLayer[0]=0;
	pthis->BackGroundLayer[gridCntX-1]=0;
	pthis->BackGroundLayer[gridCntX]=3;
	

	pthis->frameMax.x=di.cxScreen;
	pthis->frameMax.y=di.cyScreen;

	pthis->frameStart.x=0;
	pthis->frameStart.y=0;


	MEMSET(pthis->rgMaps, 0, sizeof(pthis->rgMaps));
	pthis->rgMaps[0].pMapArray = (uint16*) pthis->BackGroundLayer;
	pthis->rgMaps[0].x = pthis->frameStart.x;
	pthis->rgMaps[0].y = pthis->frameStart.y;
	pthis->rgMaps[0].w = MAP_SIZE_32;
	pthis->rgMaps[0].h = MAP_SIZE_1;
	pthis->rgMaps[0].unTileSize = TILE_SIZE_32X32;
	pthis->rgMaps[0].unFlags = MAP_FLAG_WRAP;
	//complete background

	//init fruit
	MEMSET(pthis->rgCmds,0,sizeof(pthis->rgCmds));

	
		for( i=0;i<FRUIT_NUM;i++)
		{
			pthis->rgCmds[i].x=pthis->frameStart.x+PIC_WIDTH*Random((int16)gridCntXSprite);
			pthis->rgCmds[i].y=pthis->frameStart.y+PIC_WIDTH*Random((int16)gridCntYSprite);
			pthis->rgCmds[i].unSpriteIndex=PIC_START_FRUIT+i;
			pthis->rgCmds[i].unSpriteSize=SPRITE_SIZE_8X8;
			pthis->rgCmds[i].unComposite=0;
			pthis->rgCmds[i].unLayer=1;
			pthis->rgCmds[i].reserved[0]=0;
			pthis->rgCmds[i].reserved[1]=0;
			
			pthis->rgCmds[i+FRUIT_NUM].x=pthis->frameStart.x+PIC_WIDTH*Random((int16)gridCntXSprite);
			pthis->rgCmds[i+FRUIT_NUM].y=pthis->frameStart.y+PIC_WIDTH*Random((int16)gridCntYSprite);
			pthis->rgCmds[i+FRUIT_NUM].unSpriteIndex=PIC_START_FRUIT+i;
			pthis->rgCmds[i+FRUIT_NUM].unSpriteSize=SPRITE_SIZE_8X8;
			pthis->rgCmds[i+FRUIT_NUM].unComposite=0;
			pthis->rgCmds[i+FRUIT_NUM].unLayer=1;
			pthis->rgCmds[i+FRUIT_NUM].reserved[0]=0;
			pthis->rgCmds[i+FRUIT_NUM].reserved[1]=0;

			
		}
		checkIfInBar(pthis);

	//init bar*(12+6+6)
		for(i=SPRITE_BAR;i<SPRITE_BAR+12;i++)
		{
			pthis->rgCmds[i].x=-PIC_WIDTH*6+PIC_WIDTH*(i-SPRITE_BAR);
			pthis->rgCmds[i].y=(pthis->frameMax.y)/2+4;
			pthis->rgCmds[i].unSpriteIndex=PIC_START_BAR;
			pthis->rgCmds[i].unSpriteSize=SPRITE_SIZE_8X8;
			pthis->rgCmds[i].unComposite=0;
			pthis->rgCmds[i].unLayer=2;
		}
		for(i=SPRITE_BAR+12;i<SPRITE_BAR+12+12;i++)
		{
			pthis->rgCmds[i].x=-PIC_WIDTH*6+PIC_WIDTH*(i-SPRITE_BAR)+3*PIC_WIDTH;
			pthis->rgCmds[i].y=(pthis->frameMax.y)/2+4;
			pthis->rgCmds[i].unSpriteIndex=PIC_START_BAR;
			pthis->rgCmds[i].unSpriteSize=SPRITE_SIZE_8X8;
			pthis->rgCmds[i].unComposite=0;
			pthis->rgCmds[i].unLayer=2;
		}
			

	pthis->rgCmds[24+2*FRUIT_NUM].unSpriteSize=SPRITE_SIZE_END;


	if (GameWnd_LoadResources(pthis) != SUCCESS) {
		return FALSE;
	}	
	ISHELL_SetTimerEx(pthis->pMe->a.m_pIShell, 0, &pthis->cbTimer);

	return TRUE;
}

void GameWnd_Close(GameWnd *pthis)
{
	CALLBACK_Cancel(&pthis->cbTimer);
		if(pthis->pIMedia)
		{
			IMEDIA_RegisterNotify(pthis->pIMedia,NULL,NULL);
			IMEDIA_Stop(pthis->pIMedia);
			IMEDIA_Release(pthis->pIMedia);
			pthis->pIMedia=NULL;

		}
	GameWnd_UnloadResources(pthis);
}

void GameWnd_Free(GameWnd *pthis)
{
	CALLBACK_Cancel(&pthis->cbTimer);
		if(pthis->pIMedia)
		{
			IMEDIA_RegisterNotify(pthis->pIMedia,NULL,NULL);
			IMEDIA_Stop(pthis->pIMedia);
			IMEDIA_Release(pthis->pIMedia);
			pthis->pIMedia=NULL;

		}
	GameWnd_UnloadResources(pthis);
}

static int GameWnd_LoadResources(GameWnd *pthis)
{
	IBitmap	*pbmScreen;
	
	//creates instance of ISprite
	ISHELL_CreateInstance(pthis->pMe->a.m_pIShell, AEECLSID_SPRITE, 
		(void**)&pthis->pISprite);
	//sets IDisplay as its destination
	pbmScreen = IDISPLAY_GetDestination(pthis->pMe->a.m_pIDisplay);
	ISPRITE_SetDestination(pthis->pISprite, pbmScreen);
	IBITMAP_Release(pbmScreen);
	
	//load image for tile
	GameWnd_LoadSprites(pthis, FRUIT_RES_FILE, IDB_BACKGROUND, TILE_SIZE_32X32, TRUE);
	
	//load image for sprite
	GameWnd_LoadSprites(pthis, FRUIT_RES_FILE, IDB_SPRITE16, SPRITE_SIZE_8X8, FALSE);

	
	return SUCCESS;
}

static boolean GameWnd_HandleKeyEvent(GameWnd *pthis, AEEEvent eCode, uint16 wParam)
{
	if (eCode == EVT_KEY_PRESS)  {
		switch (wParam) {
		case AVK_RIGHT:
			if (pthis->keyLeft == FALSE) {
				pthis->keyRight = TRUE;
			}
			break;
		case AVK_LEFT:
			if (pthis->keyRight == FALSE) {
				pthis->keyLeft = TRUE;
			}
			break;
		default:
			return FALSE;
		}
		return TRUE;
	} else if (eCode == EVT_KEY_RELEASE) {
		switch (wParam) {
		case AVK_RIGHT:
			pthis->keyRight = FALSE;
			break;
		case AVK_LEFT:
			pthis->keyLeft = FALSE;
			break;
		default:
			return FALSE;
		}
		return TRUE;
		
	} else if(eCode == EVT_KEY) {
		switch(wParam) {
		case AVK_CLR:
			return Pfruit_SetActiveWnd(pthis->pMe, IDW_MAINMENU);
		default:
			return FALSE;
		}
	}
	return FALSE;
}

static void GameWnd_NextFrame(GameWnd *pthis)
{
	int i;
	ISHELL_SetTimerEx(pthis->pMe->a.m_pIShell, 40, &pthis->cbTimer);
	
		//update isDetach statement
	for(i=SPRITE_FRUIT;i<SPRITE_FRUIT+2*FRUIT_NUM;i++)
	{
		if(pthis->rgCmds[i].x > pthis->rgCmds[SPRITE_BAR].x)
		{
			pthis->rgCmds[i].reserved[1]=1;
		}
		if(pthis->rgCmds[i].x < pthis->rgCmds[SPRITE_BAR].x+PIC_WIDTH)
		{
			pthis->rgCmds[i].reserved[1]=2;
		}
	}
	//update isDetach
	pthis->isDetach=TRUE;
	for(i=SPRITE_FRUIT;i<SPRITE_FRUIT+FRUIT_NUM;i++)	
	{
		if((pthis->rgCmds[i].reserved[1] ==1) && (pthis->rgCmds[i+FRUIT_NUM].reserved[1]  ==1) )
		{
			pthis->isDetach=FALSE;
		}
		if ((pthis->rgCmds[i].reserved[1] ==2) && (pthis->rgCmds[i+FRUIT_NUM].reserved[1]==2))
		{
			pthis->isDetach=FALSE;
		}
	}

	
	if(!pthis->isDetach)
	{
		if(pthis->keyLeft==TRUE)
		{
			if(pthis->rgCmds[SPRITE_BAR].x>-6*PIC_WIDTH-6*PIC_WIDTH)
			{
				for(i=SPRITE_BAR;i<24+SPRITE_BAR;i++)
				{
					pthis->rgCmds[i].x-=3;
				}
				
			}

		}else if(pthis->keyRight==TRUE)
		{
			if(pthis->rgCmds[SPRITE_BAR].x<0)
			{
				for(i=SPRITE_BAR;i<24+SPRITE_BAR;i++)
				{
					pthis->rgCmds[i].x+=3;
				}
				
			}
		}
		
		//update fruit
		for( i=0;i<2*FRUIT_NUM;i++)
		{
			pthis->rgCmds[i].x+=speedTableX[i];
			pthis->rgCmds[i].y+=speedTableY[i];
		}
		//collide with wall
		collideWithWall(pthis);
		//collide with bar
		collideWithBar(pthis);
	}
	else
	{
		
		CALLBACK_Cancel(&pthis->cbTimer);
	}
	
	

	ISPRITE_DrawTiles(pthis->pISprite, pthis->rgMaps);
	ISPRITE_DrawSprites(pthis->pISprite,pthis->rgCmds);
	IDISPLAY_Update(pthis->pMe->a.m_pIDisplay);

}


static void GameWnd_LoadSprites(GameWnd *pthis, const char * pszFile, 
				uint16 resID, uint8 unSpriteSize, boolean isTile)
{
	IBitmap       *pbmScreen = NULL;
	IBitmap       *pbmDib = NULL;
	IBitmap       *pbmDdb = NULL;
	NativeColor    color;
	AEEBitmapInfo  bi;
	
	pbmScreen = IDISPLAY_GetDestination(pthis->pMe->a.m_pIDisplay);
	
	pbmDib = ISHELL_LoadResBitmap(pthis->pMe->a.m_pIShell, pszFile, resID);
	IBITMAP_GetInfo(pbmDib, &bi, sizeof(bi));
	IBITMAP_CreateCompatibleBitmap(pbmScreen, 
		&pbmDdb, (uint16)bi.cx, (uint16)bi.cy);
	IBITMAP_BltIn(pbmDdb, 0, 0, (uint16)bi.cx, (uint16)bi.cy, 
		pbmDib, 0, 0, AEE_RO_COPY);
	IBITMAP_Release(pbmDib);
	IBITMAP_GetPixel(pbmDdb, 0, 0, &color);
	IBITMAP_SetTransparencyColor(pbmDdb, color);
	if (isTile == TRUE) {
		ISPRITE_SetTileBuffer(pthis->pISprite, unSpriteSize, pbmDdb);
	} else {
		ISPRITE_SetSpriteBuffer(pthis->pISprite, unSpriteSize, pbmDdb);
	}
	IBITMAP_Release(pbmDdb);
	IBITMAP_Release(pbmScreen);
}

static void GameWnd_UnloadResources(GameWnd *pthis)
{
	if (pthis->pISprite) {
		ISPRITE_Release(pthis->pISprite);
		pthis->pISprite = NULL;
	}
}

static void collideWithBar(GameWnd *pthis)//碰撞两段还需测试
{
	int i;

	for(i=0;i<FRUIT_NUM*2;i++)
	{
		
		if(pthis->rgCmds[i].y+PIC_WIDTH>pthis->rgCmds[SPRITE_BAR].y && pthis->rgCmds[i].y<pthis->rgCmds[SPRITE_BAR].y+PIC_WIDTH )
		{	
			
		
							
					if(pthis->rgCmds[i].reserved[0]==0)
					{	//1
							if(pthis->rgCmds[i].x < pthis->rgCmds[SPRITE_BAR+11].x+PIC_WIDTH )	
							{  //2
										if(pthis->rgCmds[i].x < pthis->rgCmds[SPRITE_BAR+11].x )
										{
							
											speedTableY[i]*=-1;
											pthis->rgCmds[i].reserved[0]++;
										}
										else
										{
												if(speedTableX[i]<0)
												{
													//判断是在截面上碰撞还是在表面上(根据角度判断)
														if(speedTableY[i]>0)
														{
															if(abs((int16)(speedTableX[i]/speedTableY[i]))>abs((int16)((pthis->rgCmds[SPRITE_BAR+11].x+PIC_WIDTH - pthis->rgCmds[i].x)/(pthis->rgCmds[SPRITE_BAR+11].y - pthis->rgCmds[i].y+PIC_WIDTH))))//(pthis->rgCmds[i].y+PIC_WIDTH - pthis->rgCmds[SPRITE_BAR+11].y) > (pthis->rgCmds[SPRITE_BAR].x+PIC_WIDTH - pthis->rgCmds[i].x)  )
															{
																speedTableX[i]*=-1;
																pthis->rgCmds[i].reserved[0]++;
																
															}
															else
															{
																	speedTableY[i]*=-1;
																	pthis->rgCmds[i].reserved[0]++;
															}
														
														}
														else
														{
															if(abs((int16)(speedTableX[i]/speedTableY[i]))>abs((int16)((pthis->rgCmds[SPRITE_BAR+11].x+PIC_WIDTH-pthis->rgCmds[i].x)/(pthis->rgCmds[SPRITE_BAR+11].y+PIC_WIDTH-pthis->rgCmds[i].y))))
															{
																speedTableX[i]*=-1;
																pthis->rgCmds[i].reserved[0]++;
															}
																else
															{
																	speedTableY[i]*=-1;
																	pthis->rgCmds[i].reserved[0]++;
															}
														}
												}
												else
												{
														speedTableY[i]*=-1;
														pthis->rgCmds[i].reserved[0]++;
												}
								
										}
							}//2
						




							if(pthis->rgCmds[i].x+PIC_WIDTH > pthis->rgCmds[SPRITE_BAR+12].x )
							{  //2
										if(pthis->rgCmds[i].x < pthis->rgCmds[SPRITE_BAR+12].x )
										{
												if(speedTableX[i] > 0)
												{
													//判断是在截面上碰撞还是在表面上(根据位置角度判断)
														if(speedTableY[i]>0)
														{
															if(abs((int16)(speedTableX[i]/speedTableY[i]))>abs((int16)((pthis->rgCmds[SPRITE_BAR+12].x+-pthis->rgCmds[i].x+PIC_WIDTH)/(pthis->rgCmds[SPRITE_BAR+12].y-pthis->rgCmds[i].y+PIC_WIDTH))))
															{
																speedTableX[i]*=-1;
																pthis->rgCmds[i].reserved[0]++;
																
															}
															else
															{
																	speedTableY[i]*=-1;
																	pthis->rgCmds[i].reserved[0]++;
															}
														
														}
														else
														{
															if(abs((int16)(speedTableX[i]/speedTableY[i]))>abs((int16)((pthis->rgCmds[SPRITE_BAR+12].x-pthis->rgCmds[i].x+PIC_WIDTH)/(pthis->rgCmds[SPRITE_BAR+12].y+PIC_WIDTH-pthis->rgCmds[i].y))))
															{
																speedTableX[i]*=-1;
																pthis->rgCmds[i].reserved[0]++;
															}
															else
															{
																	speedTableY[i]*=-1;
																	pthis->rgCmds[i].reserved[0]++;
															}
														}
												}
												else
												{
														speedTableY[i]*=-1;
														pthis->rgCmds[i].reserved[0]++;
												}
										
										}
										else
										{

												speedTableY[i]*=-1;
												pthis->rgCmds[i].reserved[0]++;
										}
							}//2



					}//1
		}
		else
		{
			pthis->rgCmds[i].reserved[0]=0;
		}
		
	

	}
	


}

static void collideWithWall(GameWnd *pthis)
{
	int i;
	for(i=0;i<12;i++)
	{
		if(pthis->rgCmds[i].x>pthis->frameMax.x-PIC_WIDTH||pthis->rgCmds[i].x<0)
		{
			speedTableX[i]*=-1;
		}
		if(pthis->rgCmds[i].y>pthis->frameMax.y-PIC_WIDTH||pthis->rgCmds[i].y<0)
		{
			speedTableY[i]*=-1;
		}
	}
	

}
	
	

//让在BAR里的水果提出来
static void checkIfInBar(GameWnd *pthis)
{
		int i;
		for(i=0;i<FRUIT_NUM*2;i++)
		{
		
		if(pthis->rgCmds[i].y+PIC_WIDTH>pthis->rgCmds[SPRITE_BAR].y && pthis->rgCmds[i].y<pthis->rgCmds[SPRITE_BAR].y+PIC_WIDTH)
		{	
			pthis->rgCmds[i].y+=PIC_WIDTH;
		}
	
	}


}


static int16 Random(int16 range)
{
	uint16 rand;
	GETRAND((byte *)&rand,2);
	return range == 0 ? 0 : rand%range;
}
static int16 abs(int16 range)
{
	return range >0 ? range:-1*range;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -