draw overlay hover bar
draw border around overlay map Changed from refptr<map<U8, Player> > to map<U8, refptr<player> > minor bugfix - using more memory on sky than needed Fixed some bugs with multiplayer CCFS: print error when unable to find file by default simplify GLProgram creation with stdarg
This commit is contained in:
parent
abd731f3ca
commit
eacfd38e15
18
assets/fs/shaders/overlay_hover.f.glsl
Normal file
18
assets/fs/shaders/overlay_hover.f.glsl
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
varying vec3 pos_i;
|
||||
|
||||
const vec4 red = vec4(1, 0, 0, 1);
|
||||
const vec4 yellow = vec4(1, 1, 0, 1);
|
||||
const vec4 green = vec4(0, 1, 0, 1);
|
||||
|
||||
void main(void)
|
||||
{
|
||||
if (pos_i.x < 0)
|
||||
{
|
||||
gl_FragColor = mix(red, yellow, pos_i.x + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_FragColor = mix(yellow, green, pos_i.x);
|
||||
}
|
||||
}
|
10
ccfs_gen.py
10
ccfs_gen.py
@ -47,6 +47,8 @@ def main(argv):
|
||||
c_file = open(out_fname, 'w')
|
||||
h_file = open(header_fname, 'w')
|
||||
c_file.write('#include <string.h>\n')
|
||||
c_file.write('#include <iostream>\n')
|
||||
c_file.write('using namespace std;\n')
|
||||
c_file.write('#include "%s"\n' % os.path.basename(header_fname))
|
||||
for p in paths:
|
||||
c_name = cname(p)
|
||||
@ -77,7 +79,8 @@ def main(argv):
|
||||
c_file.write('};\n')
|
||||
|
||||
c_file.write('''
|
||||
const unsigned char *CCFSClass::get_file(const char *fname, unsigned int *length)
|
||||
const unsigned char *CCFSClass::get_file(const char *fname,
|
||||
unsigned int *length, bool err_on_not_found)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; store[i].fname != NULL; i++)
|
||||
@ -89,6 +92,8 @@ const unsigned char *CCFSClass::get_file(const char *fname, unsigned int *length
|
||||
return store[i].data;
|
||||
}
|
||||
}
|
||||
if (err_on_not_found)
|
||||
cerr << "Error loading file \\"" << fname << '"' << endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -100,7 +105,8 @@ CCFSClass %s;
|
||||
class CCFSClass
|
||||
{
|
||||
public:
|
||||
const unsigned char *get_file(const char *fname, unsigned int *length);
|
||||
const unsigned char *get_file(const char *fname,
|
||||
unsigned int *length = NULL, bool err_on_not_found = true);
|
||||
};
|
||||
|
||||
extern CCFSClass %s;
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include GL_INCLUDE_FILE
|
||||
@ -42,6 +41,12 @@ static const struct
|
||||
{{-0.5, -0.5, 0.0}, {0.0, 0.0}},
|
||||
{{0.5, -0.5, 0.0}, {1.0, 0.0}}
|
||||
};
|
||||
static const float quad_attributes[][3] = {
|
||||
{0.5, 0.5, 0.0},
|
||||
{-0.5, 0.5, 0.0},
|
||||
{-0.5, -0.5, 0.0},
|
||||
{0.5, -0.5, 0.0}
|
||||
};
|
||||
|
||||
static bool load_file(const char *fname, WFObj::Buffer & buff)
|
||||
{
|
||||
@ -87,91 +92,37 @@ bool Client::initgl()
|
||||
return false;
|
||||
}
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
GLProgram::AttributeBinding obj_attrib_bindings[] = {
|
||||
{0, "pos"},
|
||||
{1, "normal"}
|
||||
};
|
||||
GLProgram::AttributeBinding sky_attrib_bindings[] = {
|
||||
{0, "pos"},
|
||||
{1, "color"}
|
||||
};
|
||||
GLProgram::AttributeBinding lava_attrib_bindings[] = {
|
||||
{0, "pos"},
|
||||
{1, "tex_coord"}
|
||||
};
|
||||
const char *obj_uniforms[] = {
|
||||
"ambient",
|
||||
"diffuse",
|
||||
"specular",
|
||||
"shininess",
|
||||
"projection",
|
||||
"modelview"
|
||||
};
|
||||
const char *overlay_uniforms[] = {
|
||||
"projection",
|
||||
"modelview",
|
||||
"color"
|
||||
};
|
||||
const char *sky_uniforms[] = {
|
||||
"projection",
|
||||
"modelview"
|
||||
};
|
||||
const char *lava_uniforms[] = {
|
||||
"projection",
|
||||
"modelview",
|
||||
"tex",
|
||||
"shift"
|
||||
};
|
||||
const char *obj_v_source =
|
||||
(const char *) CFS.get_file("shaders/obj.v.glsl", NULL);
|
||||
const char *obj_f_source =
|
||||
(const char *) CFS.get_file("shaders/obj.f.glsl", NULL);
|
||||
const char *overlay_f_source =
|
||||
(const char *) CFS.get_file("shaders/overlay.f.glsl", NULL);
|
||||
const char *sky_v_source =
|
||||
(const char *) CFS.get_file("shaders/sky.v.glsl", NULL);
|
||||
const char *sky_f_source =
|
||||
(const char *) CFS.get_file("shaders/sky.f.glsl", NULL);
|
||||
const char *lava_v_source =
|
||||
(const char *) CFS.get_file("shaders/lava.v.glsl", NULL);
|
||||
const char *lava_f_source =
|
||||
(const char *) CFS.get_file("shaders/lava.f.glsl", NULL);
|
||||
if (obj_v_source == NULL || obj_f_source == NULL ||
|
||||
overlay_f_source == NULL ||
|
||||
sky_v_source == NULL || sky_f_source == NULL ||
|
||||
lava_v_source == NULL || lava_f_source == NULL)
|
||||
{
|
||||
cerr << "Error loading shader sources" << endl;
|
||||
if (!m_obj_program.create(
|
||||
CFS.get_file("shaders/obj.v.glsl"),
|
||||
CFS.get_file("shaders/obj.f.glsl"),
|
||||
"pos", 0, "normal", 1, NULL,
|
||||
"ambient", "diffuse", "specular", "shininess",
|
||||
"projection", "modelview", NULL))
|
||||
return false;
|
||||
}
|
||||
if (!m_obj_program.create(obj_v_source, obj_f_source,
|
||||
obj_attrib_bindings, LEN(obj_attrib_bindings),
|
||||
obj_uniforms, LEN(obj_uniforms)))
|
||||
{
|
||||
cerr << "Error creating obj program" << endl;
|
||||
if (!m_overlay_program.create(
|
||||
CFS.get_file("shaders/obj.v.glsl"),
|
||||
CFS.get_file("shaders/overlay.f.glsl"),
|
||||
"pos", 0, "normal", 1, NULL,
|
||||
"projection", "modelview", "color", NULL))
|
||||
return false;
|
||||
}
|
||||
if (!m_overlay_program.create(obj_v_source, overlay_f_source,
|
||||
obj_attrib_bindings, LEN(obj_attrib_bindings),
|
||||
overlay_uniforms, LEN(overlay_uniforms)))
|
||||
{
|
||||
cerr << "Error creating overlay program" << endl;
|
||||
if (!m_overlay_hover_program.create(
|
||||
CFS.get_file("shaders/obj.v.glsl"),
|
||||
CFS.get_file("shaders/overlay_hover.f.glsl"),
|
||||
"pos", 0, "normal", 1, NULL,
|
||||
"projection", "modelview", NULL))
|
||||
return false;
|
||||
}
|
||||
if (!m_sky_program.create(sky_v_source, sky_f_source,
|
||||
sky_attrib_bindings, LEN(sky_attrib_bindings),
|
||||
sky_uniforms, LEN(sky_uniforms)))
|
||||
{
|
||||
cerr << "Error creating sky program" << endl;
|
||||
if (!m_sky_program.create(
|
||||
CFS.get_file("shaders/sky.v.glsl"),
|
||||
CFS.get_file("shaders/sky.f.glsl"),
|
||||
"pos", 0, "color", 1, NULL,
|
||||
"projection", "modelview", NULL))
|
||||
return false;
|
||||
}
|
||||
if (!m_lava_program.create(lava_v_source, lava_f_source,
|
||||
lava_attrib_bindings, LEN(lava_attrib_bindings),
|
||||
lava_uniforms, LEN(lava_uniforms)))
|
||||
{
|
||||
cerr << "Error creating lava program" << endl;
|
||||
if (!m_lava_program.create(
|
||||
CFS.get_file("shaders/lava.v.glsl"),
|
||||
CFS.get_file("shaders/lava.f.glsl"),
|
||||
"pos", 0, "tex_coord", 1, NULL,
|
||||
"projection", "modelview", "tex", "shift", NULL))
|
||||
return false;
|
||||
}
|
||||
if (!m_tank_obj.load("models/tank.obj", load_file))
|
||||
{
|
||||
cerr << "Error loading tank model" << endl;
|
||||
@ -197,10 +148,16 @@ bool Client::initgl()
|
||||
if (!m_tex_quad_attributes.create(GL_ARRAY_BUFFER, GL_STATIC_DRAW,
|
||||
tex_quad_attributes, sizeof(tex_quad_attributes)))
|
||||
{
|
||||
cerr << "Error creating tex quad attribute buffer" << endl;
|
||||
cerr << "Error creating tex quad attributes buffer" << endl;
|
||||
return false;
|
||||
}
|
||||
vector<GLfloat> sky_attributes((NUM_SKY_STEPS + 1) * 2 * (3 * 3));
|
||||
if (!m_quad_attributes.create(GL_ARRAY_BUFFER, GL_STATIC_DRAW,
|
||||
quad_attributes, sizeof(quad_attributes)))
|
||||
{
|
||||
cerr << "Error creating quad attributes buffer" << endl;
|
||||
return false;
|
||||
}
|
||||
vector<GLfloat> sky_attributes((NUM_SKY_STEPS + 1) * 2 * (3 + 3));
|
||||
for (int i = 0, idx = 0; i <= NUM_SKY_STEPS; i++)
|
||||
{
|
||||
GLfloat x = SKY_DIST * sin(M_PI_4 + i * M_PI_2 / NUM_SKY_STEPS);
|
||||
@ -258,22 +215,22 @@ void Client::redraw()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
double dir_x = cos((*m_players)[current_player].direction);
|
||||
double dir_y = sin((*m_players)[current_player].direction);
|
||||
double dir_x = cos(m_players[current_player]->direction);
|
||||
double dir_y = sin(m_players[current_player]->direction);
|
||||
m_modelview.load_identity();
|
||||
m_modelview.look_at(
|
||||
(*m_players)[current_player].x - dir_x * 25, (*m_players)[current_player].y - dir_y * 25, 30,
|
||||
(*m_players)[current_player].x, (*m_players)[current_player].y, 20,
|
||||
m_players[current_player]->x - dir_x * 25, m_players[current_player]->y - dir_y * 25, 30,
|
||||
m_players[current_player]->x, m_players[current_player]->y, 20,
|
||||
0, 0, 1);
|
||||
|
||||
// TODO: call draw_player() for each networked player
|
||||
for(std::map<sf::Uint8, Player>::iterator piter = m_players->begin(); piter != m_players->end(); piter++)
|
||||
{
|
||||
draw_player(piter->second);
|
||||
}
|
||||
|
||||
|
||||
draw_map();
|
||||
for(std::map<sf::Uint8, refptr<Player> >::iterator piter = m_players.begin(); piter != m_players.end(); piter++)
|
||||
{
|
||||
draw_player(piter->second);
|
||||
}
|
||||
|
||||
|
||||
draw_map();
|
||||
draw_sky();
|
||||
draw_lava();
|
||||
|
||||
@ -282,12 +239,12 @@ void Client::redraw()
|
||||
m_window->display();
|
||||
}
|
||||
|
||||
void Client::draw_player(Player player)
|
||||
void Client::draw_player(refptr<Player> player)
|
||||
{
|
||||
m_obj_program.use();
|
||||
m_modelview.push();
|
||||
m_modelview.translate(player.x, player.y, 4);
|
||||
m_modelview.rotate(player.direction * 180.0 / M_PI, 0, 0, 1);
|
||||
m_modelview.translate(player->x, player->y, 4);
|
||||
m_modelview.rotate(player->direction * 180.0 / M_PI, 0, 0, 1);
|
||||
m_modelview.scale(2, 2, 2);
|
||||
m_tank_obj.bindBuffers();
|
||||
glEnableVertexAttribArray(0);
|
||||
@ -391,6 +348,7 @@ void Client::draw_map()
|
||||
|
||||
void Client::draw_overlay()
|
||||
{
|
||||
/* draw overlay map */
|
||||
int overlay_size = (int)(m_width * 0.15);
|
||||
glViewport(m_width - overlay_size - 50, m_height - overlay_size - 50,
|
||||
overlay_size, overlay_size);
|
||||
@ -403,8 +361,8 @@ void Client::draw_overlay()
|
||||
proj.ortho(-span, span, -span, span, -1, 1);
|
||||
proj.to_uniform(m_overlay_program.uniform("projection"));
|
||||
GLMatrix modelview;
|
||||
modelview.rotate(90 - (*m_players)[current_player].direction * 180 / M_PI, 0, 0, 1);
|
||||
modelview.translate(-(*m_players)[current_player].x, -(*m_players)[current_player].y, 0);
|
||||
modelview.rotate(90 - m_players[current_player]->direction * 180 / M_PI, 0, 0, 1);
|
||||
modelview.translate(-m_players[current_player]->x, -m_players[current_player]->y, 0);
|
||||
m_overlay_hex_attributes.bind();
|
||||
m_overlay_hex_indices.bind();
|
||||
glEnableVertexAttribArray(0);
|
||||
@ -446,9 +404,48 @@ void Client::draw_overlay()
|
||||
glPointSize(3);
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
|
||||
/* draw hover bar */
|
||||
glViewport(m_width - 200, 100, 150, 25);
|
||||
m_overlay_hover_program.use();
|
||||
m_quad_attributes.bind();
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);
|
||||
GLMatrix::Identity.to_uniform(
|
||||
m_overlay_hover_program.uniform("projection"));
|
||||
modelview.load_identity();
|
||||
modelview.translate(m_players[current_player]->hover - 1, 0, 0);
|
||||
modelview.scale(m_players[current_player]->hover * 2, 2.0, 1.0);
|
||||
modelview.to_uniform(m_overlay_hover_program.uniform("modelview"));
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
|
||||
/* draw map border */
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
m_overlay_program.use();
|
||||
m_quad_attributes.bind();
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);
|
||||
GLMatrix::Identity.to_uniform(m_overlay_program.uniform("projection"));
|
||||
modelview.load_identity();
|
||||
modelview.ortho(0, m_width, 0, m_height, -1, 1);
|
||||
modelview.translate(m_width - overlay_size / 2 - 50,
|
||||
m_height - overlay_size / 2 - 50, 0);
|
||||
modelview.scale(overlay_size + 0.1, overlay_size + 0.1, 1);
|
||||
modelview.to_uniform(m_overlay_program.uniform("modelview"));
|
||||
glUniform4f(m_overlay_program.uniform("color"), 1, 1, 1, 1);
|
||||
glDrawArrays(GL_LINE_LOOP, 0, 4);
|
||||
|
||||
/* draw hover bar border */
|
||||
modelview.load_identity();
|
||||
modelview.ortho(0, m_width, 0, m_height, -1, 1);
|
||||
modelview.translate(m_width - 200 + 150 / 2, 100 + 25 / 2, 0);
|
||||
modelview.scale(150.1, 25.1, 1);
|
||||
modelview.to_uniform(m_overlay_program.uniform("modelview"));
|
||||
glDrawArrays(GL_LINE_LOOP, 0, 4);
|
||||
|
||||
/* reset GL to normal state */
|
||||
glDisableVertexAttribArray(0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
}
|
||||
|
||||
void Client::draw_sky()
|
||||
@ -457,8 +454,8 @@ void Client::draw_sky()
|
||||
m_sky_attributes.bind();
|
||||
m_projection.to_uniform(m_sky_program.uniform("projection"));
|
||||
m_modelview.push();
|
||||
m_modelview.translate((*m_players)[current_player].x, (*m_players)[current_player].y, 0);
|
||||
m_modelview.rotate((*m_players)[current_player].direction * 180.0 / M_PI, 0, 0, 1);
|
||||
m_modelview.translate(m_players[current_player]->x, m_players[current_player]->y, 0);
|
||||
m_modelview.rotate(m_players[current_player]->direction * 180.0 / M_PI, 0, 0, 1);
|
||||
m_modelview.to_uniform(m_sky_program.uniform("modelview"));
|
||||
m_modelview.pop();
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,
|
||||
|
@ -1,15 +1,15 @@
|
||||
#include <math.h>
|
||||
#include "Client.h"
|
||||
#include "Types.h"
|
||||
#include "Timer.h"
|
||||
|
||||
Client::Client()
|
||||
{
|
||||
m_net_client = new Network();
|
||||
m_net_client->Create(59243, "127.0.0.1"); // Just connect to local host for now - testing
|
||||
client_has_focus = true;
|
||||
m_players = new std::map<sf::Uint8, Player>;
|
||||
m_players->clear();
|
||||
current_player = 0;
|
||||
client_has_focus = true;
|
||||
m_players.clear();
|
||||
current_player = 0;
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
@ -20,13 +20,14 @@ Client::~Client()
|
||||
|
||||
void Client::run(bool fullscreen, int width, int height, std::string pname)
|
||||
{
|
||||
|
||||
current_player_name = pname;
|
||||
Timer client_timer;
|
||||
client_timer.Init();
|
||||
current_player_name = pname;
|
||||
if (!create_window(fullscreen, width, height))
|
||||
return;
|
||||
m_clock.restart();
|
||||
sf::Mouse::setPosition(sf::Vector2i(m_width / 2, m_height / 2), *m_window);
|
||||
|
||||
|
||||
double last_time = 0.0;
|
||||
while (m_window->isOpen())
|
||||
{
|
||||
@ -65,12 +66,17 @@ void Client::run(bool fullscreen, int width, int height, std::string pname)
|
||||
}
|
||||
}
|
||||
|
||||
// Time must be updated before any messages are sent
|
||||
// Especially guaranteed messages, since the time needs to be
|
||||
// non zero.
|
||||
client_timer.Update();
|
||||
|
||||
update(elapsed_time);
|
||||
if(m_players->size() > 0)
|
||||
{
|
||||
redraw();
|
||||
}
|
||||
last_time = current_time;
|
||||
if(m_players.size() > 0)
|
||||
{
|
||||
redraw();
|
||||
}
|
||||
last_time = current_time;
|
||||
|
||||
// temporary for now. otherwise this thread consumed way too processing
|
||||
sf::sleep(sf::seconds(0.005)); // 5 milli-seconds
|
||||
@ -79,7 +85,7 @@ void Client::run(bool fullscreen, int width, int height, std::string pname)
|
||||
|
||||
void Client::update(double elapsed_time)
|
||||
{
|
||||
static bool registered_player = false;
|
||||
static bool registered_player = false;
|
||||
sf::Packet client_packet;
|
||||
|
||||
|
||||
@ -88,127 +94,141 @@ void Client::update(double elapsed_time)
|
||||
// Handle all received data (only really want the latest)
|
||||
while(m_net_client->getData(client_packet))
|
||||
{
|
||||
sf::Uint8 packet_type;
|
||||
client_packet >> packet_type;
|
||||
switch(packet_type)
|
||||
{
|
||||
case PLAYER_CONNECT:
|
||||
{
|
||||
Player p;
|
||||
sf::Uint8 pindex;
|
||||
std::string name = "";
|
||||
client_packet >> pindex;
|
||||
client_packet >> name;
|
||||
if(name == current_player_name)
|
||||
{
|
||||
current_player = pindex;
|
||||
}
|
||||
p.name = name;
|
||||
(*m_players)[pindex] = p;
|
||||
break;
|
||||
}
|
||||
case PLAYER_UPDATE:
|
||||
{
|
||||
sf::Uint8 player_index;
|
||||
// Update player position as calculated from the server.
|
||||
client_packet >> player_index;
|
||||
if(m_players->end() != m_players->find(player_index))
|
||||
{
|
||||
client_packet >> (*m_players)[player_index].direction;
|
||||
client_packet >> (*m_players)[player_index].x;
|
||||
client_packet >> (*m_players)[player_index].y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PLAYER_DISCONNECT:
|
||||
{
|
||||
// This will remove the player once the disconnect algorithm is implemented
|
||||
break;
|
||||
}
|
||||
case PLAYER_DEATH:
|
||||
{
|
||||
// This will set a death flag in the player struct.
|
||||
break;
|
||||
}
|
||||
default :
|
||||
{
|
||||
// Eat the packet
|
||||
break;
|
||||
}
|
||||
}
|
||||
sf::Uint8 packet_type;
|
||||
client_packet >> packet_type;
|
||||
switch(packet_type)
|
||||
{
|
||||
case PLAYER_CONNECT:
|
||||
{
|
||||
sf::Uint8 pindex;
|
||||
std::string name = "";
|
||||
client_packet >> pindex;
|
||||
client_packet >> name;
|
||||
// Should be a much better way of doing this.
|
||||
// Perhaps generate a random number
|
||||
if(name == current_player_name)
|
||||
{
|
||||
current_player = pindex;
|
||||
}
|
||||
|
||||
// Create a new player if one does not exist.
|
||||
if(m_players.end() == m_players.find(pindex))
|
||||
{
|
||||
refptr<Player> p = new Player();
|
||||
p->name = name;
|
||||
client_packet >> p->direction;
|
||||
client_packet >> p->x;
|
||||
client_packet >> p->y;
|
||||
m_players[pindex] = p;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PLAYER_UPDATE:
|
||||
{
|
||||
sf::Uint8 player_index;
|
||||
// Update player position as calculated from the server.
|
||||
client_packet >> player_index;
|
||||
if(m_players.end() != m_players.find(player_index))
|
||||
{
|
||||
client_packet >> m_players[player_index]->direction;
|
||||
client_packet >> m_players[player_index]->x;
|
||||
client_packet >> m_players[player_index]->y;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PLAYER_DISCONNECT:
|
||||
{
|
||||
// This will remove the player once the disconnect algorithm is implemented
|
||||
break;
|
||||
}
|
||||
case PLAYER_DEATH:
|
||||
{
|
||||
// This will set a death flag in the player struct.
|
||||
break;
|
||||
}
|
||||
default :
|
||||
{
|
||||
// Eat the packet
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For now, we are going to do a very crude shove data into
|
||||
// packet from keyboard and mouse events.
|
||||
// TODO: Clean this up and make it more robust
|
||||
if(m_players->size() > 0)
|
||||
{
|
||||
sf::Uint8 w_pressed = KEY_NOT_PRESSED;
|
||||
sf::Uint8 a_pressed = KEY_NOT_PRESSED;
|
||||
sf::Uint8 s_pressed = KEY_NOT_PRESSED;
|
||||
sf::Uint8 d_pressed = KEY_NOT_PRESSED;
|
||||
sf::Int32 rel_mouse_movement = 0;
|
||||
if(m_players.size() > 0)
|
||||
{
|
||||
sf::Uint8 w_pressed = KEY_NOT_PRESSED;
|
||||
sf::Uint8 a_pressed = KEY_NOT_PRESSED;
|
||||
sf::Uint8 s_pressed = KEY_NOT_PRESSED;
|
||||
sf::Uint8 d_pressed = KEY_NOT_PRESSED;
|
||||
sf::Int32 rel_mouse_movement = 0;
|
||||
|
||||
// This is a fix so that the mouse will not move outside the window and
|
||||
// cause the user to click on another program.
|
||||
// Note: Does not work well with fast movement.
|
||||
if(client_has_focus)
|
||||
{
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
|
||||
{
|
||||
a_pressed = KEY_PRESSED;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
|
||||
{
|
||||
d_pressed = KEY_PRESSED;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
|
||||
{
|
||||
w_pressed = KEY_PRESSED;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
|
||||
{
|
||||
s_pressed = KEY_PRESSED;
|
||||
}
|
||||
rel_mouse_movement = sf::Mouse::getPosition(*m_window).x - m_width / 2;
|
||||
sf::Mouse::setPosition(sf::Vector2i(m_width / 2, m_height / 2), *m_window);
|
||||
}
|
||||
// This is a fix so that the mouse will not move outside the window and
|
||||
// cause the user to click on another program.
|
||||
// Note: Does not work well with fast movement.
|
||||
if(client_has_focus)
|
||||
{
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
|
||||
{
|
||||
a_pressed = KEY_PRESSED;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
|
||||
{
|
||||
d_pressed = KEY_PRESSED;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
|
||||
{
|
||||
w_pressed = KEY_PRESSED;
|
||||
}
|
||||
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
|
||||
{
|
||||
s_pressed = KEY_PRESSED;
|
||||
}
|
||||
rel_mouse_movement = sf::Mouse::getPosition(*m_window).x - m_width / 2;
|
||||
sf::Mouse::setPosition(sf::Vector2i(m_width / 2, m_height / 2), *m_window);
|
||||
}
|
||||
|
||||
// Send an update to the server if something has changed
|
||||
if(((*m_players)[current_player].w_pressed != w_pressed) ||
|
||||
((*m_players)[current_player].a_pressed != a_pressed) ||
|
||||
((*m_players)[current_player].s_pressed != s_pressed) ||
|
||||
((*m_players)[current_player].d_pressed != d_pressed) ||
|
||||
((*m_players)[current_player].rel_mouse_movement != rel_mouse_movement))
|
||||
{
|
||||
sf::Uint8 packet_type = PLAYER_UPDATE;
|
||||
client_packet.clear();
|
||||
client_packet << packet_type;
|
||||
client_packet << current_player;
|
||||
client_packet << w_pressed;
|
||||
client_packet << a_pressed;
|
||||
client_packet << s_pressed;
|
||||
client_packet << d_pressed;
|
||||
client_packet << rel_mouse_movement;
|
||||
// Send an update to the server if something has changed
|
||||
if((m_players[current_player]->w_pressed != w_pressed) ||
|
||||
(m_players[current_player]->a_pressed != a_pressed) ||
|
||||
(m_players[current_player]->s_pressed != s_pressed) ||
|
||||
(m_players[current_player]->d_pressed != d_pressed) ||
|
||||
(m_players[current_player]->rel_mouse_movement != rel_mouse_movement))
|
||||
{
|
||||
sf::Uint8 packet_type = PLAYER_UPDATE;
|
||||
client_packet.clear();
|
||||
client_packet << packet_type;
|
||||
client_packet << current_player;
|
||||
client_packet << w_pressed;
|
||||
client_packet << a_pressed;
|
||||
client_packet << s_pressed;
|
||||
client_packet << d_pressed;
|
||||
client_packet << rel_mouse_movement;
|
||||
|
||||
m_net_client->sendData(client_packet);
|
||||
m_net_client->sendData(client_packet);
|
||||
|
||||
(*m_players)[current_player].w_pressed = w_pressed;
|
||||
(*m_players)[current_player].a_pressed = a_pressed;
|
||||
(*m_players)[current_player].s_pressed = s_pressed;
|
||||
(*m_players)[current_player].d_pressed = d_pressed;
|
||||
(*m_players)[current_player].rel_mouse_movement = rel_mouse_movement;
|
||||
}
|
||||
}
|
||||
else if(!registered_player)
|
||||
{
|
||||
sf::Uint8 packet_type = PLAYER_CONNECT;
|
||||
client_packet.clear();
|
||||
client_packet << packet_type;
|
||||
client_packet << current_player;
|
||||
client_packet << current_player_name;
|
||||
m_net_client->sendData(client_packet);
|
||||
registered_player = true;
|
||||
}
|
||||
m_players[current_player]->w_pressed = w_pressed;
|
||||
m_players[current_player]->a_pressed = a_pressed;
|
||||
m_players[current_player]->s_pressed = s_pressed;
|
||||
m_players[current_player]->d_pressed = d_pressed;
|
||||
m_players[current_player]->rel_mouse_movement = rel_mouse_movement;
|
||||
}
|
||||
}
|
||||
else if(!registered_player)
|
||||
{
|
||||
sf::Uint8 packet_type = PLAYER_CONNECT;
|
||||
client_packet.clear();
|
||||
client_packet << packet_type;
|
||||
client_packet << current_player;
|
||||
client_packet << current_player_name;
|
||||
m_net_client->sendData(client_packet, true);
|
||||
registered_player = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
m_net_client->Transmit();
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#ifndef CLIENT_H
|
||||
#define CLIENT_H
|
||||
|
||||
@ -25,7 +24,7 @@ class Client
|
||||
void resize_window(int width, int height);
|
||||
void update(double elapsed_time);
|
||||
void redraw();
|
||||
void draw_player(Player player);
|
||||
void draw_player(refptr<Player> player);
|
||||
void draw_map();
|
||||
void draw_overlay();
|
||||
void draw_sky();
|
||||
@ -34,13 +33,14 @@ class Client
|
||||
refptr<sf::Window> m_window;
|
||||
sf::Clock m_clock;
|
||||
Map m_map;
|
||||
sf::Uint8 current_player;
|
||||
std::string current_player_name;
|
||||
refptr< std::map<sf::Uint8, Player> > m_players;
|
||||
sf::Uint8 current_player;
|
||||
std::string current_player_name;
|
||||
std::map<sf::Uint8, refptr<Player> > m_players;
|
||||
int m_width;
|
||||
int m_height;
|
||||
GLProgram m_obj_program;
|
||||
GLProgram m_overlay_program;
|
||||
GLProgram m_overlay_hover_program;
|
||||
GLProgram m_sky_program;
|
||||
GLProgram m_lava_program;
|
||||
WFObj m_tank_obj;
|
||||
@ -51,6 +51,7 @@ class Client
|
||||
GLBuffer m_overlay_hex_indices;
|
||||
GLBuffer m_sky_attributes;
|
||||
GLBuffer m_tex_quad_attributes;
|
||||
GLBuffer m_quad_attributes;
|
||||
refptr<Network> m_net_client;
|
||||
bool client_has_focus;
|
||||
sf::Texture m_lava_texture;
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
#include "GLProgram.h"
|
||||
#include <stdint.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
@ -7,7 +8,6 @@ using namespace std;
|
||||
GLProgram::GLProgram()
|
||||
{
|
||||
m_id = 0;
|
||||
m_uniform_locations = NULL;
|
||||
}
|
||||
|
||||
GLProgram::~GLProgram()
|
||||
@ -16,29 +16,50 @@ GLProgram::~GLProgram()
|
||||
{
|
||||
glDeleteProgram(m_id);
|
||||
}
|
||||
if (m_uniform_locations != NULL)
|
||||
{
|
||||
delete[] m_uniform_locations;
|
||||
}
|
||||
}
|
||||
|
||||
bool GLProgram::create(const char *v_source, const char *f_source,
|
||||
GLProgram::AttributeBinding *bindings, int n_bindings,
|
||||
const char **uniforms, int n_uniforms)
|
||||
bool GLProgram::create(const char *v_source, const char *f_source, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, f_source);
|
||||
bool rv = createv(v_source, f_source, va);
|
||||
va_end(va);
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool GLProgram::create(const uint8_t *v_source, const uint8_t *f_source, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, f_source);
|
||||
bool rv = createv((const char *) v_source, (const char *) f_source, va);
|
||||
va_end(va);
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool GLProgram::createv(const char *v_source, const char *f_source, va_list va)
|
||||
{
|
||||
if (v_source == NULL || f_source == NULL)
|
||||
return false;
|
||||
if (!m_v_shader.create(GL_VERTEX_SHADER, v_source))
|
||||
return false;
|
||||
if (!m_f_shader.create(GL_FRAGMENT_SHADER, f_source))
|
||||
return false;
|
||||
m_id = glCreateProgram();
|
||||
if (m_id <= 0)
|
||||
{
|
||||
cerr << "Error allocating GL program object" << endl;
|
||||
return false;
|
||||
}
|
||||
glAttachShader(m_id, m_v_shader.get_id());
|
||||
glAttachShader(m_id, m_f_shader.get_id());
|
||||
|
||||
for (int i = 0; i < n_bindings; i++)
|
||||
for (;;)
|
||||
{
|
||||
glBindAttribLocation(m_id, bindings[i].index, bindings[i].name);
|
||||
const char *attribute_name = va_arg(va, const char *);
|
||||
if (attribute_name == NULL)
|
||||
break;
|
||||
GLuint attribute_index = va_arg(va, uint32_t);
|
||||
glBindAttribLocation(m_id, attribute_index, attribute_name);
|
||||
}
|
||||
|
||||
glLinkProgram(m_id);
|
||||
@ -59,14 +80,14 @@ bool GLProgram::create(const char *v_source, const char *f_source,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (n_uniforms > 0)
|
||||
for (;;)
|
||||
{
|
||||
m_uniform_locations = new GLint[n_uniforms];
|
||||
for (int i = 0; i < n_uniforms; i++)
|
||||
{
|
||||
m_uniform_locations[i] = glGetUniformLocation(m_id, uniforms[i]);
|
||||
m_uniform_location_names[uniforms[i]] = m_uniform_locations[i];
|
||||
}
|
||||
const char *uniform_name = va_arg(va, const char *);
|
||||
if (uniform_name == NULL)
|
||||
break;
|
||||
GLint loc = glGetUniformLocation(m_id, uniform_name);
|
||||
m_uniform_locations.push_back(loc);
|
||||
m_uniform_location_names[uniform_name] = loc;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -2,23 +2,20 @@
|
||||
#ifndef GLPROGRAM_H
|
||||
#define GLPROGRAM_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "GLShader.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class GLProgram
|
||||
{
|
||||
public:
|
||||
typedef struct
|
||||
{
|
||||
GLuint index;
|
||||
const char *name;
|
||||
} AttributeBinding;
|
||||
GLProgram();
|
||||
~GLProgram();
|
||||
bool create(const char *v_source, const char *f_source,
|
||||
AttributeBinding *bindings = NULL, int n_bindings = 0,
|
||||
const char **uniforms = NULL, int n_uniforms = 0);
|
||||
bool create(const char *v_source, const char *f_source, ...);
|
||||
bool create(const uint8_t *v_source, const uint8_t *f_source, ...);
|
||||
bool createv(const char *v_source, const char *f_source, va_list va);
|
||||
GLuint get_id() { return m_id; }
|
||||
GLint get_uniform_location(const char *name);
|
||||
void get_uniform_locations(const char **names, int num, GLint *locs);
|
||||
@ -29,7 +26,7 @@ class GLProgram
|
||||
GLuint m_id;
|
||||
GLShader m_v_shader;
|
||||
GLShader m_f_shader;
|
||||
GLint * m_uniform_locations;
|
||||
std::vector<GLint> m_uniform_locations;
|
||||
std::map<std::string, GLint> m_uniform_location_names;
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include "Client.h"
|
||||
@ -8,14 +7,14 @@ int main(int argc, char *argv[])
|
||||
bool fullscreen = false;
|
||||
int width = 1200;
|
||||
int height = 900;
|
||||
std::string player_name = "Player";
|
||||
std::string player_name = "Player";
|
||||
|
||||
struct option longopts[] = {
|
||||
{"fullscreen", no_argument, NULL, 'f'},
|
||||
{"height", required_argument, NULL, 'h'},
|
||||
{"width", required_argument, NULL, 'w'},
|
||||
{"name", required_argument, NULL, 'n'},
|
||||
{NULL, 0, NULL, 0}
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
for (;;)
|
||||
{
|
||||
@ -33,9 +32,9 @@ int main(int argc, char *argv[])
|
||||
case 'w':
|
||||
width = atoi(optarg);
|
||||
break;
|
||||
case 'n':
|
||||
player_name = std::string(optarg);
|
||||
break;
|
||||
case 'n':
|
||||
player_name = std::string(optarg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#include <math.h>
|
||||
#include "HexTile.h"
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#ifndef HEXTILE_H
|
||||
#define HEXTILE_H
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#include "Map.h"
|
||||
#include "HexTile.h"
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#ifndef MAP_H
|
||||
#define MAP_H
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#include "Player.h"
|
||||
#include <math.h>
|
||||
|
||||
@ -8,11 +7,11 @@ Player::Player()
|
||||
y = 0.0;
|
||||
direction = M_PI_2;
|
||||
hover = 1.0;
|
||||
name = "";
|
||||
w_pressed = KEY_NOT_PRESSED;
|
||||
a_pressed = KEY_NOT_PRESSED;
|
||||
s_pressed = KEY_NOT_PRESSED;
|
||||
d_pressed = KEY_NOT_PRESSED;
|
||||
rel_mouse_movement = 0;
|
||||
updated = false;
|
||||
name = "";
|
||||
w_pressed = KEY_NOT_PRESSED;
|
||||
a_pressed = KEY_NOT_PRESSED;
|
||||
s_pressed = KEY_NOT_PRESSED;
|
||||
d_pressed = KEY_NOT_PRESSED;
|
||||
rel_mouse_movement = 0;
|
||||
updated = false;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#ifndef PLAYER_H
|
||||
#define PLAYER_H
|
||||
|
||||
@ -14,12 +13,12 @@ class Player
|
||||
double y;
|
||||
double direction; /* 0 = East, M_PI_2 = North, M_PI = West, ... */
|
||||
double hover;
|
||||
sf::Uint8 w_pressed;
|
||||
sf::Uint8 a_pressed;
|
||||
sf::Uint8 s_pressed;
|
||||
sf::Uint8 d_pressed;
|
||||
sf::Int32 rel_mouse_movement;
|
||||
bool updated;
|
||||
sf::Uint8 w_pressed;
|
||||
sf::Uint8 a_pressed;
|
||||
sf::Uint8 s_pressed;
|
||||
sf::Uint8 d_pressed;
|
||||
sf::Int32 rel_mouse_movement;
|
||||
bool updated;
|
||||
|
||||
Player();
|
||||
};
|
||||
|
@ -23,7 +23,6 @@ void Timer::Update(void)
|
||||
{
|
||||
// Record the time step
|
||||
stepTime = ((myClock.getElapsedTime().asSeconds() / 1000.0f) * gameSpeed);
|
||||
//stepTime = ((((sf::Window*)screen)->GetFrameTime() / 1000.0f) * gameSpeed);
|
||||
myClock.restart();
|
||||
|
||||
// Add the time to the total time
|
||||
|
@ -4,9 +4,9 @@
|
||||
#define KEY_PRESSED 0xA5u
|
||||
#define KEY_NOT_PRESSED 0x5Au
|
||||
|
||||
#define PLAYER_CONNECT 0x1Au
|
||||
#define PLAYER_DISCONNECT 0x2Bu
|
||||
#define PLAYER_DEATH 0x3Cu
|
||||
#define PLAYER_UPDATE 0x4Du
|
||||
#define PLAYER_CONNECT 0x1Au
|
||||
#define PLAYER_DISCONNECT 0x2Bu
|
||||
#define PLAYER_DEATH 0x3Cu
|
||||
#define PLAYER_UPDATE 0x4Du
|
||||
|
||||
#endif
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
#ifndef REFPTR_H
|
||||
#define REFPTR_H REFPTR_H
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
#include "Server.h"
|
||||
#include "Types.h"
|
||||
#include <math.h>
|
||||
#include "Timer.h"
|
||||
|
||||
Server::Server(sf::Uint16 port)
|
||||
{
|
||||
m_net_server = new Network();
|
||||
m_net_server->Create(port, sf::IpAddress::None);
|
||||
m_players = new std::map<sf::Uint8, Player>;
|
||||
m_players->clear();
|
||||
m_players.clear();
|
||||
}
|
||||
|
||||
Server::~Server()
|
||||
@ -20,10 +20,18 @@ void Server::run( void )
|
||||
double current_time;
|
||||
double elapsed_time;
|
||||
double last_time = 0.0;
|
||||
Timer server_timer;
|
||||
server_timer.Init();
|
||||
while(1)
|
||||
{
|
||||
current_time = m_clock.getElapsedTime().asSeconds();
|
||||
elapsed_time = current_time - last_time;
|
||||
|
||||
// Time must be updated before any messages are sent
|
||||
// Especially guaranteed messages, since the time needs to be
|
||||
// non zero.
|
||||
server_timer.Update();
|
||||
|
||||
update( elapsed_time );
|
||||
last_time = current_time;
|
||||
|
||||
@ -43,132 +51,138 @@ void Server::update( double elapsed_time )
|
||||
// Handle all received data (only really want the latest)
|
||||
while(m_net_server->getData(server_packet))
|
||||
{
|
||||
sf::Uint8 ptype;
|
||||
// Get packet type
|
||||
server_packet >> ptype;
|
||||
switch(ptype)
|
||||
{
|
||||
case PLAYER_CONNECT:
|
||||
{
|
||||
Player p;
|
||||
std::string pname;
|
||||
sf::Uint8 pindex;
|
||||
|
||||
server_packet >> pindex;
|
||||
server_packet >> pname;
|
||||
// When a player connects, we need to associate
|
||||
// that player with a new ID. find first unused id
|
||||
// player zero means a player does not exist.
|
||||
if(pindex == 0)
|
||||
{
|
||||
for(pindex = 1u; pindex < 255u; pindex++ )
|
||||
{
|
||||
if(m_players->end() == m_players->find(pindex))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
p.name = pname;
|
||||
(*m_players)[pindex] = p;
|
||||
|
||||
// Send a response to the newly added player
|
||||
server_packet.clear();
|
||||
server_packet << ptype;
|
||||
server_packet << pindex;
|
||||
server_packet << p.name;
|
||||
m_net_server->sendData(server_packet, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PLAYER_UPDATE:
|
||||
{
|
||||
// Need to determine the correct player id
|
||||
// then update the stored contents.
|
||||
sf::Uint8 pindex;
|
||||
server_packet >> pindex;
|
||||
if(m_players->end() != m_players->find(pindex))
|
||||
{
|
||||
server_packet >> (*m_players)[pindex].w_pressed;
|
||||
server_packet >> (*m_players)[pindex].a_pressed;
|
||||
server_packet >> (*m_players)[pindex].s_pressed;
|
||||
server_packet >> (*m_players)[pindex].d_pressed;
|
||||
server_packet >> (*m_players)[pindex].rel_mouse_movement;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PLAYER_DISCONNECT:
|
||||
{
|
||||
// This completely removes the player from the game
|
||||
// Deletes member from the player list
|
||||
break;
|
||||
}
|
||||
case PLAYER_DEATH:
|
||||
{
|
||||
// This just forces the player to dissapper from the
|
||||
// playing field.
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// Just eat the packet
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(std::map<sf::Uint8, Player>::iterator piter = m_players->begin(); piter != m_players->end(); piter++)
|
||||
{
|
||||
sf::Uint8 pindex = piter->first;
|
||||
double direction = (*m_players)[pindex].direction;
|
||||
direction -= M_PI * 0.5 * (*m_players)[pindex].rel_mouse_movement / 1000;
|
||||
if(direction != (*m_players)[pindex].direction)
|
||||
{
|
||||
(*m_players)[pindex].direction = direction;
|
||||
(*m_players)[pindex].updated = true;
|
||||
}
|
||||
if (KEY_PRESSED == (*m_players)[pindex].a_pressed)
|
||||
{
|
||||
direction = (*m_players)[pindex].direction + M_PI_2;
|
||||
(*m_players)[pindex].x += cos(direction) * move_speed * elapsed_time;
|
||||
(*m_players)[pindex].y += sin(direction) * move_speed * elapsed_time;
|
||||
(*m_players)[pindex].updated = true;
|
||||
}
|
||||
if (KEY_PRESSED == (*m_players)[pindex].d_pressed)
|
||||
{
|
||||
direction = (*m_players)[pindex].direction - M_PI_2;
|
||||
(*m_players)[pindex].x += cos(direction) * move_speed * elapsed_time;
|
||||
(*m_players)[pindex].y += sin(direction) * move_speed * elapsed_time;
|
||||
(*m_players)[pindex].updated = true;
|
||||
}
|
||||
if (KEY_PRESSED == (*m_players)[pindex].w_pressed)
|
||||
{
|
||||
direction = (*m_players)[pindex].direction;
|
||||
(*m_players)[pindex].x += cos(direction) * move_speed * elapsed_time;
|
||||
(*m_players)[pindex].y += sin(direction) * move_speed * elapsed_time;
|
||||
(*m_players)[pindex].updated = true;
|
||||
}
|
||||
if (KEY_PRESSED == (*m_players)[pindex].s_pressed)
|
||||
{
|
||||
direction = (*m_players)[pindex].direction + M_PI;
|
||||
(*m_players)[pindex].x += cos(direction) * move_speed * elapsed_time;
|
||||
(*m_players)[pindex].y += sin(direction) * move_speed * elapsed_time;
|
||||
(*m_players)[pindex].updated = true;
|
||||
}
|
||||
|
||||
server_packet.clear();
|
||||
sf::Uint8 ptype;
|
||||
// Get packet type
|
||||
server_packet >> ptype;
|
||||
switch(ptype)
|
||||
{
|
||||
case PLAYER_CONNECT:
|
||||
{
|
||||
refptr<Player> p = new Player();
|
||||
std::string pname;
|
||||
sf::Uint8 pindex;
|
||||
|
||||
// Send the player update if there were changes
|
||||
if((*m_players)[pindex].updated)
|
||||
{
|
||||
sf::Uint8 ptype = PLAYER_UPDATE;
|
||||
server_packet << ptype;
|
||||
server_packet << pindex;
|
||||
server_packet << (*m_players)[pindex].direction;
|
||||
server_packet << (*m_players)[pindex].x;
|
||||
server_packet << (*m_players)[pindex].y;
|
||||
m_net_server->sendData(server_packet);
|
||||
(*m_players)[pindex].updated = false;
|
||||
}
|
||||
}
|
||||
server_packet >> pindex;
|
||||
server_packet >> pname;
|
||||
// When a player connects, we need to associate
|
||||
// that player with a new ID. find first unused id
|
||||
// player zero means a player does not exist.
|
||||
if(pindex == 0)
|
||||
{
|
||||
for(pindex = 1u; pindex < 255u; pindex++ )
|
||||
{
|
||||
if(m_players.end() == m_players.find(pindex))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
p->name = pname;
|
||||
m_players[pindex] = p;
|
||||
|
||||
// Alert all connected clients of all the connected players.
|
||||
for(std::map<sf::Uint8, refptr<Player> >::iterator piter = m_players.begin(); piter != m_players.end(); piter++)
|
||||
{
|
||||
server_packet.clear();
|
||||
server_packet << ptype;
|
||||
server_packet << piter->first;
|
||||
server_packet << piter->second->name;
|
||||
// Send correct starting locations so that they match
|
||||
// the other players screens.
|
||||
server_packet << piter->second->direction;
|
||||
server_packet << piter->second->x;
|
||||
server_packet << piter->second->y;
|
||||
m_net_server->sendData(server_packet, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PLAYER_UPDATE:
|
||||
{
|
||||
// Need to determine the correct player id
|
||||
// then update the stored contents.
|
||||
sf::Uint8 pindex;
|
||||
server_packet >> pindex;
|
||||
if(m_players.end() != m_players.find(pindex))
|
||||
{
|
||||
server_packet >> m_players[pindex]->w_pressed;
|
||||
server_packet >> m_players[pindex]->a_pressed;
|
||||
server_packet >> m_players[pindex]->s_pressed;
|
||||
server_packet >> m_players[pindex]->d_pressed;
|
||||
server_packet >> m_players[pindex]->rel_mouse_movement;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PLAYER_DISCONNECT:
|
||||
{
|
||||
// This completely removes the player from the game
|
||||
// Deletes member from the player list
|
||||
break;
|
||||
}
|
||||
case PLAYER_DEATH:
|
||||
{
|
||||
// This just forces the player to dissapper from the
|
||||
// playing field.
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
// Just eat the packet
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(std::map<sf::Uint8, refptr<Player> >::iterator piter = m_players.begin(); piter != m_players.end(); piter++)
|
||||
{
|
||||
sf::Uint8 pindex = piter->first;
|
||||
if (KEY_PRESSED == m_players[pindex]->a_pressed)
|
||||
{
|
||||
double direction = m_players[pindex]->direction + M_PI_2;
|
||||
m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
|
||||
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
|
||||
m_players[pindex]->updated = true;
|
||||
}
|
||||
if (KEY_PRESSED == m_players[pindex]->d_pressed)
|
||||
{
|
||||
double direction = m_players[pindex]->direction - M_PI_2;
|
||||
m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
|
||||
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
|
||||
m_players[pindex]->updated = true;
|
||||
}
|
||||
if (KEY_PRESSED == m_players[pindex]->w_pressed)
|
||||
{
|
||||
double direction = m_players[pindex]->direction;
|
||||
m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
|
||||
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
|
||||
m_players[pindex]->updated = true;
|
||||
}
|
||||
if (KEY_PRESSED == m_players[pindex]->s_pressed)
|
||||
{
|
||||
double direction = m_players[pindex]->direction + M_PI;
|
||||
m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
|
||||
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
|
||||
m_players[pindex]->updated = true;
|
||||
}
|
||||
if(0 != m_players[pindex]->rel_mouse_movement)
|
||||
{
|
||||
m_players[pindex]->direction -= M_PI * 0.5 * m_players[pindex]->rel_mouse_movement / 1000;
|
||||
m_players[pindex]->updated = true;
|
||||
}
|
||||
|
||||
server_packet.clear();
|
||||
|
||||
// Send the player update if there were changes
|
||||
if(m_players[pindex]->updated)
|
||||
{
|
||||
sf::Uint8 ptype = PLAYER_UPDATE;
|
||||
server_packet << ptype;
|
||||
server_packet << pindex;
|
||||
server_packet << m_players[pindex]->direction;
|
||||
server_packet << m_players[pindex]->x;
|
||||
server_packet << m_players[pindex]->y;
|
||||
m_net_server->sendData(server_packet);
|
||||
m_players[pindex]->updated = false;
|
||||
}
|
||||
}
|
||||
m_net_server->Transmit();
|
||||
}
|
||||
|
@ -12,6 +12,6 @@ class Server{
|
||||
protected:
|
||||
void update(double elapsed_time);
|
||||
refptr<Network> m_net_server;
|
||||
refptr< std::map<sf::Uint8, Player> > m_players;
|
||||
std::map<sf::Uint8, refptr<Player> > m_players;
|
||||
sf::Clock m_clock;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user