1
Fork 0

Added drawing and undoing

This commit is contained in:
Joshua Moerman 2013-06-01 18:11:59 +02:00
parent 39b71cc5c5
commit ee571c1b56
3 changed files with 117 additions and 33 deletions

View file

@ -92,7 +92,7 @@ void GameRenderer::draw(Client const & client){
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
auto projectionMatrix = projection_matrices::orthographic(client.sim.bounds.xmin, client.sim.bounds.xmax, client.sim.bounds.ymax, client.sim.bounds.ymin, -100.0f, 100.0f);
auto projectionMatrix = projection_matrices::orthographic(0, client.window_width, client.window_height, 0, -100.0f, 100.0f);
auto modelViewProjectionMatrix = projectionMatrix;
std::swap(fbo1, fbo2);
@ -118,13 +118,13 @@ void GameRenderer::draw(Client const & client){
gl::draw_arrays(GL_POINTS, 0, client.beat.notes.size());
}
if(!client.lines.empty() || client.kick || client.snare){
if(!client.lines.empty() || client.kick || client.snare || client.drawing){
moggle::gl::blend_function(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
line_shader.s.use();
line_shader.s.uniform<matrix<float, 4>>("modelViewProjectionMatrix").set(modelViewProjectionMatrix);
lines.clear();
lines.reserve(client.lines.size() * 2 + 2 * 2);
lines.reserve(client.lines.size() * 2 + 2 * 2 + 2);
for(auto const & l : client.lines){
Color color = (l->line_kind == simulation::kFallThrough)
? Color{1.0f, l->color_intensity, std::sin(l->color_intensity)}
@ -143,6 +143,14 @@ void GameRenderer::draw(Client const & client){
lines.push_back({client.snare->starting_point, color});
lines.push_back({client.snare->end_point, color});
}
if(client.drawing){
const float color_intensity = 0.0f;
Color color = (client.current_kind == simulation::kFallThrough)
? Color{1.0f, color_intensity, std::sin(color_intensity)}
: Color{std::sin(color_intensity), 0.5f + 0.5f*color_intensity, 1.0f};
lines.push_back({to_FloatVec2(client.current_line.starting_point), color});
lines.push_back({to_FloatVec2(client.current_line.end_point), color});
}
if(debug_draw){
for(auto const & l : client.sim.lines){

View file

@ -38,7 +38,7 @@ namespace games {
}
} else if (command == "peeps"){
auto str = from_json<std::string>(object["data"]);
current_client->update_peeps(str);
current_client->set_text("Peeps: " + str);
}
} catch(std::exception& e){
throw websockets::runtime_error(e.what());
@ -115,6 +115,14 @@ namespace games {
lines_changed = true;
}
void Client::remove_line(std::shared_ptr<Instrument> const & instr){
auto& v = sim.lines;
v.erase(std::remove_if(v.begin(), v.end(), [instr](line_type const &l2){ return instr.get() == l2.information; }), v.end());
auto& w = lines;
w.erase(std::remove_if(w.begin(), w.end(), [instr](std::shared_ptr<Instrument> const & l){ return instr == l; }), w.end());
}
void Client::add_drum(){
kick = std::make_shared<Instrument>(math::Vec2{x1 - 25.0f, window_height - 100.0f}, math::Vec2{x1 + 25.0f, window_height - 50.0f}, 1, -1);
kick->sound.reset(new motor::al::Source(sounds[2]));
@ -188,19 +196,19 @@ namespace games {
info.gid = -1;
info.uid = -1;
context = libwebsocket_create_context(&info);
if(!context) throw std::runtime_error("context could not be created.");
// context = libwebsocket_create_context(&info);
// if(!context) throw std::runtime_error("context could not be created.");
// std::string address = "127.0.0.1";
std::string address = "vadovas-studios.com";
wsi = libwebsocket_client_connect(context, address.c_str(), 7681, false, "/", address.c_str(), "origin", "uberclient", -1);
if(!wsi) throw std::runtime_error("socket could not be created.");
// wsi = libwebsocket_client_connect(context, address.c_str(), 7681, false, "/", address.c_str(), "origin", "uberclient", -1);
// if(!wsi) throw std::runtime_error("socket could not be created.");
// motor
world.physics.set_gravity({0.0, 0.0, 0.0});
hud->camera.set_orthographic(-100, 100, -100, 100, 1, -1);
update_peeps("");
auto join_lbl = std::make_shared<motor::TextureLabel>("Join at: http://vadovas-studios.com/beats", motor::bundle.get_font_path() + "Arial Rounded Bold.ttf", 72);
set_text("draw mode: guitar");
auto join_lbl = std::make_shared<motor::TextureLabel>("-/+: speed, l: clear lines, b: clear balls, d: toggle drums, k: change drawmode", motor::bundle.get_font_path() + "Arial Rounded Bold.ttf", 72);
join_lbl->get_mesh()->material->diffuse_color = {1.0f, 1.0f, 1.0f, 1.0f};
join_lbl->set_position({-95.0, -95.0, 0.0});
join_lbl->set_scale(motor::scale(0.05));
@ -211,6 +219,26 @@ namespace games {
void Client::handle_input(float dt, Input input){
using motor::Position;
if(input.mouse.went_down[Input::Mouse::left]){
drawing = true;
current_line.starting_point = {input.mouse.position[0], input.mouse.position[1]};
current_line.end_point = {input.mouse.position[0], input.mouse.position[1]};
}
if(input.mouse.is_pressed[Input::Mouse::left]){
current_line.end_point = {input.mouse.position[0], input.mouse.position[1]};
current_line.line_kind = current_kind;
}
if(input.mouse.went_up[Input::Mouse::left]){
current_line.end_point = {input.mouse.position[0], input.mouse.position[1]};
add_line(current_line);
while(!undo_stack.empty()){
undo_stack.pop();
}
drawing = false;
}
if(input.keys_went_down[SDLK_b]){
sim.balls.clear();
}
@ -227,22 +255,55 @@ namespace games {
music_speed = 2.0;
}
if(input.keys_went_down[SDLK_z]){
if(input.keys_went_down[SDLK_r]){
sim_speed = 0.5;
}
if(input.keys_went_down[SDLK_x]){
if(input.keys_went_down[SDLK_t]){
sim_speed = 1.0;
}
if(input.keys_went_down[SDLK_c]){
if(input.keys_went_down[SDLK_y]){
sim_speed = 2.0;
}
if(input.keys_went_down[SDLK_z] && !lines.empty()){
std::shared_ptr<Instrument> line = lines.back();
remove_line(line);
undo_stack.push(line);
}
if(input.keys_went_down[SDLK_x] && !undo_stack.empty()){
std::shared_ptr<Instrument> line = undo_stack.top();
undo_stack.pop();
lines.push_back(line);
for(auto & l : line->calculate_lines()){
sim.lines.push_back(l);
}
}
const float step = 1.5;
if(input.keys_went_down[SDLK_MINUS]){
global_speed /= step;
}
if(input.keys_went_down[SDLK_EQUALS]){
global_speed *= step;
}
if(input.keys_went_down[SDLK_p]){
pause = !pause;
}
if(input.keys_went_down[SDLK_k]){
switch(current_kind){
case simulation::kFallThrough: current_kind = simulation::kOneWay; set_text("draw mode: bouncy"); break;
case simulation::kOneWay: current_kind = simulation::kFallThrough; set_text("draw mode: guitar"); break;
}
}
if(input.keys_went_down[SDLK_l]){
bool restore_drum = false;
if(kick || snare){
@ -295,10 +356,10 @@ namespace games {
Base::draw();
}
void Client::update_peeps(std::string peeps){
void Client::set_text(std::string peeps){
if(!peeps_lbl){
try {
peeps_lbl = std::make_shared<motor::TextureLabel>("Peeps:", motor::bundle.get_font_path() + "Arial Rounded Bold.ttf", 72);
peeps_lbl = std::make_shared<motor::TextureLabel>("", motor::bundle.get_font_path() + "Arial Rounded Bold.ttf", 72);
peeps_lbl->get_mesh()->material->diffuse_color = {1.0f, 1.0f, 1.0f, 1.0f};
peeps_lbl->set_position({-95.0, -90.0, 0.0});
peeps_lbl->set_scale(motor::scale(0.05));
@ -308,14 +369,12 @@ namespace games {
CERR << e.what() << std::endl;
}
}
if(peeps == ""){
peeps_lbl->set_text("No peeps online :(.");
} else {
peeps_lbl->set_text("Peeps: " + peeps);
}
peeps_lbl->set_text(peeps);
}
void Client::update(float const dt, Input input){
void Client::update(float dt, Input input){
dt *= global_speed;
// motor
Base::update(dt, input);
handle_input(dt, input);
@ -361,6 +420,7 @@ namespace games {
const float push_interval = 0.05;
push_time += dt;
if(context && wsi){
int ret = libwebsocket_service(context, 10);
if(ret < 0) {
CERR << "ERROR: libwebsocket returns < 0\n";
@ -370,8 +430,10 @@ namespace games {
push_time -= push_interval;
}
}
}
Client::~Client(){
if(context)
libwebsocket_context_destroy(context);
current_client = nullptr;
}

View file

@ -2,6 +2,7 @@
#include <vector>
#include <memory>
#include <stack>
#include <motor/sound/sound.hpp>
#include <motor/basic/texture_label.hpp>
@ -17,12 +18,17 @@
/*
Controls:
mouse: draw linez
1, .. 9, 0: change chord (will also be done automatically)
q, w, e: music speed (= generation of balls)
z, x, c: simulation speed
k: change line kind
a: toggle autopilot
d: toggle drum
p: pause
q, w, e: music speed (= generation of balls)
z, x, c: simulation speed
-, + (without shift): global speed
r: reload scales (aka chords)
s: reload shaders
b: clear balls
@ -32,6 +38,7 @@
namespace games {
struct Client : public Base {
static constexpr char bundle_name[] = "client";
float global_speed = 1.0;
// websocket part
libwebsocket_context * context{nullptr};
@ -54,6 +61,7 @@ namespace games {
void add_line(cheap_line_type const & line);
void remove_line(int ID);
void remove_line(std::shared_ptr<Instrument> const & instr);
void add_drum();
void remove_drum();
@ -62,6 +70,12 @@ namespace games {
float x2;
float x3;
// Input part
cheap_line_type current_line;
bool drawing = false;
simulation::LineKind current_kind = simulation::kFallThrough;
std::stack<std::shared_ptr<Instrument>> undo_stack;
// Sound part
const std::vector<std::string> scale_files{
::bundle.get_sound_path() + "pentatonic.txt", // 0 a
@ -94,13 +108,13 @@ namespace games {
};
float music_speed{1.0};
bool auto_pilot{false};
bool auto_pilot{true};
// Graphics
GameRenderer game_renderer;
std::shared_ptr<motor::TextureLabel> peeps_lbl;
void update_peeps(std::string peeps);
void set_text(std::string peeps);
// Base part
Client(int window_width, int window_height, std::shared_ptr<Base>& active_base);