void ofApp::update(){ float frame = ofGetFrameNum(); ofVec3f attractor( 10, 10, 50 ); attractor.rotate( ofGetFrameNum()/4, ofVec3f(0.5, 0.3, 0.1) ); ofVec3f diff; for( int i=0; i<shapes.size(); i++ ){ ofVec3f pos = shapes[i]->getPosition(); diff = attractor - pos; float dist2 = diff.lengthSquared(); float power = (1.0/dist2) * 50000.0; ofVec3f force( 0,0,0 ); if( 1 ){ float noise = 0; float amp = 0.5; for( int j=0; j<4; j++ ){ noise += ofNoise( pos.x, pos.y, pos.z, frame*0.001) * amp; amp *= 0.5; } force += diff.normalized() * power; } #pragma mark ADD_PERLIN_NOISE if( 0 ){ ofVec3f noise; noise.zero(); float amp = 0.5; for( int j=0; j<4; j++ ){ noise.x += ofSignedNoise( pos.x, frame*0.001 ) * amp; noise.y += ofSignedNoise( pos.y, frame*0.001 ) * amp; noise.z += ofSignedNoise( pos.z, frame*0.001 ) * amp; amp *= 0.5; } force += noise*5.0; } shapes[i]->applyCentralForce( force ); points.setVertex( i, pos ); } lines.clear(); int num_line = 3; // per point for( int i=0; i<shapes.size(); i++ ){ // if(ofRandom(1.0)>0.1) // continue; ofVec3f pos1 = shapes[i]->getPosition(); multimap<float, ofVec3f> near_p; pair<float, ofVec3f> pair1( 999999999999, ofVec3f(0,0,0) ); for( int line=0; line<num_line; line++ ){ near_p.insert( pair1 ); } for( int j=i+1; j<shapes.size(); j++ ){ ofVec3f pos2 = shapes[j]->getPosition(); float dist = pos1.distance( pos2 ); multimap<float, ofVec3f>::iterator itr = near_p.end(); itr--; if( dist < itr->first ){ std::pair<float, ofVec3f> pair2( dist, pos2 ); near_p.insert( pair2 ); multimap<float, ofVec3f>::iterator end = near_p.end(); near_p.erase( --end ); } } multimap<float, ofVec3f>::iterator itr = near_p.begin(); for(; itr!=near_p.end(); itr++ ){ ofVec3f &pos2 = itr->second; lines.addVertex( pos1 ); lines.addVertex( pos2 ); lines.addColor( ofFloatColor( ofRandom(0.2,0.4), ofRandom(0.2, 0.4)) ); lines.addColor( ofFloatColor( ofRandom(0.2,0.4), ofRandom(0.2, 0.4)) ); } } world.update(); }
int menu(SDL_Surface *screen, SDL_Surface *vscreen) { unsigned frameStart; bool leave = false; // Load and prepare the background image SDL_Surface *loadedImage = IMG_Load("title.png"); if (!loadedImage) { fprintf(stderr, "Could not load title image.\n"); return MENU_ERROR; } SDL_Surface *background = SDL_DisplayFormatAlpha(loadedImage); SDL_FreeSurface(loadedImage); TTF_Font *fontSmall = TTF_OpenFont("FreeSansBold.ttf", 10); TTF_Font *fontLarge = TTF_OpenFont("FreeSansBold.ttf", 12); if (!fontSmall || !fontLarge) { fprintf(stderr, "Could not load font.\n"); return MENU_ERROR; } SDL_Color playerFontColour, autuinFontColour; playerFontColour.r = playerFontColour.g = playerFontColour.b = 230; autuinFontColour.r = autuinFontColour.g = autuinFontColour.b = 200; SDL_Surface *onePlayerTextSmall = TTF_RenderText_Solid(fontSmall, "ONE PLAYER", playerFontColour); SDL_Surface *twoPlayerTextSmall = TTF_RenderText_Solid(fontSmall, "TWO PLAYER", playerFontColour); SDL_Surface *onePlayerTextLarge = TTF_RenderText_Solid(fontLarge, "ONE PLAYER", playerFontColour); SDL_Surface *twoPlayerTextLarge = TTF_RenderText_Solid(fontLarge, "TWO PLAYER", playerFontColour); SDL_Surface *autuinText = TTF_RenderText_Solid(fontSmall, "(C) 2012 AUTOMATIC TURQUOISE INTERNATIONAL", autuinFontColour); TTF_CloseFont(fontSmall); TTF_CloseFont(fontLarge); SDL_Rect onePlayerRectSmall, onePlayerRectLarge; SDL_Rect twoPlayerRectSmall, twoPlayerRectLarge; onePlayerRectSmall.x = 60; onePlayerRectLarge.x = 50; twoPlayerRectSmall.x = 190; twoPlayerRectLarge.x = 180; onePlayerRectSmall.y = twoPlayerRectSmall.y = 172; onePlayerRectLarge.y = twoPlayerRectLarge.y = 170; SDL_Rect autuinRect; autuinRect.x = 35; autuinRect.y = 187; Uint32 black = SDL_MapRGB(vscreen->format, 0, 0, 0); Mix_Chunk *boop = Mix_LoadWAV("boop.wav"); Mix_Chunk *theme = Mix_LoadWAV("title.wav"); if (!boop || !theme) { fprintf(stderr, "Could not load audio.\n"); return MENU_ERROR; } // Initialize the star locations and speeds Star stars[NUM_STARS]; for (int i=0; i<NUM_STARS; i++) { stars[i].x = random() / ((float) RAND_MAX) * SCREEN_WIDTH; stars[i].y = random() / ((float) RAND_MAX) * SCREEN_HEIGHT; float intensity = random() / (float) RAND_MAX; unsigned char colourIntensity = (intensity * 155) + 100; stars[i].speed = intensity * .2; stars[i].colour = SDL_MapRGB(vscreen->format, colourIntensity, colourIntensity, colourIntensity); } Mix_PlayChannel(-1, theme, -1); char selectedOption = 0; unsigned int frame = 0; while (!leave) { // Handle events frameStart = SDL_GetTicks(); SDL_Event e; while (SDL_PollEvent(&e)) switch (e.type) { case SDL_KEYDOWN: switch (e.key.keysym.sym) { case SDLK_UP: case SDLK_LEFT: if (selectedOption != 0) Mix_PlayChannel(-1, boop, 0); selectedOption = 0; frame = 0; break; case SDLK_DOWN: case SDLK_RIGHT: if (selectedOption != 1) Mix_PlayChannel(-1, boop, 0); selectedOption = 1; frame = 0; break; case SDLK_ESCAPE: selectedOption = -1; leave = true; break; case SDLK_UNKNOWN: // Suspend button selectedOption = -2; leave = true; break; case SDLK_RETURN: leave = true; break; case SDL_QUIT: selectedOption = -1; leave = true; break; } } // Debounce any keys currently down (wait 1 sec) if (frame >= FPS && controllerHasData()) { unsigned int c = readController(); if ((c & P1_LEFT) && selectedOption != 0) { Mix_PlayChannel(-1, boop, 0); selectedOption = 0; } else if ((c & P1_RIGHT) && selectedOption != 1) { Mix_PlayChannel(-1, boop, 0); selectedOption = 1; } else if (c & P1_FIRE) { leave = true; } else if (c & SELECT) { selectedOption = -1; leave = true; } frame = FPS; } // Draw the frame SDL_FillRect(vscreen, NULL, black); SDL_LockSurface(vscreen); Uint32 *s = (Uint32 *) vscreen->pixels; for (unsigned int i=0; i<NUM_STARS; i++) { unsigned x = stars[i].x, y = stars[i].y; *(s + (y * SCREEN_WIDTH) + x) = stars[i].colour; stars[i].y += stars[i].speed; if (stars[i].y >= SCREEN_HEIGHT) stars[i].y = 0; } SDL_UnlockSurface(vscreen); SDL_BlitSurface(background, NULL, vscreen, NULL); SDL_BlitSurface(autuinText, NULL, vscreen, &autuinRect); SDL_BlitSurface( selectedOption==0?onePlayerTextLarge:onePlayerTextSmall, NULL, vscreen, selectedOption==0?&onePlayerRectLarge:&onePlayerRectSmall ); SDL_BlitSurface( selectedOption==1?twoPlayerTextLarge:twoPlayerTextSmall, NULL, vscreen, selectedOption==1?&twoPlayerRectLarge:&twoPlayerRectSmall ); // Double up the resolution SDL_Surface *zoomed = zoomSurface(vscreen, 2, 2.31, 0); SDL_BlitSurface(zoomed, NULL, screen, NULL); SDL_FreeSurface(zoomed); // Blit the frame SDL_Flip(screen); // Go to sleep SDL_Delay(FRAME_TICKS - (SDL_GetTicks() - frameStart)); frame++; if (frame > FPS * 30) { attractor(screen, vscreen); frame = 0; } } // Stop the audio Mix_HaltChannel(-1); // One last boop for the quit/play action Mix_PlayChannel(-1, boop, 0); while(Mix_Playing(-1) != 0) SDL_Delay(10); // Free resources SDL_FreeSurface (background); SDL_FreeSurface (autuinText); SDL_FreeSurface (onePlayerTextSmall); SDL_FreeSurface (twoPlayerTextSmall); SDL_FreeSurface (onePlayerTextLarge); SDL_FreeSurface (twoPlayerTextLarge); Mix_FreeChunk(boop); Mix_FreeChunk(theme); switch (selectedOption) { case -2: return MENU_SUSPEND; case -1: return MENU_QUIT; case 0: return MENU_ONEPLAYER; case 1: return MENU_TWOPLAYER; } }
void main() { vec4 pos = texture2D(tPositions, vUv); vec4 pos_prev = texture2D(tPositions2, vUv); // derive velocity vec3 velocity = pos_prev.xyz - pos.xyz; vec3 pos_new; if (home > 0 || explosionType > 2) { // HOME MODE if (explosionType == 3) { pos_new = velocity * damping + pos_prev.xyz; } else if (explosionType == 5) { pos_new = sphere(vUv); } else if (explosionType == 6) { pos_new = cone(vUv); } else if (explosionType == 7) { pos_new = supershape(vUv); } else { pos_new = getInitialTexturePos(vUv, fboWidth, photoDimensions); } if (implode == 1) { pos_new = pos_prev.xyz + (pos_new - pos_prev.xyz) * clamp(exp_ease_out(transition / 0.8), 0.0, 1.0); } } else { // EXPLOSION MODE if (explosionType == 0) { velocity.x += SimplexPerlin3D(vec3(pos_prev.x / width, pos_prev.y / width, time)) / slowness; // velocity.y += SimplexPerlin3D(vec3(pos_prev.x / width + offset, pos_prev.y / width + offset, time)) / slowness; velocity.z += SimplexPerlin3D(vec3(pos_prev.x / width * 4.0 + 2.0 * offset, pos_prev.y / width * 4.0 + 2.0 * offset, time)) / slowness / 4.0; // DAMPING velocity.xyz *= damping; } else { vec4 pixel_color = texture2D(photoTexture, vUv); vec3 r_attractor_pos = vec3(-600.0, -200.0, -340.0); vec3 g_attractor_pos = vec3(-100.0, 400, -350.0); vec3 b_attractor_pos = vec3(400.0, -100.0, -300.0); float d = (explosionType == 2) ? -delta : delta; velocity += attractor(pos_prev.xyz, r_attractor_pos, pixel_color.r * d); velocity += attractor(pos_prev.xyz, g_attractor_pos, pixel_color.g * d); velocity += attractor(pos_prev.xyz, b_attractor_pos, pixel_color.b * d); // speed limit float speed_limit = 9.0; if (length(velocity) > speed_limit) { velocity = normalize(velocity) * speed_limit; } } pos_new = pos_prev.xyz + velocity; } // Write new position out gl_FragColor = vec4(pos_new, 1.0); }