• src/main.rs
+54 -10src/main.rs
1 1
use sdl2::pixels::Color;
2 2
use sdl2::event::Event;
3 3
use sdl2::keyboard::Keycode;
4 4
use sdl2::render::{WindowCanvas, Texture};
5 5
use sdl2::rect::{Point, Rect};
6 6
// "self" imports the "image" module itself as well as everything else we listed
7 7
use sdl2::image::{self, LoadTexture, InitFlag};
8 8
use std::time::Duration;
9 9

  10
const PLAYER_MOVEMENT_SPEED: i32 = 20;
  11

  12
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
  13
enum Direction {
  14
    Up,
  15
    Down,
  16
    Left,
  17
    Right,
  18
}
  19

10 20
#[derive(Debug)]
11 21
struct Player {
12 22
    position: Point,
13 23
    sprite: Rect,
14 24
    speed: i32,
  25
    direction: Direction,
15 26
}
16 27

17 28
fn render(
18 29
    canvas: &mut WindowCanvas,
19 30
    color: Color,
20 31
    texture: &Texture,
21 32
    player: &Player,
22 33
) -> Result<(), String> {
23 34
    canvas.set_draw_color(color);
24 35
    canvas.clear();
25 36

26 37
    let (width, height) = canvas.output_size()?;
27 38

28 39
    // Treat the center of the screen as the (0, 0) coordinate
29 40
    let screen_position = player.position + Point::new(width as i32 / 2, height as i32 / 2);
30 41
    let screen_rect = Rect::from_center(screen_position, player.sprite.width(), player.sprite.height());
31 42
    canvas.copy(texture, player.sprite, screen_rect)?;
32 43

33 44
    canvas.present();
34 45

35 46
    Ok(())
36 47
}
37 48

  49
// Update player a fixed amount based on their speed.
  50
// WARNING: Calling this function too often or at a variable speed will cause the player's speed
  51
// to be unpredictable!
  52
fn update_player(player: &mut Player) {
  53
    use self::Direction::*;
  54
    match player.direction {
  55
        Left => {
  56
            player.position = player.position.offset(-player.speed, 0);
  57
        },
  58
        Right => {
  59
            player.position = player.position.offset(player.speed, 0);
  60
        },
  61
        Up => {
  62
            player.position = player.position.offset(0, -player.speed);
  63
        },
  64
        Down => {
  65
            player.position = player.position.offset(0, player.speed);
  66
        },
  67
    }
  68
}
  69

