mod support; use cubik::glium::{glutin, Surface}; use cubik::draw::{ObjDrawInfo, EnvDrawInfo, basic_render, MAX_LIGHTS, Light}; use cubik::camera::perspective_matrix; use cubik::input::{InputListener, process_input_event, center_cursor}; use cubik::skybox::Skybox; use cubik::animation::ObjAnimation; use cubik::player::{Player, PlayerControlType}; use cubik::peer_player::PeerPlayer; use support::constants::APP_ID; use cubik::audio::{buffer_sound, get_sound_stream, SoundStream}; use cubik::container::RenderContainer; use std::collections::HashMap; use cubik::client::ClientContainer; use cubik::map::GameMap; use support::msg::AppMessage; const PORT: u16 = 27020; fn net_update(client_container: &mut ClientContainer, peer_map: &mut HashMap, player: &mut Player, sound_stream: &SoundStream, time_delta: f32) { let pids = client_container.pids(); peer_map.retain(|&k, _| pids.contains(&k)); client_container.update().unwrap(); for msg in client_container.get_msgs() { if let AppMessage::PlayerChange { msg, player_id } = msg { if client_container.player_id.unwrap_or(0) == player_id { player.update(0., None, Some(sound_stream), Some(msg)); } else { let peer_player = peer_map.entry(player_id) .or_insert(PeerPlayer::new()); peer_player.update(Some(msg), time_delta); } } } for peer_player in peer_map.values_mut() { peer_player.update(None, time_delta); } if let Some(out_msg) = player.update(time_delta, None, Some(sound_stream), None) { client_container.send(AppMessage::PlayerChange { player_id: 0, msg: out_msg }).unwrap(); } } fn main() { let event_loop = glutin::event_loop::EventLoop::new(); let mut ctr = RenderContainer::new(&event_loop, 1280, 720, "Example", false); let mut map_info: ObjDrawInfo = Default::default(); map_info.generate_matrix(); let sound_stream = get_sound_stream().unwrap(); let mut peer_map: HashMap = HashMap::new(); let mut client_container: ClientContainer = ClientContainer::new(format!("127.0.0.1:{}", PORT).as_str()).unwrap(); let mut player = Player::new([0.0, 1.5, 0.0], PlayerControlType::MultiplayerClient, [0.0, 0.275, 0.0], [0.44, 0.275, 0.08]); player.walking_sound = Some(buffer_sound("./audio/running.wav", APP_ID).unwrap()); let map = GameMap::load_map("models/map2", APP_ID, Some(&ctr.display), Some(&mut ctr.textures), false).unwrap(); let wolf_standing = cubik::wavefront::load_obj("models/wolf_standing.obj", APP_ID, Some(&ctr.display), Some(&mut ctr.textures), &[1., 1., 1.], None, None, None).unwrap(); let wolf_anim = ObjAnimation::load_wavefront("models/wolfrunning", APP_ID, &ctr.display, &mut ctr.textures, 0.041).unwrap(); let skybox = Skybox::new(&ctr.display, "skybox1", APP_ID, 512, 50.).unwrap(); let mut lights_arr: [Light; MAX_LIGHTS] = Default::default(); let mut light_iter = map.lights.values(); for i in 0..map.lights.len() { lights_arr[i] = *light_iter.next().unwrap(); } let mut displace = 0.0f32; let mut last_frame_time = std::time::Instant::now(); let mut input_enabled = true; event_loop.run(move |ev, _, control_flow| { let listeners: Vec<&mut dyn InputListener> = vec![&mut player]; *control_flow = glutin::event_loop::ControlFlow::Poll; match ev { glutin::event::Event::WindowEvent { event, .. } => match event { glutin::event::WindowEvent::CloseRequested => { *control_flow = glutin::event_loop::ControlFlow::Exit; return; }, glutin::event::WindowEvent::KeyboardInput { input, .. } => { if let Some(keycode) = input.virtual_keycode { match keycode { glutin::event::VirtualKeyCode::Escape => { *control_flow = glutin::event_loop::ControlFlow::Exit; return; }, glutin::event::VirtualKeyCode::T => { if input.state == glutin::event::ElementState::Released { input_enabled = !input_enabled; let gl_window = ctr.display.gl_window(); let window = gl_window.window(); window.set_cursor_visible(!input_enabled); } return; } _ => () }; } if !input_enabled { return; } process_input_event(event, listeners, &ctr.display); return; }, _ => { if !input_enabled { return; } process_input_event(event, listeners, &ctr.display); return; } }, glutin::event::Event::NewEvents(cause) => match cause { glutin::event::StartCause::ResumeTimeReached { .. } => (), glutin::event::StartCause::Init => { center_cursor(&ctr.display, false); }, glutin::event::StartCause::Poll => (), _ => return }, _ => return } let new_frame_time = std::time::Instant::now(); let time_delta = new_frame_time.duration_since(last_frame_time).as_secs_f32(); last_frame_time = new_frame_time; displace += time_delta; net_update(&mut client_container, &mut peer_map, &mut player, &sound_stream, time_delta); let mut target = ctr.display.draw(); let perspective_mat = perspective_matrix(&mut target); let env_info = EnvDrawInfo { perspective_mat: perspective_mat, view_mat: player.camera.view_matrix(), lights: lights_arr, light_count: map.lights.len(), params: &ctr.params, textures: &ctr.textures }; target.clear_color_and_depth((0.85, 0.85, 0.85, 1.0), 1.0); for (key, o) in &map.objects { let text_displace = if key.starts_with("water") { Some([displace.sin() * 0.005, displace.sin() * 0.005]) } else { None }; basic_render(&mut target, &env_info, &map_info, &o, &ctr.main_program, text_displace); } for peer_player in peer_map.values_mut() { peer_player.draw(&mut target, &env_info, &ctr.main_program, &wolf_anim, &wolf_standing, wolf_anim.get_keyframe_by_index(5)); } skybox.draw(&mut target, &env_info, &ctr.skybox_program); target.finish().unwrap(); }); }