AEDispatchHandler::AEDispatchHandler(DescType handlerClass, AEGenericClass* handler, Boolean deleteOnRemove /* = true*/ ) : mDeleteHandler(deleteOnRemove) , mHandlerClass(handlerClass) , mHandler(handler) { AE_ASSERT(mHandler, "No handler"); }
/*---------------------------------------------------------------------------- DispatchEvent ----------------------------------------------------------------------------*/ void AEDispatchHandler::DispatchEvent( AEDesc * token, const AppleEvent * appleEvent, AppleEvent * reply) { AE_ASSERT(mHandler, "No handler"); mHandler->DispatchEvent(token, appleEvent, reply); }
/*---------------------------------------------------------------------------- GetDataFromListOrObject ----------------------------------------------------------------------------*/ void AEDispatchHandler::GetDataFromListOrObject( const AEDesc * tokenOrTokenList, AEDesc * desiredTypes, AEDesc * data) { AE_ASSERT(mHandler, "No handler"); mHandler->GetDataFromListOrObject(tokenOrTokenList, desiredTypes, data); }
VALUE ae_proc_call_3(VALUE proc, VALUE param1, VALUE param2, VALUE param3) { AE_TRACE(); AE_ASSERT(! NIL_P(proc)); return rb_funcall(proc, method_call, 3, param1, param2, param3); }
VALUE ae_proc_call_1(VALUE proc, VALUE param) { AE_TRACE(); AE_ASSERT(! NIL_P(proc)); return rb_funcall2(proc, method_call, 1, ¶m); }
VALUE ae_proc_call_0(VALUE proc) { AE_TRACE(); AE_ASSERT(! NIL_P(proc)); return rb_funcall2(proc, method_call, 0, NULL); }
/*---------------------------------------------------------------------------- CountObjects ----------------------------------------------------------------------------*/ void AEDispatchHandler::CountObjects( DescType desiredType, DescType containerClass, const AEDesc * container, long * result) { AE_ASSERT(mHandler, "No handler"); mHandler->CountObjects(desiredType, containerClass, container, result); }
/*---------------------------------------------------------------------------- CompareObjects ----------------------------------------------------------------------------*/ void AEDispatchHandler::CompareObjects( DescType comparisonOperator, const AEDesc * object, const AEDesc * descriptorOrObject, Boolean * result) { AE_ASSERT(mHandler, "No handler"); mHandler->CompareObjects(comparisonOperator, object, descriptorOrObject, result); }
void Animation::addFrame(const std::string &filename) { auto newFrame = GameObject::create(filename); AE_ASSERT(newFrame); this->addChild(newFrame); AnimationFrame.push_back(newFrame); newFrame->setVisible(false); }
/* * When any AsyncEngine handler runs a Ruby callback, it must * use this function, which must be called without the GVL. * TODO: Allow passing a VALUE parameter...? */ VALUE ae_take_gvl_and_run_with_error_handler(void* function) { AE_TRACE(); AE_ASSERT(AE_status != AE_STOPPED); return rb_thread_call_with_gvl(ae_run_with_error_handler, function); }
/*---------------------------------------------------------------------------- GetProperty ----------------------------------------------------------------------------*/ void AEDispatchHandler::GetProperty( DescType desiredClass, const AEDesc* containerToken, DescType containerClass, DescType keyForm, const AEDesc* keyData, AEDesc* resultToken) { AE_ASSERT(mHandler, "No handler"); mHandler->GetProperty(desiredClass, containerToken, containerClass, keyForm, keyData, resultToken); }
/* * When any AsyncEngine handler runs a handle method having the GVL, * it must use this function, which can receive an optional VALUE parameter. */ VALUE ae_run_with_error_handler(void* function, VALUE param) { AE_TRACE(); VALUE ret, error; int error_tag; AE_ASSERT(AE_status != AE_STOPPED); if (param) ret = rb_protect(function, (VALUE)param, &error_tag); else ret = rb_protect(function, Qnil, &error_tag); /* * If an error occurs while in function() it can be due: * * - An Exception (including SystemExit), this is "rescue-able" via "rescue Exception" * and will run the "ensure" code if present. In this case rb_errinfo() returns the * exact Exception object. * * - A Thread#kill. This is NOT "rescue-able" via "rescue Exception" but it WILL run * the "ensure" code if present. In this case rb_errinfo() returns FIXNUM 8. * * So, check the class of the object returned by rb_errinfo(). If it's an Exception then * store it, release the loop and raise it. Otherwise (Thread#kill) then don't store the * exception returned by rb_errinfo() and just release the loop. Ruby will do the rest. */ if (error_tag) { // NOTE: This could return Fixnum 8: https://github.com/ibc/AsyncEngine/issues/4, // so the error handler must check it. error = rb_errinfo(); rb_set_errinfo(Qnil); // NOTE: While in RELEASING status ignore errors in user's provided callback/method. if (AE_status == AE_RELEASING) { AE_DEBUG2("error %s rescued while in RELEASING status, ignoring it", rb_obj_classname(error)); return Qnil; } else { AE_DEBUG("error %s rescued, passing it to the error handler", rb_obj_classname(error)); ae_handle_error(error); return Qnil; } } else return ret; }
/*---------------------------------------------------------------------------- CreateSelfSpecifier ----------------------------------------------------------------------------*/ void AEDispatchHandler::CreateSelfSpecifier( const AEDesc * token, AEDesc * outSpecifier) { AE_ASSERT(mHandler, "No handler"); mHandler->CreateSelfSpecifier(token, outSpecifier); }
GameObjInst* astCreate(GameObjInst* pSrc) { GameObjInst* pInst; AEVec2 pos, vel; f32 t, angle, size; if (pSrc) { f32 posOffset = pSrc->scale * 0.25f; f32 velOffset = (AST_SIZE_MAX - pSrc->scale + 1.0f) * 0.25f; f32 scaleNew = pSrc->scale * 0.5f; sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 0.0f * PI - 0.01f * PI, 0.0f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr); sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 0.5f * PI - 0.01f * PI, 0.5f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr); sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 1.0f * PI - 0.01f * PI, 1.0f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr); sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 1.5f * PI - 0.01f * PI, 1.5f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr); pInst = astCreate(0); pInst->scale = scaleNew; AEVec2Set(&pInst->posCurr, pSrc->posCurr.x - posOffset, pSrc->posCurr.y - posOffset); AEVec2Set(&pInst->velCurr, pSrc->velCurr.x - velOffset, pSrc->velCurr.y - velOffset); pInst = astCreate(0); pInst->scale = scaleNew; AEVec2Set(&pInst->posCurr, pSrc->posCurr.x + posOffset, pSrc->posCurr.y - posOffset); AEVec2Set(&pInst->velCurr, pSrc->velCurr.x + velOffset, pSrc->velCurr.y - velOffset); pInst = astCreate(0); pInst->scale = scaleNew; AEVec2Set(&pInst->posCurr, pSrc->posCurr.x - posOffset, pSrc->posCurr.y + posOffset); AEVec2Set(&pInst->velCurr, pSrc->velCurr.x - velOffset, pSrc->velCurr.y + velOffset); pSrc->scale = scaleNew; AEVec2Set(&pSrc->posCurr, pSrc->posCurr.x + posOffset, pSrc->posCurr.y + posOffset); AEVec2Set(&pSrc->velCurr, pSrc->velCurr.x + velOffset, pSrc->velCurr.y + velOffset); return pSrc; } // pick a random angle and velocity magnitude angle = AERandFloat() * 2.0f * PI; size = AERandFloat() * (AST_SIZE_MAX - AST_SIZE_MIN) + AST_SIZE_MIN; // pick a random position along the top or left edge if ((t = AERandFloat()) < 0.5f) AEVec2Set(&pos, gAEWinMinX + (t * 2.0f) * (gAEWinMaxX - gAEWinMinX), gAEWinMinY - size * 0.5f); else AEVec2Set(&pos, gAEWinMinX - size * 0.5f, gAEWinMinY + ((t - 0.5f) * 2.0f) * (gAEWinMaxY - gAEWinMinY)); // calculate the velocity vector AEVec2Set (&vel, AECos(angle), AESin(angle)); AEVec2Scale (&vel, &vel, AERandFloat() * (AST_VEL_MAX - AST_VEL_MIN) + AST_VEL_MIN); // create the object instance pInst = gameObjInstCreate(TYPE_ASTEROID, size, &pos, &vel, 0.0f, true); AE_ASSERT(pInst); // set the life based on the size pInst->life = size / AST_SIZE_MAX * AST_LIFE_MAX; return pInst; }
void Update2(void) { //unsigned long i; float winMaxX, winMaxY, winMinX, winMinY; double frameTime; // ========================================================================================== // 获取窗口四条边的坐标,当窗口发生移动或缩放,以下值会发生变化 // ========================================================================================== winMaxX = AEGfxGetWinMaxX(); winMaxY = AEGfxGetWinMaxY(); winMinX = AEGfxGetWinMinX(); winMinY = AEGfxGetWinMinY(); // ====================== // 帧时间:相当于zero中的dt // ====================== frameTime = AEFrameRateControllerGetFrameTime(); // ========================= // 游戏逻辑响应输入 // ========================= // 状态切换 if (KeyPressed[KeyR]) Next = GS_Restart; if (KeyPressed[KeyESC]) Next = GS_Quit; if (KeyPressed[Key1]) Next = GS_L1; if (KeyPressed[KeyMenu]) Next = GS_MENU; // 主角的移动 if (KeyPressed[KeyUp]) { obj1Y += 20.0f; } else if (KeyPressed[KeyDown]) { obj1Y -= 20.0f; } if (KeyPressed[KeyLeft]) { obj1X -= 20.0f; } else if (KeyPressed[KeyRight]) { obj1X += 20.0f; } //鼠标左键控制石头生成 if ((KeyPressed[KeyLeftBottom]) && (Burglar->flag& FLAG_ACTIVE))//&& (StoneCount>0)) { pStone = gameObjCreate(TYPE_STONE, 3.0f, 0, 0, 0.0f);; AE_ASSERT(pStone); // 实例化 // 初始化: 坐标位置 朝向和尺寸大小 //在主角位置产生,射向鼠标位置 pStone->posCurr.x = Burglar->posCurr.x; pStone->posCurr.y = Burglar->posCurr.y; //石头减一 StoneCount -= 1; } //随机产生水果,每隔3秒产生一个,一个界面最多产生10个水果 TimeTot++; if (TimeTot == 180 && Fruit_NUM<10) { Fruit_NUM++; int Xx, Yy; Xx = rand(); Yy = rand(); //控制水果在界面内产生 while (Xx > 800.0f) //控制水果在界面宽度内产生 { Xx = (int)rand(); } while (Yy > 600.0f)//控制水果在界面高度度内产生 { Yy = (int)rand(); } Xx = Xx - 400; Yy = Yy - 300; TimeTot = 0; GameObj* pFruit = gameObjCreate(TYPE_WATERMELON, 3.0f, 0, 0, 0.0f);; AE_ASSERT(pFruit); // 实例化 // 初始化: 坐标位置 朝向和尺寸大小 pFruit->posCurr.x = Xx; pFruit->posCurr.y = Yy; pFruit->scale = 5.0f; } else if (TimeTot == 200) TimeTot = 0; //遍历所有对象以决定操作 for (int i = 1; i < GAME_OBJ_NUM_MAX; i++) { GameObj* pObj = sGameObjList + i; //石头的发射 if (pObj->flag && pObj->pObject->type == TYPE_STONE) { //石头朝着鼠标位置运动 pStone->velCurr.x = (posX - Burglar->posCurr.x) / 10.0f; pStone->velCurr.y = (posY - Burglar->posCurr.y) / 10.0f; pObj->posCurr.x += pObj->velCurr.x; pObj->posCurr.y += pObj->velCurr.y; //碰撞到狗或者boss for (int j = 1; j < GAME_OBJ_NUM_MAX; j++) { GameObj* pObj0 = sGameObjList + j; if (pObj0->flag && (pObj0->pObject->type == TYPE_DOG || pObj0->pObject->type == TYPE_BOSS)) { if (StaticPointToStaticCircle(&pObj->posCurr, &pObj0->posCurr, 10.0)) { gameObjDestroy(pObj0); gameObjDestroy(pObj); } } } } //捡石头 if (pObj->flag&&pObj->pObject->type == TYPE_STONE_STATIC) { if (StaticRectToStaticRect(&Burglar->posCurr, 33, 30, &pObj->posCurr, 15, 15)) { gameObjDestroy(pObj); StoneCount += 1; } } //离陷阱距离近时 if (pObj->flag && pObj->pObject->type == TYPE_TRAP_IN) { if (Burglar->flag&FLAG_ACTIVE) { if (((pObj->posCurr.x - Burglar->posCurr.x)*(pObj->posCurr.x - Burglar->posCurr.x) + (pObj->posCurr.y - Burglar->posCurr.y) *(pObj->posCurr.y - Burglar->posCurr.y)) < 4000) { pTrap = gameObjCreate(TYPE_TRAP_OUT, 10.0f, 0, 0, 0.0f); pTrap->posCurr.x = pObj->posCurr.x; pTrap->posCurr.y = pObj->posCurr.y; pTrap->scale = 10.0; if (StaticRectToStaticRect(&Burglar->posCurr, 30, 30, &pObj->posCurr, 40, 40) && pObj->flag) { Burglar->scale -= 0.5; } if (Burglar->scale < 1.0f) { gameObjDestroy(Burglar);//碰撞了,减少scale,并销毁对象 } } } } //远离陷阱时 if (pObj->flag && pObj->pObject->type == TYPE_TRAP_OUT) { if (((pObj->posCurr.x - Burglar->posCurr.x)*(pObj->posCurr.x - Burglar->posCurr.x) + (pObj->posCurr.y - Burglar->posCurr.y) *(pObj->posCurr.y - Burglar->posCurr.y))>40000) gameObjDestroy(pObj); } //Boss 的运动跟碰撞 if (pObj->flag && pObj->pObject->type == TYPE_BOSS) { //发生碰撞,主角死亡 if (StaticRectToStaticRect(&Burglar->posCurr, 15.0f, 15.0f, &pObj->posCurr, 15.0f, 15.0f)) { gameObjDestroy(Burglar); } } //狗的边界控制 if (pObj->flag&&pObj->pObject->type == TYPE_DOG) { if (pObj->posCurr.x >= winMaxX || pObj->posCurr.x <= winMinX) { pObj->posCurr.x = -pObj->posCurr.x; } if (pObj->posCurr.y <= winMinY || pObj->posCurr.y >= winMaxY) { pObj->posCurr.y = -pObj->posCurr.y; } //是否与狗发生碰撞 if (StaticRectToStaticRect(&Burglar->posCurr, 30, 30, &pObj->posCurr, 30, 30) && pObj->flag) { Burglar->scale -= 0.5; } if (Burglar->scale < 1.0f) { gameObjDestroy(Burglar);//碰撞了,减少scale,并销毁对象 } } //捡西瓜 if (pObj->flag&&pObj->pObject->type == TYPE_WATERMELON) { if (StaticPointToStaticCircle(&Burglar->posCurr, &pObj->posCurr, 10.0)) { gameObjDestroy(pObj); Fruit_NUM -= 1; sScore += 10; } } if (pObj->flag && pObj->pObject->type == TYPE_BURGLARBLOOD) { //更新血量位置 pObj->posCurr.x = Burglar->posCurr.x; pObj->posCurr.y = Burglar->posCurr.y + 35.0f; if (!Burglar->flag&FLAG_ACTIVE) { gameObjDestroy(pObj); //销毁主角的同时,销毁主角的血量 } } }//for //狗运动 for (int a = 0; a < 5; a++) { srand(time()); int PosDogX = (pDog[a]->posCurr.x + 400) / 40; int PosDogY = (pDog[a]->posCurr.y + 300) / 15; if (mapinfo[PosDogX - 1][PosDogY]) { pDog[a]->posCurr.x += 1; } else if (mapinfo[PosDogX + 1][PosDogY]) { pDog[a]->posCurr.x -= 1; } else if (mapinfo[PosDogX][PosDogY + 1]) { pDog[a]->posCurr.y -= 1; } else if (mapinfo[PosDogX][PosDogY - 1]) { pDog[a]->posCurr.y += 1; } //else //{ // pDog[a]->posCurr.x += 2; //} } //狗的运动 TimeTot1++; int x; if (TimeTot1 < 300) { pDog[0]->posCurr.x += 1; pDog[1]->posCurr.x -= 1; pDog[2]->posCurr.y += 1; pDog[3]->posCurr.y -= 1; pDog[4]->posCurr.x += 1; } if (TimeTot1 >= 300 && TimeTot1 < 600) { pDog[0]->posCurr.x -= 1; pDog[1]->posCurr.x += 1; pDog[2]->posCurr.y -= 1; pDog[3]->posCurr.y += 1; pDog[4]->posCurr.y -= 1; } if (TimeTot1 >= 600 && TimeTot1 < 900) { pDog[0]->posCurr.y += 1; pDog[1]->posCurr.y -= 1; pDog[2]->posCurr.x += 1; pDog[3]->posCurr.x -= 1; pDog[4]->posCurr.y += 1; } if (TimeTot1 >= 900 && TimeTot1 < 1200) { pDog[0]->posCurr.y -= 1; pDog[1]->posCurr.y += 1; pDog[2]->posCurr.x -= 1; pDog[3]->posCurr.x += 1; pDog[4]->posCurr.y -= 1; } if (TimeTot1 == 1200) { TimeTot1 = 0; } //按空格键 if (KeyPressed[KeySpace]) { } // 输入重置 Input_Initialize(); // 签到 fprintf(fp, "Level2:Update\n"); }
void Ini2(void) { //水果数量 Fruit_NUM = 0; //水果产生时间间隔 TimeTot = 0; //临时定义狗运动时间 TimeTot1 = 0; //捡到的石头数量 static int StoneCount = 10; // 对象1的初始位置 obj1X = -10.0f; obj1Y = 0.0f; memset(sGameObjList, 0, sizeof(GameObj)*GAME_OBJ_NUM_MAX); GameObj* pObj; int i; BossBlood = 2; //初始化BOSS血量 // 为开始画对象做准备 AEGfxSetBackgroundColor(0.0f, 0.0f, 0.0f); AEGfxSetBlendMode(AE_GFX_BM_BLEND); // 对象实例化:游戏开始只有小盗和狗和农场主需要实例化 // 小盗对象实例化 Burglar = gameObjCreate(TYPE_BURGLAR, BURGLAR_SIZE, 0, 0, 0.0f); AE_ASSERT(Burglar); Burglar->posCurr.x = AEGfxGetWinMaxX()-20; Burglar->posCurr.y = 100.0f; Burglar->dirCurr = acosf(Burglar->posCurr.x / ((float)sqrt(Burglar->posCurr.x*Burglar->posCurr.x + Burglar->posCurr.y * Burglar->posCurr.y))) - PI; Burglar->scale = 10.0f; //初始化静止的石头 for (i = 0; i < 3; i++) { pObj = gameObjCreate(TYPE_STONE_STATIC, 3.0f, 0, 0, 0.0f); AE_ASSERT(pObj); // 实例化 // 初始化: 坐标位置 朝向和尺寸大小 switch (i) { case 0: pObj->posCurr.x = 100.0f; pObj->posCurr.y = 100.0f; break; case 1: pObj->posCurr.x = 100.0f; pObj->posCurr.y = AEGfxGetWinMaxY() - 30; break; case 2: pObj->posCurr.x = AEGfxGetWinMinX() + 40; pObj->posCurr.y = 50.0f; break; } pObj->dirCurr = acosf(pObj->posCurr.x / ((float)sqrt(pObj->posCurr.x*pObj->posCurr.x + pObj->posCurr.y * pObj->posCurr.y))) - PI; pObj->scale = 5.0f; } //初始化看不见的陷阱 for (int a = 0; a < 3; a++) { pObj = gameObjCreate(TYPE_TRAP_IN, 10.0f, 0, 0, 0.0f); AE_ASSERT(pObj); //初始化陷阱位置及朝向比例 pObj->posCurr.x = a*100.0f; pObj->posCurr.y = -100.0f; pObj->dirCurr = acosf(pObj->posCurr.x / ((float)sqrt(pObj->posCurr.x*pObj->posCurr.x + pObj->posCurr.y * pObj->posCurr.y))) - PI; pObj->scale = 10.0f; } //初始化农场主 pBoss = gameObjCreate(TYPE_BOSS, 10.0f, 0, 0, 0.0f); AE_ASSERT(pBoss); //初始化农场主位置及朝向比例 pBoss->posCurr.x = 100.0f; pBoss->posCurr.y = 100; pBoss->dirCurr = acosf(pBoss->posCurr.x / ((float)sqrt(pBoss->posCurr.x*pBoss->posCurr.x + pBoss->posCurr.y * pBoss->posCurr.y))) - PI; pBoss->scale = 10.0f; //狗对象实例化 并 初始化 for (i = 0; i < DOG_NUM; i++) { // 实例化 pObj = gameObjCreate(TYPE_DOG, 10.0f, 0, 0, 0.0f); pDog[i] = pObj;//给狗分配指针 AE_ASSERT(pObj); pObj->posCurr.x = 100.0f; pObj->posCurr.y = 100.0f; pObj->dirCurr = acosf(pObj->posCurr.x / ((float)sqrt(pObj->posCurr.x*pObj->posCurr.x + pObj->posCurr.y * pObj->posCurr.y))) - PI; pObj->scale = 10.0f; } //农场主血量初始化 pObj = gameObjCreate(TYPE_BOSSBLOOD, 10.0f, 0, 0, 0.0f); AE_ASSERT(pObj); //初始化血量位置 pObj->posCurr.x = pBoss->posCurr.x; pObj->posCurr.y = pBoss->posCurr.y + 35.0f; //主角血量初始化 pObj = gameObjCreate(TYPE_BURGLARBLOOD, 10.0f, 0, 0, 0.0f); AE_ASSERT(pObj); //初始化血量位置 pObj->posCurr.x = Burglar->posCurr.x; pObj->posCurr.y = Burglar->posCurr.y + 35.0f; //地图的引入 FILE *fp = NULL; if ((fp = fopen("wdp.txt", "r")) != NULL) { int length = 0, width = 0; fscanf(fp, "%d%d", &length, &width); int i = 0, j = 0; for (; i < length; i++) { for (j = 0; j < width; j++) { fscanf(fp, "%d", &mapinfo[i][j]); } } //读入地图 for (i = 0; i < length; i++) { for (j = 0; j < width; j++) { if (mapinfo[i][j] == 1) { //画地图 pObj = gameObjCreate(TYPE_MAP, 1.0f, 0, 0, 0.0f); AE_ASSERT(pObj); pObj->posCurr.y = i * 40 - 400.0f; pObj->posCurr.x = j*15 - 300.0f; } } } } else if ((fp = fopen("wdp.txt", "r")) == NULL) { KeyPressed[KeyESC] = TRUE; } // 签到 fprintf(fp, "Level2:Initialize\n"); }