38 70
fn main() -> Result<(), String> {
39 71
    let sdl_context = sdl2::init()?;
40 72
    let video_subsystem = sdl_context.video()?;
41 73
    // Leading "_" tells Rust that this is an unused variable that we don't care about. It has to
42 74
    // stay unused because if we don't have any variable at all then Rust will treat it as a
43 75
    // temporary value and drop it right away!
44 76
    let _image_context = image::init(InitFlag::PNG | InitFlag::JPG)?;
45 77

46 78
    let window = video_subsystem.window("game tutorial", 800, 600)
47 79
        .position_centered()
48 80
        .build()
49 81
        .expect("could not initialize video subsystem");
50 82

51 83
    let mut canvas = window.into_canvas().build()
52 84
        .expect("could not make a canvas");
53 85

54 86
    let texture_creator = canvas.texture_creator();
55 87
    let texture = texture_creator.load_texture("assets/bardo.png")?;
56 88

57 89
    let mut player = Player {
58 90
        position: Point::new(0, 0),
59 91
        sprite: Rect::new(0, 0, 26, 36),
60  
        speed: 5,
  92
        speed: 0,
  93
        direction: Direction::Right,
61 94
    };
62 95

63 96
    let mut event_pump = sdl_context.event_pump()?;
64 97
    let mut i = 0;
65 98
    'running: loop {
66 99
        // Handle events
67 100
        for event in event_pump.poll_iter() {
68 101
            match event {
69 102
                Event::Quit {..} |
70 103
                Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
71 104
                    break 'running;
72 105
                },
73  
                Event::KeyDown { keycode: Some(Keycode::Left), .. } => {
74  
                    player.position = player.position.offset(-player.speed, 0);
  106
                Event::KeyDown { keycode: Some(Keycode::Left), repeat: false, .. } => {
  107
                    player.speed = PLAYER_MOVEMENT_SPEED;
  108
                    player.direction = Direction::Left;
75 109
                },
76  
                Event::KeyDown { keycode: Some(Keycode::Right), .. } => {
77  
                    player.position = player.position.offset(player.speed, 0);
  110
                Event::KeyDown { keycode: Some(Keycode::Right), repeat: false, .. } => {
  111
                    player.speed = PLAYER_MOVEMENT_SPEED;
  112
                    player.direction = Direction::Right;
78 113
                },
79  
                Event::KeyDown { keycode: Some(Keycode::Up), .. } => {
80  
                    player.position = player.position.offset(0, -player.speed);
  114
                Event::KeyDown { keycode: Some(Keycode::Up), repeat: false, .. } => {
  115
                    player.speed = PLAYER_MOVEMENT_SPEED;
  116
                    player.direction = Direction::Up;
81 117
                },
82  
                Event::KeyDown { keycode: Some(Keycode::Down), .. } => {
83  
                    player.position = player.position.offset(0, player.speed);
  118
                Event::KeyDown { keycode: Some(Keycode::Down), repeat: false, .. } => {
  119
                    player.speed = PLAYER_MOVEMENT_SPEED;
  120
                    player.direction = Direction::Down;
  121
                },
  122
                Event::KeyUp { keycode: Some(Keycode::Left), repeat: false, .. } |
  123
                Event::KeyUp { keycode: Some(Keycode::Right), repeat: false, .. } |
  124
                Event::KeyUp { keycode: Some(Keycode::Up), repeat: false, .. } |
  125
                Event::KeyUp { keycode: Some(Keycode::Down), repeat: false, .. } => {
  126
                    player.speed = 0;
84 127
                },
85 128
                _ => {}
86 129
            }
87 130
        }
88 131

89 132
        // Update
90 133
        i = (i + 1) % 255;
  134
        update_player(&mut player);
91 135

92 136
        // Render
93 137
        render(&mut canvas, Color::RGB(i, 64, 255 - i), &texture, &player)?;
94 138

95 139
        // Time management!
96  
        ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
  140
        ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 20));
97 141
    }
98 142

99 143
    Ok(())
100 144
}
+54 -10src/main.rs
1
use sdl2::pixels::Color;
1
use sdl2::pixels::Color;
2
use sdl2::event::Event;
2
use sdl2::event::Event;
3
use sdl2::keyboard::Keycode;
3
use sdl2::keyboard::Keycode;
4
use sdl2::render::{WindowCanvas, Texture};
4
use sdl2::render::{WindowCanvas, Texture};
5
use sdl2::rect::{Point, Rect};
5
use sdl2::rect::{Point, Rect};
6
// "self" imports the "image" module itself as well as everything else we listed
6
// "self" imports the "image" module itself as well as everything else we listed
7
use sdl2::image::{self, LoadTexture, InitFlag};
7
use sdl2::image::{self, LoadTexture, InitFlag};
8
use std::time::Duration;
8
use std::time::Duration;
9

9

    10
const PLAYER_MOVEMENT_SPEED: i32 = 20;
    11

    12
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
    13
enum Direction {
    14
    Up,
    15
    Down,
    16
    Left,
    17
    Right,
    18
}
    19

10
#[derive(Debug)]
20
#[derive(Debug)]
11
struct Player {
21
struct Player {
12
    position: Point,
22
    position: Point,
13
    sprite: Rect,
23
    sprite: Rect,
14
    speed: i32,
24
    speed: i32,
    25
    direction: Direction,
15
}
26
}
16

27

17
fn render(
28
fn render(
18
    canvas: &mut WindowCanvas,
29
    canvas: &mut WindowCanvas,
19
    color: Color,
30
    color: Color,
20
    texture: &Texture,
31
    texture: &Texture,
21
    player: &Player,
32
    player: &Player,
22
) -> Result<(), String> {
33
) -> Result<(), String> {
23
    canvas.set_draw_color(color);
34
    canvas.set_draw_color(color);
24
    canvas.clear();
35
    canvas.clear();
25

36

26
    let (width, height) = canvas.output_size()?;
37
    let (width, height) = canvas.output_size()?;
27

38

28
    // Treat the center of the screen as the (0, 0) coordinate
39
    // Treat the center of the screen as the (0, 0) coordinate
29
    let screen_position = player.position + Point::new(width as i32 / 2, height as i32 / 2);
40
    let screen_position = player.position + Point::new(width as i32 / 2, height as i32 / 2);
30
    let screen_rect = Rect::from_center(screen_position, player.sprite.width(), player.sprite.height());
41
    let screen_rect = Rect::from_center(screen_position, player.sprite.width(), player.sprite.height());
31
    canvas.copy(texture, player.sprite, screen_rect)?;
42
    canvas.copy(texture, player.sprite, screen_rect)?;
32

43

33
    canvas.present();
44
    canvas.present();
34

45

35
    Ok(())
46
    Ok(())
36
}
47
}
37

48

    49
// Update player a fixed amount based on their speed.
    50
// WARNING: Calling this function too often or at a variable speed will cause the player's speed
    51
// to be unpredictable!
    52
fn update_player(player: &mut Player) {
    53
    use self::Direction::*;
    54
    match player.direction {
    55
        Left => {
    56
            player.position = player.position.offset(-player.speed, 0);
    57
        },
    58
        Right => {
    59
            player.position = player.position.offset(player.speed, 0);
    60
        },
    61
        Up => {
    62
            player.position = player.position.offset(0, -player.speed);
    63
        },
    64
        Down => {
    65
            player.position = player.position.offset(0, player.speed);
    66
        },
    67
    }
    68
}
    69

