Added drawing and undoing
This commit is contained in:
parent
39b71cc5c5
commit
ee571c1b56
3 changed files with 117 additions and 33 deletions
|
@ -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){
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Reference in a new issue