381 lines
8.7 KiB
C++
381 lines
8.7 KiB
C++
#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;
|
|
}
|
|
}
|