38
fn main() -> Result<(), String> {
70
fn main() -> Result<(), String> {
39
    let sdl_context = sdl2::init()?;
71
    let sdl_context = sdl2::init()?;
40
    let video_subsystem = sdl_context.video()?;
72
    let video_subsystem = sdl_context.video()?;
41
    // Leading "_" tells Rust that this is an unused variable that we don't care about. It has to
73
    // Leading "_" tells Rust that this is an unused variable that we don't care about. It has to
42
    // stay unused because if we don't have any variable at all then Rust will treat it as a
74
    // stay unused because if we don't have any variable at all then Rust will treat it as a
43
    // temporary value and drop it right away!
75
    // temporary value and drop it right away!
44
    let _image_context = image::init(InitFlag::PNG | InitFlag::JPG)?;
76
    let _image_context = image::init(InitFlag::PNG | InitFlag::JPG)?;
45

77

46
    let window = video_subsystem.window("game tutorial", 800, 600)
78
    let window = video_subsystem.window("game tutorial", 800, 600)
47
        .position_centered()
79
        .position_centered()
48
        .build()
80
        .build()
49
        .expect("could not initialize video subsystem");
81
        .expect("could not initialize video subsystem");
50

82

51
    let mut canvas = window.into_canvas().build()
83
    let mut canvas = window.into_canvas().build()
52
        .expect("could not make a canvas");
84
        .expect("could not make a canvas");
53

85

54
    let texture_creator = canvas.texture_creator();
86
    let texture_creator = canvas.texture_creator();
55
    let texture = texture_creator.load_texture("assets/bardo.png")?;
87
    let texture = texture_creator.load_texture("assets/bardo.png")?;
56

88

57
    let mut player = Player {
89
    let mut player = Player {
58
        position: Point::new(0, 0),
90
        position: Point::new(0, 0),
59
        sprite: Rect::new(0, 0, 26, 36),
91
        sprite: Rect::new(0, 0, 26, 36),
60
        speed: 5,
92
        speed: 0,
    93
        direction: Direction::Right,
61
    };
94
    };
62

95

63
    let mut event_pump = sdl_context.event_pump()?;
96
    let mut event_pump = sdl_context.event_pump()?;
64
    let mut i = 0;
97
    let mut i = 0;
65
    'running: loop {
98
    'running: loop {
66
        // Handle events
99
        // Handle events
67
        for event in event_pump.poll_iter() {
100
        for event in event_pump.poll_iter() {
68
            match event {
101
            match event {
69
                Event::Quit {..} |
102
                Event::Quit {..} |
70
                Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
103
                Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
71
                    break 'running;
104
                    break 'running;
72
                },
105
                },
73
                Event::KeyDown { keycode: Some(Keycode::Left), .. } => {
106
                Event::KeyDown { keycode: Some(Keycode::Left), repeat: false, .. } => {
74
                    player.position = player.position.offset(-player.speed, 0);
107
                    player.speed = PLAYER_MOVEMENT_SPEED;
    108
                    player.direction = Direction::Left;
75
                },
109
                },
76
                Event::KeyDown { keycode: Some(Keycode::Right), .. } => {
110
                Event::KeyDown { keycode: Some(Keycode::Right), repeat: false, .. } => {
77
                    player.position = player.position.offset(player.speed, 0);
111
                    player.speed = PLAYER_MOVEMENT_SPEED;
    112
                    player.direction = Direction::Right;
78
                },
113
                },
79
                Event::KeyDown { keycode: Some(Keycode::Up), .. } => {
114
                Event::KeyDown { keycode: Some(Keycode::Up), repeat: false, .. } => {
80
                    player.position = player.position.offset(0, -player.speed);
115
                    player.speed = PLAYER_MOVEMENT_SPEED;
    116
                    player.direction = Direction::Up;
81
                },
117
                },
82
                Event::KeyDown { keycode: Some(Keycode::Down), .. } => {
118
                Event::KeyDown { keycode: Some(Keycode::Down), repeat: false, .. } => {
83
                    player.position = player.position.offset(0, player.speed);
119
                    player.speed = PLAYER_MOVEMENT_SPEED;
    120
                    player.direction = Direction::Down;
    121
                },
    122
                Event::KeyUp { keycode: Some(Keycode::Left), repeat: false, .. } |
    123
                Event::KeyUp { keycode: Some(Keycode::Right), repeat: false, .. } |
    124
                Event::KeyUp { keycode: Some(Keycode::Up), repeat: false, .. } |
    125
                Event::KeyUp { keycode: Some(Keycode::Down), repeat: false, .. } => {
    126
                    player.speed = 0;
84
                },
127
                },
85
                _ => {}
128
                _ => {}
86
            }
129
            }
87
        }
130
        }
88

131

89
        // Update
132
        // Update
90
        i = (i + 1) % 255;
133
        i = (i + 1) % 255;
    134
        update_player(&mut player);
91

135

92
        // Render
136
        // Render
93
        render(&mut canvas, Color::RGB(i, 64, 255 - i), &texture, &player)?;
137
        render(&mut canvas, Color::RGB(i, 64, 255 - i), &texture, &player)?;
94

138

95
        // Time management!
139
        // Time management!
96
        ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
140
        ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 20));
97
    }
141
    }
98

142

99
    Ok(())
143
    Ok(())
