#include #include #include #include "player.h" #include "input.h" #include "libs/mainloop-api/mainloop.h" #include "textures.h" #include "blocks.h" #include "world.h" #include "math.h" double player_power = 0; double player_angle[2] = {0, 0}; double player_pos[3] = {10, 0, 0}; double player_max_speed = 0.001; double fall_speed = 0; bool break_block_pressed = false; bool place_block_pressed = false; int TEX_CAR; int TEX_BOAT; int TEX_PLANE; int TEX_EDITOR; int player_mode = PLAYER_BOAT; void player_init() { // Load the vehicles textures int w, h; //TEX_CAR = loadArchiveImageGL("textures/vehicles/car_inside.rimg", 'L', w, h); //TEX_BOAT = loadArchiveImageGL("textures/vehicles/boat_inside.rimg", 'L', w, h); //TEX_PLANE = loadArchiveImageGL("textures/vehicles/plane_inside.rimg", 'L', w, h); TEX_EDITOR = loadArchiveImageGL("textures/vehicles/editor_inside.rimg", 'L', w, h); } void player_render() { // Car if(player_mode == PLAYER_CAR) { // Bind the texture glBindTexture(GL_TEXTURE_2D, TEX_EDITOR); } // Boat if(player_mode == PLAYER_BOAT) { // Bind the texture glBindTexture(GL_TEXTURE_2D, TEX_EDITOR); } // Editor if(player_mode == PLAYER_EDITOR) { // Bind the texture glBindTexture(GL_TEXTURE_2D, TEX_EDITOR); } glColor4f(1.0f,1.0f,1.0f,1.0f); glBegin(GL_QUADS); glTexCoord2d(0,0); glVertex2d(-1, 1); glTexCoord2d(1,0); glVertex2d( 1, 1); glTexCoord2d(1,1); glVertex2d( 1,-1); glTexCoord2d(0,1); glVertex2d(-1,-1); glEnd(); } void player_actions(int *args) { // Make this happen again mainloopRegAction(player_actions, 10, 0); // Is the player out of the world or player pressed respawn if(player_pos[1] < -1000 || gpad_button_pressed(BUTTON_X)) { // Make the player respawn player_respawn(); // Reset the power player_power = 0; } // Copy the current position double nx = player_pos[0]; double ny = player_pos[1]; double nz = player_pos[2]; // Is this the editor if(player_mode == PLAYER_EDITOR) { // Create the bullet double bullet[3] = {player_pos[0], player_pos[1], player_pos[2]}; if( (gpad_trigger_length(TRIGGER_RIGHT) >= 0.5 && !place_block_pressed) || (gpad_trigger_length(TRIGGER_LEFT) >= 0.5 && !break_block_pressed) ){ // While the bullet isnt touching anything while( block_isnt_solid((int)bullet[0], (int)bullet[1], (int)bullet[2]) && block_in_world((int)bullet[0], (int)bullet[1], (int)bullet[2]) ){ // Move the bullet double y_movement = sin((player_angle[1]+90)*(PI/180.0)); bullet[0] += -cos((player_angle[0]+90)*(PI/180.0))*y_movement*0.01; bullet[2] += -sin((player_angle[0]+90)*(PI/180.0))*y_movement*0.01; bullet[1] += cos((player_angle[1]+90)*(PI/180.0))*0.01; } // Place if(gpad_trigger_length(TRIGGER_RIGHT) >= 0.5 && !place_block_pressed) { // Move the bullet double y_movement = sin((player_angle[1]+90)*(PI/180.0)); bullet[0] -= -cos((player_angle[0]+90)*(PI/180.0))*y_movement*0.01; bullet[2] -= -sin((player_angle[0]+90)*(PI/180.0))*y_movement*0.01; bullet[1] -= cos((player_angle[1]+90)*(PI/180.0))*0.01; // Set a block if(block_in_world((int)bullet[0], (int)bullet[1], (int)bullet[2])) { set_block_at((int)bullet[0], (int)bullet[1], (int)bullet[2], BLOCK_STONE); } // Set the place block check varible to true place_block_pressed = true; } // Break if(gpad_trigger_length(TRIGGER_LEFT) >= 0.5 && !break_block_pressed) { // Set an air block if(block_in_world((int)bullet[0], (int)bullet[1], (int)bullet[2])) { set_block_at((int)bullet[0], (int)bullet[1], (int)bullet[2], BLOCK_AIR); } // Set the break block check varible to true break_block_pressed = true; } } // Place block button released if(gpad_trigger_length(TRIGGER_RIGHT) < 0.5 && place_block_pressed) { // Reset the check varible place_block_pressed = false; } // Break block button released if(gpad_trigger_length(TRIGGER_LEFT) < 0.5 && break_block_pressed) { // Reset the check varible break_block_pressed = false; } // Set the default movement power double power = 0.1; // Is the up button pressed if(gpad_button_pressed(BUTTON_A)) { // Go up ny += power; } // Is the down button pressed if(gpad_button_pressed(BUTTON_B)) { // Go down ny -= power; } // Get the stick values float lx, ly, rx, ry; gpad_stick_value(STICK_LEFT, lx, ly); gpad_stick_value(STICK_RIGHT, rx, ry); // Set the movement values nx += -cos((player_angle[0]+90)*(PI/180.0))*ly*power; nz += -sin((player_angle[0]+90)*(PI/180.0))*ly*power; nx += -cos((player_angle[0]+180)*(PI/180.0))*lx*power; nz += -sin((player_angle[0]+180)*(PI/180.0))*lx*power; // Change the players angle player_angle[0] += rx; player_angle[1] -= ry; } else { // Can the user move bool can_move = true; // Is the player a boat if(player_mode == PLAYER_BOAT) { // Is their water under the player can_move = block_is_fluid(player_pos[0], player_pos[1]-1, player_pos[2]); } // Can the user move if(can_move) { // Add power player_power += 0.000002*gpad_trigger_length(TRIGGER_RIGHT); // Add reverse power player_power -= 0.000002*gpad_trigger_length(TRIGGER_LEFT); } // Is the power positive if(player_power > 0) { // Reduce some power player_power -= 0.0000001; } // Is the power negative else if(player_power < 0) { // Reduce some power in the other direction player_power += 0.0000001; } // Is the power too low if(player_power < -player_max_speed) { // Set the value to the fastest speed player_power = -player_max_speed; } // Is the power too high if(player_power > player_max_speed) { // Set it to the maximum player_power = player_max_speed; } // Make the player go forward double p = sin((player_power/player_max_speed*90.0)*(PI/180.0)); nx += -cos((player_angle[0]+90)*(PI/180.0))*p; nz += -sin((player_angle[0]+90)*(PI/180.0))*p; // Change the angle float lx, ly; gpad_stick_value(STICK_LEFT, lx, ly); double max_turn = PI/32.0; // Can the user change the angle if(can_move) { // Too sharp turn forwards if(p>max_turn) { // Reset the angle player_angle[0] += lx*max_turn*10; } // Too sharp turn backwards else if(p<-max_turn) { // Reset the angle player_angle[0] += lx*-max_turn*10; } else { // Turn due to speed player_angle[0] += lx*p*10; } } if( // Is the player in water block_is_fluid(player_pos[0], player_pos[1], player_pos[2]) && // Is the player a boat player_mode == PLAYER_BOAT ){ // Increase the falling varible negatively if(fall_speed > 0) fall_speed -= 0.008; else fall_speed -= 0.004; // Make the player fall ny -= fall_speed; } // Is there air under the player else if(block_isnt_solid(player_pos[0], player_pos[1]-1, player_pos[2])) { // Increase the falling varible if(fall_speed < 0) fall_speed += 0.008; else fall_speed += 0.004; // Make the player fall ny -= fall_speed; } } // Is the angle out of range while(player_angle[0] > 360) player_angle[0] -= 360; while(player_angle[0] < 0) player_angle[0] += 360; if(player_angle[1] > 90) player_angle[1] = 90; if(player_angle[1] < -90) player_angle[1] = -90; /*// Is the move valid if(block_is_air(nx, ny, nz)) { // Update the position player_pos[0] = nx; player_pos[1] = ny; player_pos[2] = nz; }*/ double invert_multiply = -0.25; if( block_isnt_solid(player_pos[0], ny, player_pos[2]) && block_isnt_solid(player_pos[0], ny-1, player_pos[2]) ){ // Update the position player_pos[1] = ny; } else { // Stop falling fall_speed = 0; } // Is the move valid if(block_isnt_solid(nx, player_pos[1], player_pos[2])) { // Is the lower block solid while( !block_isnt_solid(nx, player_pos[1]-1, player_pos[2]) && block_isnt_solid(player_pos[0], ny+1, player_pos[2]) ){ // Teleport the player up it player_pos[1] += 0.01; } // Update the position player_pos[0] = nx; } else { // Invert the player motion player_power *= invert_multiply; } if(block_isnt_solid(player_pos[0], player_pos[1], nz)) { // Is the lower block solid while( !block_isnt_solid(player_pos[0], player_pos[1]-1, nz) && block_isnt_solid(player_pos[0], ny+1, player_pos[2]) ){ // Teleport the player up it player_pos[1] += 0.01; } // Update the position player_pos[2] = nz; } else { // Invert the player motion player_power *= invert_multiply; } }