void HotCubeCube::start() { BaseGameCube::start(); Float2 panning; panning.set(0, 0); buffer->bg1.setMask(BG1Mask::filled(vec(4,7), vec(8,2))); buffer->bg1.text(vec(4,7), BlackFont, " "); buffer->bg1.setPanning(panning); }
void writeScore(int i) { int maskWidth = 2; cubeVideo[cube].bg1.setMask(BG1Mask::filled(vec(0,12), vec(maskWidth * 2, 4))); text.set(-64 + maskWidth * 6, 52); String<3> bTest; bTest << Fixed(i, maskWidth, true); textTarget = text; writeText(bTest.c_str()); }
static void onTouch(void* ctxt, unsigned cube) { if(g_iCurMode & MODE_GAMEOVER && boards[cube].hasMarble()) //Tap on the "game over" cube to restart { //Play sound effect for clearing board (also board reset-- why not?) channels[BOARD_SFX_CHANNEL]->play(sBoardClear); for(int i = 0; i < NUM_CUBES; i++) { boards[i].getVid()->bg1.eraseMask(); //Wipe "game over" screen boards[i].initTilemap(); //Load a new tilemap into each boards[i].takeMarble(); } //Add marble to first cube Float2 fVel; fVel.set(0,0); Float2 fPos = LCD_center; fPos.x += TILE_WIDTH/2.0; fPos.y += TILE_HEIGHT/2.0; boards[0].addMarble(fPos, fVel); //Other starting tasks for(int i = 0; i < NUM_COLORS; i++) g_bColorsUsed[i] = false; g_iScore = -1; g_iCurMode = BOARD_NOTHING; for(int i = 0; i < NUM_CUBES; i++) g_starsCollected[i] = 0; g_iBoardReset = -1; } if(g_iCurMode & BOARD_WAITPORTAL && boards[cube].hasMarble()) //Tap on the flashy arrow cube to ignore portal { boards[cube].spitBack(); //Spit marble back out //Play sound effect for exiting a portal channels[PORTAL_CHANNEL]->play(sPortalExit); g_iCurMode = BOARD_NOTHING; for(int iCube = 0; iCube < NUM_CUBES; iCube++) { //Hide any flashy arrows boards[iCube].hideArrows(); boards[iCube].resetFlashTimer(); } } }
void Renderer::fitViewNearFarToObjects(Float2& near_far, const Float4x4& view, const float near_min, const float far_max, const bool inc_light_vols) const { near_far.set(near_min, far_max); return; // Note, the fitting is NOT tight. Firstly, we're using the geometry's // axis aligned bounding box, which is not tight (after the model // transform) then we're assuming the size of the box is maximum after // rotation into the camera space (which is also not tight). // Recall: OpenGL convention is to look down the negative Z axis, // therefore, more negative values are actually further away. near_far[0] = -std::numeric_limits<float>::infinity(); // znear near_far[1] = std::numeric_limits<float>::infinity(); // zfar float min_z, max_z; gm_->renderStackReset(); while (!gm_->renderStackEmpty()) { GeometryInstance* cur_geometry = gm_->renderStackPop(); AABBox* aabbox = cur_geometry->aabbox(); if (aabbox) { aabbox->calcMinMaxZBoundInViewSpace(min_z, max_z, view); if (max_z < near_far[1]) { near_far[1] = max_z; } if (min_z > near_far[0]) { near_far[0] = min_z; } } } // Also fit to light geometry: if (inc_light_vols) { Float3 pos_source; Float3 dir; float rad; Float3 center_view; LightPoint* light_point; LightSpot* light_spot; for (uint32_t i = 0; i < lighting_->lights().size(); i++) { switch (lighting_->lights()[i]->type()) { case LIGHT_POINT: light_point = (LightPoint*)(lighting_->lights()[i]); // Calculate model view projection matrix Float3::affineTransformPos(center_view, view, light_point->pos_world()); rad = light_point->outside_rad(); if ((center_view[2] - rad) < near_far[1]) { near_far[1] = center_view[2] - rad; } if ((center_view[2] + rad) > near_far[0]) { near_far[0] = center_view[2] + rad; } break; case LIGHT_SPOT_VSM: case LIGHT_SPOT: light_spot = (LightSpot*)(lighting_->lights()[i]); // Check the source point Float3::affineTransformPos(pos_source, view, light_spot->pos_world()); if (pos_source[2] < near_far[1]) { near_far[1] = pos_source[2]; } if (pos_source[2] > near_far[0]) { near_far[0] = pos_source[2]; } // Now check the cone end Float3::affineTransformPos(center_view, view, light_spot->cone_center_world()); rad = light_spot->cone_outside_radius(); if ((center_view[2] - rad) < near_far[1]) { near_far[1] = center_view[2] - rad; } if ((center_view[2] + rad) > near_far[0]) { near_far[0] = center_view[2] + rad; } break; default: break; } } } near_far[0] += LOOSE_EPSILON; near_far[1] -= LOOSE_EPSILON; // now clamp the near and far to the user defined values if (near_far[0] > near_min) { near_far[0] = near_min; } if (near_far[1] < far_max) { near_far[1] = far_max; } if (near_far[1] > near_far[0]) { near_far[1] = near_far[0] - 0.1f; } }
void main() { //Create our audio channels AudioChannel a1(0); AudioChannel a2(1); AudioChannel a3(2); AudioChannel a4(3); AudioChannel a5(4); AudioChannel a6(5); channels[0] = &a1; channels[1] = &a2; channels[2] = &a3; channels[3] = &a4; channels[4] = &a5; channels[5] = &a6; r.seed(); channels[BALL_ROLL_CHANNEL]->play(sRollLoop, REPEAT); //Start playing rolling marble noise channels[BALL_ROLL_CHANNEL]->setVolume(0); for(int i = 0; i < NUM_CUBES; i++) g_starsCollected[i] = 0; for(int i = 0; i < NUM_COLORS; i++) g_bColorsUsed[i] = false; g_iBoardReset = -1; g_iScore = -1; TimeStep ts; float fTapPromptDelay = 0.0; int iBoardDied; //Initialize our boards for(int i = 0; i < NUM_CUBES; i++) boards[i].init(i); Events::neighborAdd.set(onNeighborAdd); //Function for when two cubes touch each other Events::cubeTouch.set(onTouch); //Function for when a cube is tapped //Add the marble to one of them Float2 fVel; fVel.set(0,0); Float2 fPos = LCD_center; fPos.x += TILE_WIDTH/2.0; fPos.y += TILE_HEIGHT/2.0; boards[0].addMarble(fPos, fVel); TextDraw td; bool bFirstSound = true; //Main loop while (1) { ts.next(); for(int i = 0; i < NUM_CUBES; i++) { int iMode; switch(g_iCurMode) { case BOARD_NOTHING: iMode = boards[i].update(float(ts.delta())); //Update our rolling sound to the right volume if(boards[i].hasMarble()) { float fVol = boards[i].getMarbleVelocity() * 0.9; if(fVol > MAX_VOLUME) fVol = MAX_VOLUME; channels[BALL_ROLL_CHANNEL]->setVolume(fVol); } if(iMode & BOARD_GOTPOINT) { iMode ^= BOARD_GOTPOINT; g_iScore++; if(++g_starsCollected[i] == NUM_STARS_CUBE) g_iBoardReset = i; //Play sound for getting a star, but not right on reset if(bFirstSound) bFirstSound = false; else channels[BALL_SFX_CHANNEL]->play(sGetStar); } if(iMode & BOARD_DIED) { //Show game over screen iMode ^= BOARD_DIED; iMode |= MODE_GAMEOVER; td.draw(boards[i].getVid(), "Game over", 6); String<64> s; s << "Score: " << g_iScore; td.draw(boards[i].getVid(), s.c_str(), 8); fTapPromptDelay = 0.0; iBoardDied = i; bFirstSound = true; channels[BALL_ROLL_CHANNEL]->setVolume(0); channels[BALL_SFX_CHANNEL]->play(sDie); } if(iMode & BOARD_LEFT) { iMode ^= BOARD_LEFT; if(g_iBoardReset == i) { boards[i].reset(g_bColorsUsed); g_starsCollected[i] = 0; g_iBoardReset = -1; g_iScore += 3; //Three points for clearing board //Play sound effect for clearing board channels[BOARD_SFX_CHANNEL]->play(sBoardClear); } //Play pass-through-portal sound else if(!channels[PORTAL_CHANNEL]->isPlaying()) channels[PORTAL_CHANNEL]->play(sThroughPortal); } if(iMode & BOARD_WAITPORTAL) { //Play sound effect for entering a portal channels[PORTAL_CHANNEL]->play(sPortalEnter); channels[BALL_ROLL_CHANNEL]->setVolume(0); } g_iCurMode = iMode; break; case BOARD_WAITPORTAL: boards[i].waitPortal(float(ts.delta())); channels[BALL_ROLL_CHANNEL]->setVolume(0); break; case MODE_GAMEOVER: fTapPromptDelay += float(ts.delta()) / 3.0; if(fTapPromptDelay >= TAP_PROMPT_DELAY && fTapPromptDelay < 100.0) { fTapPromptDelay = 100; td.draw(boards[iBoardDied].getVid(), "Tap to restart", 14); } channels[BALL_ROLL_CHANNEL]->setVolume(0); } } System::paint(); } }