100
}
144
}
/target
**/*.rs.bk
[package]
name = "game-tutorial"
version = "0.1.0"
authors = ["Sunjay Varma <[email protected]>"]
edition = "2018"

[dependencies]

[dependencies.sdl2]
version = "0.32.1"
default-features = false
features = ["image"]
use sdl2::pixels::Color;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::render::{WindowCanvas, Texture};
use sdl2::rect::{Point, Rect};
// "self" imports the "image" module itself as well as everything else we listed
use sdl2::image::{self, LoadTexture, InitFlag};
use std::time::Duration;

const PLAYER_MOVEMENT_SPEED: i32 = 20;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Direction {
    Up,
    Down,
    Left,
    Right,
}

#[derive(Debug)]
struct Player {
    position: Point,
    sprite: Rect,
    speed: i32,
    direction: Direction,
}

fn render(
    canvas: &mut WindowCanvas,
    color: Color,
    texture: &Texture,
    player: &Player,
) -> Result<(), String> {
    canvas.set_draw_color(color);
    canvas.clear();

    let (width, height) = canvas.output_size()?;

    // Treat the center of the screen as the (0, 0) coordinate
    let screen_position = player.position + Point::new(width as i32 / 2, height as i32 / 2);
    let screen_rect = Rect::from_center(screen_position, player.sprite.width(), player.sprite.height());
    canvas.copy(texture, player.sprite, screen_rect)?;

    canvas.present();

    Ok(())
}

// Update player a fixed amount based on their speed.
// WARNING: Calling this function too often or at a variable speed will cause the player's speed
// to be unpredictable!
fn update_player(player: &mut Player) {
    use self::Direction::*;
    match player.direction {
        Left => {
            player.position = player.position.offset(-player.speed, 0);
        },
        Right => {
            player.position = player.position.offset(player.speed, 0);
        },
        Up => {
            player.position = player.position.offset(0, -player.speed);
        },
        Down => {
            player.position = player.position.offset(0, player.speed);
        },
    }
}

fn main() -> Result<(), String> {
    let sdl_context = sdl2::init()?;
    let video_subsystem = sdl_context.video()?;
    // Leading "_" tells Rust that this is an unused variable that we don't care about. It has to
    // stay unused because if we don't have any variable at all then Rust will treat it as a
    // temporary value and drop it right away!
    let _image_context = image::init(InitFlag::PNG | InitFlag::JPG)?;

    let window = video_subsystem.window("game tutorial", 800, 600)
        .position_centered()
        .build()
        .expect("could not initialize video subsystem");

    let mut canvas = window.into_canvas().build()
        .expect("could not make a canvas");

    let texture_creator = canvas.texture_creator();
    let texture = texture_creator.load_texture("assets/bardo.png")?;

    let mut player = Player {
        position: Point::new(0, 0),
        sprite: Rect::new(0, 0, 26, 36),
        speed: 0,
        direction: Direction::Right,
    };

    let mut event_pump = sdl_context.event_pump()?;
    let mut i = 0;
    'running: loop {
        // Handle events
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit {..} |
                Event::KeyDown { keycode: Some(Keycode::Escape), .. } => {
                    break 'running;
                },
                Event::KeyDown { keycode: Some(Keycode::Left), repeat: false, .. } => {
                    player.speed = PLAYER_MOVEMENT_SPEED;
                    player.direction = Direction::Left;
                },
                Event::KeyDown { keycode: Some(Keycode::Right), repeat: false, .. } => {
                    player.speed = PLAYER_MOVEMENT_SPEED;
                    player.direction = Direction::Right;
                },
                Event::KeyDown { keycode: Some(Keycode::Up), repeat: false, .. } => {
                    player.speed = PLAYER_MOVEMENT_SPEED;
                    player.direction = Direction::Up;
                },
                Event::KeyDown { keycode: Some(Keycode::Down), repeat: false, .. } => {
                    player.speed = PLAYER_MOVEMENT_SPEED;
                    player.direction = Direction::Down;
                },
                Event::KeyUp { keycode: Some(Keycode::Left), repeat: false, .. } |
                Event::KeyUp { keycode: Some(Keycode::Right), repeat: false, .. } |
                Event::KeyUp { keycode: Some(Keycode::Up), repeat: false, .. } |
                Event::KeyUp { keycode: Some(Keycode::Down), repeat: false, .. } => {
                    player.speed = 0;
                },
                _ => {}
            }
        }

        // Update
        i = (i + 1) % 255;
        update_player(&mut player);

        // Render
        render(&mut canvas, Color::RGB(i, 64, 255 - i), &texture, &player)?;

        // Time management!
        ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 20));
    }

    Ok(())
}