//! TODO: Rewrite for new renderer. use amethyst; mod audio; mod bundle; mod pong; mod systems; use amethyst::{ audio::AudioBundle, core::{frame_limiter::FrameRateLimitStrategy, transform::TransformBundle}, ecs::prelude::{Component, DenseVecStorage}, input::InputBundle, prelude::*, renderer::{DisplayConfig, DrawFlat2D, Pipeline, RenderBundle, Stage}, ui::{DrawUi, UiBundle}, utils::application_root_dir, }; use crate::{audio::Music, bundle::PongBundle}; use amethyst_editor_sync::*; use serde::*; use std::time::Duration; use tap::*; const ARENA_HEIGHT: f32 = 100.0; const ARENA_WIDTH: f32 = 100.0; const PADDLE_HEIGHT: f32 = 16.0; const PADDLE_WIDTH: f32 = 4.0; const PADDLE_VELOCITY: f32 = 75.0; const BALL_VELOCITY_X: f32 = 75.0; const BALL_VELOCITY_Y: f32 = 50.0; const BALL_RADIUS: f32 = 2.0; const AUDIO_MUSIC: &'static [&'static str] = &[ "audio/Computer_Music_All-Stars_-_Wheres_My_Jetpack.ogg", "audio/Computer_Music_All-Stars_-_Albatross_v2.ogg", ]; const AUDIO_BOUNCE: &'static str = "audio/bounce.ogg"; const AUDIO_SCORE: &'static str = "audio/score.ogg"; fn main() -> amethyst::Result<()> { use crate::pong::Pong; amethyst::start_logger(Default::default()); let editor_sync_bundle = SyncEditorBundle::new() .tap(SyncEditorBundle::sync_default_types) .tap(|bundle| sync_components!(bundle, Ball, Paddle)) .tap(|bundle| sync_resources!(bundle, ScoreBoard)); // EditorLogger::new(&editor_sync_bundle).start(); let app_root = application_root_dir(); let display_config_path = format!("{}/examples/pong/resources/display.ron", app_root); let config = DisplayConfig::load(&display_config_path); let pipe = Pipeline::build().with_stage( Stage::with_backbuffer() .clear_target([0.0, 0.0, 0.0, 1.0], 1.0) .with_pass(DrawFlat2D::new()) .with_pass(DrawUi::new()), ); let key_bindings_path = { if cfg!(feature = "sdl_controller") { format!("{}/examples/pong/resources/input_controller.ron", app_root) } else { format!("{}/examples/pong/resources/input.ron", app_root) } }; let assets_dir = format!("{}/examples/assets/", app_root); let game_data = GameDataBuilder::default() .with_bundle( InputBundle::::new().with_bindings_from_file(&key_bindings_path)?, )? .with_bundle(PongBundle)? .with_bundle(RenderBundle::new(pipe, Some(config)).with_sprite_sheet_processor())? .with_bundle(TransformBundle::new().with_dep(&["ball_system", "paddle_system"]))? .with_bundle(AudioBundle::new(|music: &mut Music| music.music.next()))? .with_bundle(UiBundle::::new())? .with_bundle(editor_sync_bundle)?; let mut game = Application::build(assets_dir, Pong)? .with_frame_limit( FrameRateLimitStrategy::SleepAndYield(Duration::from_millis(2)), 144, ) .build(game_data)?; game.run(); Ok(()) } #[derive(Debug, Serialize, Deserialize)] pub struct Ball { pub velocity: [f32; 2], pub radius: f32, } impl Component for Ball { type Storage = DenseVecStorage; } #[derive(Debug, PartialEq, Eq, Deserialize, Serialize)] pub enum Side { Left, Right, } #[derive(Debug, Serialize, Deserialize)] pub struct Paddle { pub velocity: f32, pub side: Side, pub width: f32, pub height: f32, } impl Paddle { pub fn new(side: Side) -> Paddle { Paddle { velocity: 1.0, side: side, width: 1.0, height: 1.0, } } } impl Component for Paddle { type Storage = DenseVecStorage; } #[derive(Debug, Default, Deserialize, Serialize)] pub struct ScoreBoard { score_left: i32, score_right: i32, } impl ScoreBoard { pub fn new() -> ScoreBoard { ScoreBoard { score_left: 0, score_right: 0, } } }