ユーザ用ツール

サイト用ツール


youtube:sfml-base

SFMLの基礎

作成日: 2022-12-07 (水)

src/main.rs

// https://github.com/SFML/SFML-Game-Development-Book/tree/master/01_Intro

use sfml::{
    system::{
        Vector2f,
        Clock,
        Time
    },
    window::{
        Event,
        Style,
        Key
    },
    graphics::{
        RenderTarget,
        RenderWindow,
        Transformable,
        Color,
        Sprite,
        Texture,
    },
    SfBox
};

struct ResourceManager {
    player_texture: SfBox<Texture>
}

fn load_resources() -> ResourceManager {
    ResourceManager {
        player_texture: Texture::from_file("media/eagle.png").unwrap()
    }
}

struct MoveFlags {
    up: bool,
    down: bool,
    left: bool,
    right: bool
}

struct Game<'a> {
    window: RenderWindow,
    player: Sprite<'a>,
    player_speed: f32,
    move_flags: MoveFlags
}

impl<'a> Game<'a> {
    const FRAMES_PER_SECOND: f32 = 60.0; // Time::seconds(1.0 / 60.0) is not allowed for const

    pub fn new(resman: &'a ResourceManager) -> Game<'a> {
        let window = RenderWindow::new(
            (640, 480),
            "SFML Application",
            Style::CLOSE,
            &Default::default());

        Game {
            window,
            player: Sprite::with_texture(&resman.player_texture),
            player_speed: 100.0,
            move_flags: MoveFlags {
                up: false,
                down: false,
                left: false,
                right: false
            }
        }
    }

    pub fn run(&mut self) {
        let mut clock = Clock::start();
        let mut time_since_last_update = Time::ZERO;
        let time_per_frame = Time::seconds(1.0 / Self::FRAMES_PER_SECOND);

        while self.window.is_open() {
            self.process_events();

            time_since_last_update += clock.restart();
            while time_since_last_update > time_per_frame {
                time_since_last_update -= time_per_frame;
                self.process_events();
                self.update(&time_per_frame);
            }
            self.render();
        }
    }

    fn process_events(&mut self) {
        while let Some(event) = self.window.poll_event() {
            match event {
                Event::Closed => self.window.close(),
                Event::KeyPressed { code, .. } =>
                    if code == Key::Enter || code == Key::Escape {
                        self.window.close();
                    } else {
                        self.handle_player_input(code, true);
                    },
                Event::KeyReleased { code, .. } =>
                    self.handle_player_input(code, false),
                _ => {}
            }
        }
    }

    fn update(&mut self, delta_time: &Time) {
        let mut movement = Vector2f::new(0.0, 0.0);

        if self.move_flags.up {
            movement.y -= self.player_speed;
        }
        if self.move_flags.down {
            movement.y += self.player_speed;
        }
        if self.move_flags.left {
            movement.x -= self.player_speed;
        }
        if self.move_flags.right {
            movement.x += self.player_speed;
        }

        self.player.move_(movement * delta_time.as_seconds());
    }

    fn render(&mut self) {
        self.window.clear(Color::BLACK);
        self.window.draw(&self.player);
        self.window.display();
    }

    fn handle_player_input(&mut self, key: Key, pressed: bool) {
        match key {
            Key::W => self.move_flags.up = pressed,
            Key::S => self.move_flags.down = pressed,
            Key::A => self.move_flags.left = pressed,
            Key::D => self.move_flags.right = pressed,
            _ => {}
        }
    }
}

fn main() {
    let resman = load_resources();
    let mut game = Game::new(&resman);
    game.run();
}

Cargo.toml

[package]
name = "first-game"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
sfml = "0.19.0"

youtube/sfml-base.txt · 最終更新: 2024/03/03 07:15 by freemikan

特に明示されていない限り、本Wikiの内容は次のライセンスに従います: CC0 1.0 Universal
CC0 1.0 Universal Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki