Esempio n. 1
0
bool addParticle(tEmitter *emitter)
{
	tParticle *particle;
	if (emitter != NULL && particlePool.head->next != NULL &&
	emitter->particleCount < emitter->maxParticles) {
		particle = particlePool.head->next; 
		//saca la particual del pool
		particlePool.head->next=particle->next;
		if (particle->next != NULL) particle->next->prev = particle->prev;
		//enlaza la particula en el emisor
		if (emitter->particle != NULL) emitter->particle->prev = particle;
		particle->next = emitter->particle;
		particle->prev = NULL;
		emitter->particle = particle;
		particle->radius = min_radius;
		particle->pos= emitter->pos;
		particle->prevPos= emitter->pos;
		particle->vel.x = emitter->vel.x*(1+emitter->speedVar * CORE_FRand(-1,1));
		particle->vel.y = emitter->vel.y*(1+emitter->speedVar * CORE_FRand(0,1));
		particle->index = texsmallball;
//		particle->color = tColor(1,1,1);//RGB color
		particle->life=emitter->life + (int)((float)emitter->lifeVar* CORE_FRand(0,1));
		particle->mass=1.0f+(int)((float)emitter->lifeVar* CORE_FRand(0,1));
//		particle->deltaColor = 1.0/ particle->life;
		emitter->particleCount++;
		return true;
	}
	return false;
}
Esempio n. 2
0
void GenNextElements()
{
	// Called every game loop, but only does work when close to next challange area
	if (g_current_race_pos + 2 * G_HEIGHT > g_next_challange_area)
	{
		float current_y = g_next_challange_area;
		LOG(("Current: %f\n", g_next_challange_area));

		// Choose how many layers of rocks
		int nlayers = (int)CORE_URand(1, 20);
		LOG(("nlayers: %d\n", nlayers));
		for (int i = 0; i < nlayers; i++)
		{
			LOG(("Where: %f\n", current_y));

			// Choose pass point
			float displace = (current_y - g_last_conditioned.y) * PATH_TWIST_RATIO;
			float bracket_left = g_last_conditioned.x - displace;
			float bracket_right = g_last_conditioned.x + displace;
			bracket_left = MAX(bracket_left, 2.f * MAINSHIP_RADIUS);
			bracket_right = MIN(bracket_right, G_WIDTH - 2.f * MAINSHIP_RADIUS);
			g_last_conditioned.y = current_y;
			g_last_conditioned.x = CORE_FRand(bracket_left, bracket_right);

			// Choose how many rocks
			int nrocks = (int)CORE_URand(0, 3);
			LOG(("nrocks: %d\n", nrocks));

			// Generate rocks
			for (int i = 0; i < nrocks; i++)
			{
				// Find a valid position
				vec2 rockpos;
				for (;;)
				{
					rockpos = vmake(CORE_FRand(0.f, G_WIDTH), current_y);
					if (rockpos.x + ROCK_RADIUS < g_last_conditioned.x - PATH_WIDTH
						|| rockpos.x - ROCK_RADIUS > g_last_conditioned.x + PATH_WIDTH)
						break;
				}
				// Insert obstacle
				EType t = E_ROCK;
				int gfx = g_rock[1/*CORE_URand(0,4)*/];
				if (CORE_RandChance(0.1f)) { t = E_MINE; gfx = g_mine; } // Mine?
				else if (CORE_RandChance(0.1f)) { t = E_DRONE; gfx = g_drone; } // Drone?
				vec2 vel = vmake(CORE_FRand(-0.5f, 0.5f), CORE_FRand(-0.5f, 0.5f)); // velocity
				InsertEntity(t, rockpos, vel, ROCK_RADIUS, gfx, true); // Insert the chosen entity

			}
			current_y += CORE_FRand(300.f, 600.f);
		}
		g_next_challange_area = current_y + CORE_FRand(.5f * G_HEIGHT, 1.5f * G_HEIGHT);
	}
}
Esempio n. 3
0
bool updateEmitter(tEmitter *emitter, tVector forces, float dt)
{
	int loop,emits;
	tParticle *particle, *next;
	if (emitter != NULL)
	{
		emitter->forces=forces;
		if (emitter->particle != NULL)
		{
			particle = emitter->particle;
			while (particle)
			{
				next = particle->next;
				updateParticle(particle,emitter,dt);
				particle = next;
			}
		}
		emits=emitter->emitsPerFrame+(int)((float)emitter->emitVar*CORE_FRand(0,1));
		for (loop = 0; loop < emits; loop++)
			addParticle(emitter);
		return TRUE;
	}
	return FALSE;
}
int Main(void)
{
  // Load resources
  texsmallball  = CORE_LoadBmp("data/tyrian_ball.32.bmp"      , false);
  texcursor  = CORE_LoadBmp("data/cursor.bmp", false);
  
  initCursor();

  initParticlePool(MAX_PARTICLES);

  //checking pool
  //while(particlePool.current)
  //{
	 // particlePool.current=particlePool.current->next;
  //}
  //particlePool.current = particlePool.head->next;

  initEmmiter();

  //for (int i = 0; i < NUM_PARTICLES; i++)
  //{
		//float radius;
		//radius = 8.f;
		//particle[i]=particlePool.current;
		//particlePool.current=particlePool.current->next;
		//particle[i]->radius = radius;
		//particle[i]->mass = 1.f;
		//particle[i]->index = texsmallball;
		//particle[i]->pos = vmake(CORE_FRand(radius, SCR_WIDTH-radius), CORE_FRand(radius, SCR_HEIGHT-radius));
		//particle[i]->vel = vmake(CORE_FRand(-MAX_BALL_SPEED, +MAX_BALL_SPEED), CORE_FRand(-MAX_BALL_SPEED, +MAX_BALL_SPEED));
  //}


  // Set up rendering
  glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT); // Sets up clipping
  glClearColor( 0.0f, 0.1f, 0.3f, 0.0f );
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho( 0.0, SCR_WIDTH, 0.0, SCR_HEIGHT, 0.0, 1.0);
  glEnable(GL_TEXTURE_2D);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  DWORD start_tick= GetTickCount();

  while (!SYS_GottaQuit())
  {
    // Render
    glClear( GL_COLOR_BUFFER_BIT );
		
	CORE_RenderCenteredSprite(cursor->pos, 
				vmake(cursor->radius , cursor->radius ), cursor->index);

	//fixed substep
	float dt =1.0f/(substep*FPS);
	//adaptive substep
	//DWORD elapsed_ticks= GetTickCount()- start_tick;
	//float elapsed_dt= elapsed_ticks/TICKS_PER_SECOND;

	//float edt_dt = elapsed_dt/dt;
	//int ite = (int)edt_dt;
	//float lastdt= edt_dt - ite;

	tVector forces=vmake(0,-100.0f);

//	for( int i=0; i < ite; i++)
		updateEmitter( myEmmiter, forces, dt);

//	updateEmitter( myEmmiter, forces, lastdt);
	applyDeflectors(myEmmiter);

	renderParticles(myEmmiter);

	SYS_Show();

	start_tick= GetTickCount();
    // Keypress!
    if (SYS_KeyPressed('O'))
    {
		if(cursor)cursor->pos.x-=1.0f;;
	}
    if (SYS_KeyPressed('P'))
    {
		if(cursor)cursor->pos.x+=1.0f;;
	}
    if (SYS_KeyPressed('Q'))
    {
		if(cursor)cursor->pos.y+=1.0f;;
	}
    if (SYS_KeyPressed('A'))
    {
		if(cursor)cursor->pos.y-=1.0f;;
	}

    if (0)//SYS_KeyPressed('I'))
    {
		//start single ball at random
		float radius=16.f;
		GLuint texBall=texsmallball;
		float mass=1.0f;
		int index=(int)CORE_FRand(0, MAX_PARTICLES-1);

		//particle[index]->mass = mass;
		//particle[index]->index = texBall;
		//particle[index]->radius = radius;
	 //   particle[index]->pos = vmake(CORE_FRand(radius, SCR_WIDTH-radius), CORE_FRand(SCR_HEIGHT*.5f, SCR_HEIGHT-radius));
		//particle[index]->vel = vmake(0, 10);
	}
    if (0)//SYS_KeyPressed(' '))
    {
		//give an impulse to all balss

//      for (int i = 0; i < MAX_PARTICLES; i++)
//	  {
          //if (fabs(particle[i]->vel.x) < 0.1f)
          //  particle[i]->vel.x = CORE_FRand(-MAX_BALL_SPEED, +MAX_BALL_SPEED);
          //particle[i]->vel.y = CORE_FRand(0, JUMP_SPEED);
//	  }
    }
    if (0)//SYS_KeyPressed(VK_CONTROL))
    {
	  //reset all
		glClear( GL_COLOR_BUFFER_BIT );

  //    for (int i = 0; i < MAX_PARTICLES; i++)
	 // {
		//float radius=particle[i]->radius;
		//particle[i]->pos = vmake(CORE_FRand(radius, SCR_WIDTH-radius), CORE_FRand(radius, SCR_HEIGHT-radius));
		//particle[i]->vel = vmake(0, 10);
	 // }
	  SYS_Show();
	}
    // Keep system running
    SYS_Pump();
    SYS_Sleep(17);
  }

  CORE_UnloadBmp(texsmallball);
  CORE_UnloadBmp(texcursor);

  destroyEmmmiter(myEmmiter);
  destroyParticlePool();
  destroyCursor();

  return 0;
}
Esempio n. 5
0
//-----------------------------------------------------------------------------
void RunGame()
{
	// Control main ship
	if (g_gs == GS_VICTORY || g_gs == GS_STARTING)
	{
		if (MAIN_SHIP.vel.y < SHIP_CRUISE_SPEED)
		{
			MAIN_SHIP.vel.y = SAFEADD(MAIN_SHIP.vel.y, SHIP_INC_SPEED, SHIP_CRUISE_SPEED);
		}
		MAIN_SHIP.fuel = SAFESUB(MAIN_SHIP.fuel, FRAME_FUEL_COST);
	}

	// Heal main ship
	if (g_gs != GS_DYING)
	{
		if (MAIN_SHIP.energy < MAX_ENERGY && MAIN_SHIP.fuel > MIN_FUEL_FOR_HEAL)
		{
			MAIN_SHIP.energy = SAFEADD(MAIN_SHIP.energy, ENERGY_HEAL_PER_FRAME, MAX_ENERGY);
			MAIN_SHIP.fuel = SAFESUB(MAIN_SHIP.fuel, FUEL_HEAL_PER_FRAME);
			LOG(("- energy: %f, fuel: %f\n", MAIN_SHIP.energy, MAIN_SHIP.fuel));
		}
	}

	// Move entities
	for (int i = MAX_ENTITIES - 1; i >= 0; i--)
	{
		if (g_entities[i].type != E_NULL)
		{
			g_entities[i].pos = vadd(g_entities[i].pos, g_entities[i].vel);

			// Remove entities that fell off screen
			if (g_entities[i].pos.y < g_camera_offset - G_HEIGHT)
				g_entities[i].type = E_NULL;
		}
	}

	// Advance "stars"
	for (int i = 0; i < MAX_ENTITIES; i++)
	{
		if (g_entities[i].type == E_STAR)
			g_entities[i].gfxscale *= 1.008f;
	}

	// Dont let steering off the screen
	if (MAIN_SHIP.pos.x < MAINSHIP_RADIUS)
		MAIN_SHIP.pos.x = MAINSHIP_RADIUS;
	if (MAIN_SHIP.pos.x > G_WIDTH - MAINSHIP_RADIUS)
		MAIN_SHIP.pos.x = G_WIDTH - MAINSHIP_RADIUS;

	// Check collisions
	if (g_gs == GS_PLAYING)
	{
		// Check everything against ship
		for (int i = 1; i < MAX_ENTITIES; i++)
		{
			// Should check against ship?
			if (g_entities[i].type == E_ROCK
				|| g_entities[i].type == E_JUICE
				|| g_entities[i].type == E_MINE
				|| g_entities[i].type == E_DRONE)
			{
				float distance = vlen2(vsub(g_entities[i].pos, MAIN_SHIP.pos)); // Distance from object to ship
				float crash_distance = CORE_FSquare(g_entities[i].radius + MAIN_SHIP.radius); // Minimum allowed distance before crash
				if (distance < crash_distance)
				{
					switch (g_entities[i].type)
					{
					case E_ROCK:
						if (g_entities[i].energy > 0)
						{
							MAIN_SHIP.energy = SAFESUB(MAIN_SHIP.energy, ROCK_CRASH_ENERGY_LOSS);
							MAIN_SHIP.vel.y = SHIP_START_SPEED;
							
							// Set rock velocity
							vec2 vel_direction = vsub(g_entities[i].pos, MAIN_SHIP.pos); // direction of rock velocity, away from ship
							vec2 normalized_vel_direction = vunit(vel_direction); // normalize
							vec2 vel = vscale(normalized_vel_direction, CRASH_VEL); // Scale, ie give the rock correct speed.
							g_entities[i].vel = vel;
							g_entities[i].energy = 0;
						}
						break;

					case E_JUICE:
						MAIN_SHIP.fuel = SAFEADD(MAIN_SHIP.fuel, JUICE_FUEL, MAX_FUEL);
						g_entities[i].type = E_NULL;
						break;

					case E_MINE:
						MAIN_SHIP.energy = SAFESUB(MAIN_SHIP.energy, MINE_CRASH_ENERGY_LOSS);
						MAIN_SHIP.vel.y = SHIP_START_SPEED;
						g_entities[i].type = E_NULL;
						break;

					case E_DRONE:
						MAIN_SHIP.energy = SAFESUB(MAIN_SHIP.energy, MINE_CRASH_ENERGY_LOSS);
						MAIN_SHIP.vel.y = SHIP_START_SPEED;
						g_entities[i].type = E_NULL;
						break;

					default:
						break;
					}
				}
			}
			else if (g_entities[i].type == E_ROCKET)
			{
				// Check all hit-able objects against this rocket
				for (int j = 1; i < MAX_ENTITIES; j++) 
				{
					// Should check against rocket?
					if (g_entities[j].type == E_ROCK
						|| g_entities[j].type == E_MINE
						|| g_entities[j].type == E_DRONE)
					{
						float distance = vlen2(vsub(g_entities[i].pos, g_entities[j].pos));
						float crash_distance = CORE_FSquare(g_entities[i].radius + g_entities[j].radius);
						if (distance < crash_distance)
						{
							// Impact!
							g_entities[i].type = E_NULL;
							g_entities[j].type = E_NULL;

							break;
						}
					}
				}
			}
		}
	}

	// Generate new level elements as we advance
	GenNextElements();

	// Possibly insert new juice
	if (g_gs == GS_PLAYING)
	{
		float trench = MAIN_SHIP.pos.y - g_current_race_pos; // How much advanced from previous frame
		if (CORE_RandChance(trench * JUICE_CHANCE_PER_PIXEL))
		{
			vec2 pos = vmake(CORE_FRand(0.f, G_WIDTH), g_camera_offset + G_HEIGHT + GEN_IN_ADVANCE); // Random x, insert 400y above window
			vec2 vel = vmake(CORE_FRand(-1.f, +1.f), CORE_FRand(-1.f, +1.f)); // Random small velocity to make rocks "float"
			InsertEntity(E_JUICE, pos, vel, JUICE_RADIUS, g_juice, false, true);
		}
	}

	// Set camera to follow the main ship
	g_camera_offset = MAIN_SHIP.pos.y - G_HEIGHT / 8.f;

	g_current_race_pos = MAIN_SHIP.pos.y;
	if (g_gs == GS_PLAYING)
	{
		if (g_current_race_pos >= RACE_END) // Check if victory
		{
			g_gs = GS_VICTORY;
			g_gs_timer = 0.f;
			MAIN_SHIP.gfxadditive = true;
		}
	}

	// Advance game mode
	g_gs_timer += FRAMETIME;
	switch (g_gs)
	{
	case GS_STARTING:
		if (g_gs_timer >= STARTING_TIME) // Start delay before starting to play
		{
			g_gs = GS_PLAYING;
			g_gs_timer = 0.f;
		}
		break;
	case GS_DYING:
		if (g_gs_timer >= DYING_TIME)
		{
			ResetNewGame();
		}
		break;
	case GS_PLAYING:
		if (MAIN_SHIP.energy <= 0.f || MAIN_SHIP.fuel <= 0.f) // No energy or fuel --> die
		{
			g_gs = GS_DYING;
			g_gs_timer = 0.f;
			MAIN_SHIP.gfx = g_ship_RR;
		}
		break;
	case GS_VICTORY:
		if (CORE_RandChance(1.f / 10.f))
		{
			InsertEntity(E_STAR, MAIN_SHIP.pos, vadd(MAIN_SHIP.vel, vmake(CORE_FRand(-5.f, 5.f), CORE_FRand(-5.f, 5.f))), 0, g_star, false, true);
		}
		
		if (g_gs_timer >= 8.f) // Should use VICTORY_TIME, but stupid VS dont want me to...
		{
			ResetNewGame();
		}
		break;
	}
	g_time_from_last_rocket += FRAMETIME;
}