示例#1
0
文件: game.cpp 项目: torgeha/Space
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);
	}
}
示例#2
0
文件: game.cpp 项目: torgeha/Space
//----------------------------------------------------------------------------
void ResetNewGame()
{
	// Reset everything for a new game
	g_next_challange_area = FIRST_CHALLANGE;
	g_last_conditioned = vmake(0.5f * G_WIDTH, 0.f);
	g_current_race_pos = 0.f;
	g_camera_offset = 0.f;
	g_rock_chance = START_ROCK_CHANCE_PER_PIXEL;
	g_gs = GS_STARTING;
	g_gs_timer = 0.f;

	// Start logic
	for (int i = 0; i < MAX_ENTITIES; i++)
	{
		g_entities[i].type = E_NULL;
	}
	// Insert main ship
	InsertEntity(E_MAIN, vmake(G_WIDTH / 2.0, G_HEIGHT / 8.f), vmake(0.f, SHIP_START_SPEED), MAINSHIP_RADIUS, g_ship_C, true);
}
示例#3
0
void initCursor()
{
	cursor = new tCursor;

	if( cursor)
	{
		cursor->pos= vmake(SCR_WIDTH*.7f, SCR_HEIGHT*.7f);
		cursor->radius=100.0;
		cursor->index = texcursor;
	}
}
示例#4
0
bool initEmmiter()
{
	myEmmiter = new tEmitter;
	strcpy(myEmmiter->name,"emmiter1");
	myEmmiter->id=0x0001;
	myEmmiter->flags=0;
	myEmmiter->prev=0;myEmmiter->next=0;

	myEmmiter->pos = vmake(SCR_WIDTH*.5f, SCR_HEIGHT*.3f);
	myEmmiter->vel = vmake(10.0,10.0);
	myEmmiter->speedVar = 10.0f;
	myEmmiter->particle=0;
	myEmmiter->maxParticles= MAX_PARTICLES;
	myEmmiter->particleCount=0;
	myEmmiter->emitsPerFrame = 1;//NUM_PARTICLES/10;
	myEmmiter->emitVar = 10;//NUM_PARTICLES/10;
	myEmmiter->life = 1000;
	myEmmiter->lifeVar = 50;
	myEmmiter->forces = vmake(0.0,0.0);

	return true;
}
示例#5
0
void renderParticles(tEmitter *emitter)
{
	if (emitter->particle != NULL)
	{
		tParticle* particle = emitter->particle;
		while (particle)
		{
			CORE_RenderCenteredSprite(particle->pos, 
				vmake(particle->radius , particle->radius ), particle->index);
			particle = particle->next;
		}
	}
}
示例#6
0
文件: game.cpp 项目: torgeha/Space
//-----------------------------------------------------------------------------
void InsertEntity(EType type, vec2 pos, vec2 vel, float radius, int gfx, bool has_shadow, bool additive = false)
{
	for (int i = 0; i < MAX_ENTITIES; i++)
	{
		if (g_entities[i].type == E_NULL)
		{
			g_entities[i].type =		type;
			g_entities[i].pos =			pos;
			g_entities[i].vel =			vel;
			g_entities[i].radius =		radius;
			g_entities[i].gfx =			gfx;
			g_entities[i].energy =		MAX_ENERGY;
			g_entities[i].fuel =		MAX_FUEL;
			g_entities[i].tilt =		0.f;
			g_entities[i].gfxscale =	1.f;
			g_entities[i].gfxadditive = additive;
			g_entities[i].color =		vmake(1.f, 1.f, 1.f, 1.f);
			g_entities[i].has_shadow =	has_shadow;
			break;
		}
	}
}
示例#7
0
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);

  initEmmiter();

  // 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);
	//add gravity
