Skip to content

adi_screen tutorial 6: User Input

Jeron Aldaron Lau edited this page May 18, 2017 · 1 revision

Tutorial #6: User Input

Everything we've made so far has been non-interactive. Let's make some interactive stuff!

Invent types

Let's invent a type called Player. Replace,

struct Context {
	window: Window,
	sprite: Sprite,
}

with,

struct Player {
	sprite: Sprite,
	pos: (f32, f32)
}

struct Context {
	window: Window,
	player: Player,
}

Replace,

fn redraw(context: &mut Context) {
	let disp2 = context.window.pulse_full_linear(2.0);

	Transform::create()
		.translate(0.0, 0.0, disp2)
		.perspective(&context.window, 90.0)
		.apply(&mut context.window, &context.sprite, 0);

	context.window.background(disp2, disp2, disp2);
}

with,

fn redraw(context: &mut Context) {
	let disp2 = context.window.pulse_full_linear(2.0);

	context.window.background(disp2, disp2, disp2);
}

Replace,

	let mut context = Context {
		sprite: sprite,
		window: window,
	};

with,

	let mut context = Context {
		player: Player {
			sprite: sprite,
			pos: (0.0, 0.0),
		},
		window: window,
	};

Add sprite update function

In Aldaron's Device Interface, custom types implement their own update function. Here's how you do that:

struct Player {
	sprite: Sprite,
	pos: (f32, f32)
}

impl Player {
	fn update(&mut self, window: &mut Window, input: Input) {
		match input {
			Input::KeyDown(Key::Up) => self.pos.1 -= 0.05,
			Input::KeyDown(Key::Down) => self.pos.1 += 0.05,
			Input::KeyDown(Key::Left) => self.pos.0 -= 0.05,
			Input::KeyDown(Key::Right) => self.pos.0 += 0.05,
			Input::Resize => {},
			_ => return,
		}
		Transform::create()
			.translate(self.pos.0, self.pos.1, 0.0)
			.perspective(window, 90.0)
			.apply(window, &self.sprite, 0);
	}
}

This is a common formula for update functions - 3 parameters: &mut self, &mut Window, and Input. The player will update it's position based on what key is pressed. return is a keyword that skips the rest of the function, so if no key is pressed then the transform isn't updated ( because it doesn't need to be updated if the player's not moving ). We have a little bit more to do. Replace,

	loop {
		match context.window.update() {
			Input::Back => break,
			Input::Redraw => redraw(&mut context),
			_ => {},
		}
	}

with,

	loop {
		let input = context.window.update();
		match input {
			Input::Back => break,
			Input::Redraw => redraw(&mut context),
			_ => {},
		}
		// Run the update functions
		context.player.update(&mut context.window, input);
	}

In case you didn't know // declares a comment - a note to the programmer that doesn't get compiled. Well, you can run it now.

Smoother controls

It's not very nice having to keep on pressing a key to move, so here's a held down solution.

Replace,

struct Player {
	sprite: Sprite,
	pos: (f32, f32)
}

with,

TODO