racing_game/player.cpp

381 lines
8.7 KiB
C++
Raw Normal View History

2019-05-25 14:24:49 +10:00
#include <GL/glut.h>
#include <math.h>
#include <iostream>
#include "player.h"
#include "input.h"
#include "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;
}
}