//	tVector emitterforces=vmake(0.0f,0.0f);
	tVector emitterforces= GRAVITY; //vmake(0,gravityForce);

	updateEmitter( myEmmiter, emitterforces, dt);

	applyDeflectors(myEmmiter);

	renderParticles(myEmmiter);

	SYS_Show();

	start_tick= GetTickCount();
    // Keypress!
	const float scale=2.0f;
    if (SYS_KeyPressed('O'))
    {
		if(cursor)cursor->pos.x-=1.0f*scale;
	}
    if (SYS_KeyPressed('P'))
    {
		if(cursor)cursor->pos.x+=1.0f*scale;
	}
    if (SYS_KeyPressed('Q'))
    {
		if(cursor)cursor->pos.y+=1.0f*scale;
	}
    if (SYS_KeyPressed('A'))
    {
		if(cursor)cursor->pos.y-=1.0f*scale;
	}
    if (SYS_KeyPressed('S'))
    {
		atractorScale*=1.1f;
		if( atractorScale > 1000.0f)atractorScale=1000.0f;
	}
    if (SYS_KeyPressed('W'))
    {
		atractorScale*=0.9f;
	}

    // Keep system running
    SYS_Pump();
    SYS_Sleep(17);
  }

  CORE_UnloadBmp(texsmallball);
  CORE_UnloadBmp(texcursor);

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

  return 0;
}
示例#8
0
static void
cpArbiterApplyImpulse_NEON(cpArbiter *arb)
{
    cpBody *a = arb->body_a;
    cpBody *b = arb->body_b;
    cpFloatx2_t surface_vr = vld((cpFloat_t *)&arb->surface_vr);
    cpFloatx2_t n = vld((cpFloat_t *)&arb->n);
    cpFloat_t friction = arb->u;

    int numContacts = arb->count;
    struct cpContact *contacts = arb->contacts;
    for(int i=0; i<numContacts; i++) {
        struct cpContact *con = contacts + i;
        cpFloatx2_t r1 = vld((cpFloat_t *)&con->r1);
        cpFloatx2_t r2 = vld((cpFloat_t *)&con->r2);

        cpFloatx2_t perp = vmake(-1.0, 1.0);
        cpFloatx2_t r1p = vmul(vrev(r1), perp);
        cpFloatx2_t r2p = vmul(vrev(r2), perp);

        cpFloatx2_t vBias_a = vld((cpFloat_t *)&a->v_bias);
        cpFloatx2_t vBias_b = vld((cpFloat_t *)&b->v_bias);
        cpFloatx2_t wBias = vmake(a->w_bias, b->w_bias);

        cpFloatx2_t vb1 = vadd(vBias_a, vmul_n(r1p, vget_lane(wBias, 0)));
        cpFloatx2_t vb2 = vadd(vBias_b, vmul_n(r2p, vget_lane(wBias, 1)));
        cpFloatx2_t vbr = vsub(vb2, vb1);

        cpFloatx2_t v_a = vld((cpFloat_t *)&a->v);
        cpFloatx2_t v_b = vld((cpFloat_t *)&b->v);
        cpFloatx2_t w = vmake(a->w, b->w);
        cpFloatx2_t v1 = vadd(v_a, vmul_n(r1p, vget_lane(w, 0)));
        cpFloatx2_t v2 = vadd(v_b, vmul_n(r2p, vget_lane(w, 1)));
        cpFloatx2_t vr = vsub(v2, v1);

        cpFloatx2_t vbn_vrn = vpadd(vmul(vbr, n), vmul(vr, n));

        cpFloatx2_t v_offset = vmake(con->bias, -con->bounce);
        cpFloatx2_t jOld = vmake(con->jBias, con->jnAcc);
        cpFloatx2_t jbn_jn = vmul_n(vsub(v_offset, vbn_vrn), con->nMass);
        jbn_jn = vmax(vadd(jOld, jbn_jn), vdup_n(0.0));
        cpFloatx2_t jApply = vsub(jbn_jn, jOld);

        cpFloatx2_t t = vmul(vrev(n), perp);
        cpFloatx2_t vrt_tmp = vmul(vadd(vr, surface_vr), t);
        cpFloatx2_t vrt = vpadd(vrt_tmp, vrt_tmp);

        cpFloatx2_t jtOld = {};
        jtOld = vset_lane(con->jtAcc, jtOld, 0);
        cpFloatx2_t jtMax = vrev(vmul_n(jbn_jn, friction));
        cpFloatx2_t jt = vmul_n(vrt, -con->tMass);
        jt = vmax(vneg(jtMax), vmin(vadd(jtOld, jt), jtMax));
        cpFloatx2_t jtApply = vsub(jt, jtOld);

        cpFloatx2_t i_inv = vmake(-a->i_inv, b->i_inv);
        cpFloatx2_t nperp = vmake(1.0, -1.0);

        cpFloatx2_t jBias = vmul_n(n, vget_lane(jApply, 0));
        cpFloatx2_t jBiasCross = vmul(vrev(jBias), nperp);
        cpFloatx2_t biasCrosses = vpadd(vmul(r1, jBiasCross), vmul(r2, jBiasCross));
        wBias = vadd(wBias, vmul(i_inv, biasCrosses));

        vBias_a = vsub(vBias_a, vmul_n(jBias, a->m_inv));
        vBias_b = vadd(vBias_b, vmul_n(jBias, b->m_inv));

        cpFloatx2_t j = vadd(vmul_n(n, vget_lane(jApply, 1)), vmul_n(t, vget_lane(jtApply, 0)));
        cpFloatx2_t jCross = vmul(vrev(j), nperp);
        cpFloatx2_t crosses = vpadd(vmul(r1, jCross), vmul(r2, jCross));
        w = vadd(w, vmul(i_inv, crosses));

        v_a = vsub(v_a, vmul_n(j, a->m_inv));
        v_b = vadd(v_b, vmul_n(j, b->m_inv));

        // TODO would moving these earlier help pipeline them better?
        vst((cpFloat_t *)&a->v_bias, vBias_a);
        vst((cpFloat_t *)&b->v_bias, vBias_b);
        vst_lane((cpFloat_t *)&a->w_bias, wBias, 0);
        vst_lane((cpFloat_t *)&b->w_bias, wBias, 1);

        vst((cpFloat_t *)&a->v, v_a);
        vst((cpFloat_t *)&b->v, v_b);
        vst_lane((cpFloat_t *)&a->w, w, 0);
        vst_lane((cpFloat_t *)&b->w, w, 1);

        vst_lane((cpFloat_t *)&con->jBias, jbn_jn, 0);
        vst_lane((cpFloat_t *)&con->jnAcc, jbn_jn, 1);
        vst_lane((cpFloat_t *)&con->jtAcc, jt, 0);
    }
}
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;
}
示例#10
0
文件: game.cpp 项目: torgeha/Space
//-----------------------------------------------------------------------------
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;
}
示例#11
0
文件: game.cpp 项目: torgeha/Space
void Render()
{
	glClear(GL_COLOR_BUFFER_BIT);

	// Render background, only tiles within camera view
	int first_tile = (int)floorf(g_camera_offset / G_HEIGHT);
	for (int i = first_tile; i < first_tile + 2; i++)
	{
		vec2 pos = vsub(vadd(vmake(G_WIDTH / 2.0f, G_HEIGHT / 2.0f), vmake(0.f, (float)i * G_HEIGHT)), vmake(0.f, g_camera_offset)); // split up, what does it?
		vec2 size = vmake(G_WIDTH, G_HEIGHT);
		CORE_RenderCenteredSprite(pos, size, g_bkg);
	}

	// Draw entities
	for (int i = MAX_ENTITIES - 1; i >= 0; i--)
	{
		if (g_entities[i].type != E_NULL)
		{
			ivec2 size = CORE_GetBmpSize(g_entities[i].gfx);
			vec2 pos = g_entities[i].pos;
			pos.x = (float)((int)pos.x);
			pos.y = (float)((int)pos.y);

			if (g_entities[i].has_shadow) // renders shadows first
			{
				vec2 s_pos = vadd(vsub(pos, vmake(0.f, g_camera_offset)), vmake(0.f, -SHADOW_OFFSET));
				vec2 s_size = vmake(size.x * SPRITE_SCALE * g_entities[i].gfxscale * SHADOW_SCALE, size.y * SPRITE_SCALE * g_entities[i].gfxscale * SHADOW_SCALE);
				int s_texture = g_entities[i].gfx;
				rgba s_color = vmake(0.f, 0.f, 0.f, 0.4f);
				bool s_additive = g_entities[i].gfxadditive;
				CORE_RenderCenteredSprite(s_pos, s_size, s_texture, s_color, s_additive);
			}

			// Render not shadows
			vec2 offset_pos = vsub(pos, vmake(0.f, g_camera_offset)); // Adjust to where camera is at
			vec2 scaled_size = vmake(size.x * SPRITE_SCALE * g_entities[i].gfxscale, size.y * SPRITE_SCALE * g_entities[i].gfxscale);
			int texture = g_entities[i].gfx;
			rgba color = g_entities[i].color;
			bool additive = g_entities[i].gfxadditive;
			CORE_RenderCenteredSprite(offset_pos, scaled_size, texture, color, additive);
		}
	}

	if (g_gs != GS_VICTORY) // if not yet won
	{
		// Draw UI
		// The energy bar
		float energy_ratio = MAIN_SHIP.energy / MAX_ENERGY;
		vec2 e_bar_pos = vmake(ENERGY_BAR_W / 2.f, energy_ratio * ENERGY_BAR_H / 2.f);
		vec2 e_bar_size = vmake(ENERGY_BAR_W, ENERGY_BAR_H * energy_ratio);
		CORE_RenderCenteredSprite(e_bar_pos, e_bar_size, g_energy, COLOR_WHITE, true);

		// The fuel bar
		float fuel_ratio = MAIN_SHIP.fuel / MAX_FUEL;
		vec2 f_bar_pos = vmake(G_WIDTH - FUEL_BAR_W / 2.f, fuel_ratio * FUEL_BAR_H / 2.f);
		vec2 f_bar_size = vmake(FUEL_BAR_W, FUEL_BAR_H * fuel_ratio);
		CORE_RenderCenteredSprite(f_bar_pos, f_bar_size, g_fuel, COLOR_WHITE, true);

		// Draw how long you have lasted
		int num_chunks = (int)((g_current_race_pos / RACE_END) * MAX_CHUNKS);
		for (int i = 0; i < num_chunks; i++)
		{
			vec2 c_pos = vmake(G_WIDTH - 100.f, 50.f + i * 50.f);
			vec2 c_size = vmake(CHUNK_W, CHUNK_H);
			CORE_RenderCenteredSprite(c_pos, c_size, g_pearl);
		}
	}
}
示例#12
0
文件: game.cpp 项目: torgeha/Space
	CORE_UnloadBmp(g_bkg);
	CORE_UnloadBmp(g_rock[0]);
	CORE_UnloadBmp(g_rock[1]);
	CORE_UnloadBmp(g_rock[2]);
	CORE_UnloadBmp(g_rock[3]);
	CORE_UnloadBmp(g_rock[4]);
	CORE_UnloadBmp(g_pearl);
	CORE_UnloadBmp(g_energy);
	CORE_UnloadBmp(g_fuel);
	CORE_UnloadBmp(g_star);
}

//----------------------------------------------------------------------------------
// Level generation
float g_next_challange_area = FIRST_CHALLANGE;
vec2 g_last_conditioned = vmake(0.f, 0.f);
#define PATH_TWIST_RATIO .5f // This means about 30 degrees maximum
#define PATH_WIDTH (2.f * MAINSHIP_RADIUS)

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++)