本文是对 使用 Rust 开发一个微型游戏【已完结】[1]的学习与记录.
cargo new flappy
在Cargo.toml的[dependencies]
下方增加:
bracket-lib = "~0.8.7"
main.rs中:
usebracket_lib::prelude::*;
structState{}
implGameStateforState{
fntick(&mutself,ctx:&mutBTerm){
ctx.cls();
ctx.print(1,1,"Hello,BracketTerminal!");
}
}
fnmain()->BError{
letcontext:BTerm=BTermBuilder::simple80x50()
.with_title("爽哥做游戏--FlappyDragon")
.build()?;
main_loop(context,State{})
}
cargo run后,可以看到
usebracket_lib::prelude::*;//游戏3种模式(菜单,游戏中,结束)
enumGameMode{
Menu,
Playing,
End,
}
structState{
mode:GameMode,
}
implState{
fnnew()->Self{
State{
mode:GameMode::Menu,
}
}
fnplay(&mutself,ctx:&mutBTerm){
//TODO
self.mode=GameMode::End;
}
fnrestart(&mutself){
self.mode=GameMode::Playing;
}
fnmain_menu(&mutself,ctx:&mutBTerm){
ctx.cls();
ctx.print_centered(5,"欢迎来到游戏~");
ctx.print_centered(8,"PressPkeytostartGame");
ctx.print_centered(9,"PressQtoquitGame");
ifletSome(key)=ctx.key{
matchkey{
VirtualKeyCode::P=>self.restart(),
VirtualKeyCode::Q=>ctx.quitting=true,
_=>{}
}
{}
}
}
fndead(&mutself,ctx:&mutBTerm){
ctx.cls();
ctx.print_centered(5,"你挂了..");
ctx.print_centered(8,"按P键再来一局");
ctx.print_centered(9,"按Q键退出游戏");
ifletSome(key)=ctx.key{
matchkey{
VirtualKeyCode::P=>self.restart(),
VirtualKeyCode::Q=>ctx.quitting=true,
_=>{}
}
{}
}
}
}
implGameStateforState{
fntick(&mutself,ctx:&mutBTerm){
matchself.mode{
GameMode::Menu=>self.main_menu(ctx),
GameMode::End=>self.dead(ctx),
GameMode::Playing=>self.play(ctx),
}
//ctx.cls();
//ctx.print(1,1,"Hello,BracketTerminal!");
}
}
fnmain()->BError{
letcontext:BTerm=BTermBuilder::simple80x50()
.with_title("爽哥做游戏--FlappyDragon")
.build()" />
增加玩家
usebracket_lib::prelude::*;//游戏3种模式(菜单,游戏中,结束)
enumGameMode{
Menu,
Playing,
End,
}
constSCREEN_WIDTH:i32=80;
constSCREEN_HEIGHT:i32=50;
constFRAME_DURATION:f32=75.0;
structPlayer{
x:i32,
y:i32,
velocity:f32,
}
implPlayer{
fnnew(x:i32,y:i32)->Self{
Player{
x:0,
y:0,
velocity:0.0,
}
}
fnrender(&mutself,ctx:&mutBTerm){
ctx.set(0,self.y,YELLOW,BLACK,to_cp437('@'));
}
fngravity_and_move(&mutself){
ifself.velocity<2.0{
self.velocity+=0.2;
}
self.y+=self.velocityasi32;
self.x+=1;
ifself.y<0{
self.y=0;
}
}
fnflap(&mutself){
self.velocity=-2.0;
}
}
structState{
player:Player,
frame_time:f32,
mode:GameMode,
}
implState{
fnnew()->Self{
State{
player:Player::new(5,25),
frame_time:0.0,
mode:GameMode::Menu,
}
}
fnplay(&mutself,ctx:&mutBTerm){
ctx.cls_bg(NAVY);
self.frame_time+=ctx.frame_time_ms;
ifself.frame_time>=FRAME_DURATION{
self.player.gravity_and_move();
self.frame_time=0.0;
}
//按空格
ifletSome(VirtualKeyCode::Space)=ctx.key{
self.player.flap();
}
self.player.render(ctx);
ctx.print(0,0,"按空格起飞~");
ifself.player.y>SCREEN_HEIGHT{
self.mode=GameMode::End;
}
}
fnrestart(&mutself){
self.player=Player::new(5,25);
self.frame_time=0.0;
self.mode=GameMode::Playing;
}
fnmain_menu(&mutself,ctx:&mutBTerm){
ctx.cls();
ctx.print_centered(5,"欢迎来到游戏~");
ctx.print_centered(8,"PressPkeytostartGame");
ctx.print_centered(9,"PressQtoquitGame");
ifletSome(key)=ctx.key{
matchkey{
VirtualKeyCode::P=>self.restart(),
VirtualKeyCode::Q=>ctx.quitting=true,
_=>{}
}
{}
}
}
fndead(&mutself,ctx:&mutBTerm){
ctx.cls();
ctx.print_centered(5,"你挂了..");
ctx.print_centered(8,"按P键再来一局");
ctx.print_centered(9,"按Q键退出游戏");
ifletSome(key)=ctx.key{
matchkey{
VirtualKeyCode::P=>self.restart(),
VirtualKeyCode::Q=>ctx.quitting=true,
_=>{}
}
{}
}
}
}
implGameStateforState{
fntick(&mutself,ctx:&mutBTerm){
matchself.mode{
GameMode::Menu=>self.main_menu(ctx),
GameMode::End=>self.dead(ctx),
GameMode::Playing=>self.play(ctx),
}
//ctx.cls();
//ctx.print(1,1,"Hello,BracketTerminal!");
}
}
fnmain()->BError{
letcontext:BTerm=BTermBuilder::simple80x50()
.with_title("爽哥做游戏--FlappyDragon")
.build()" />
增加障碍
usestd::fmt::format;usebracket_lib::prelude::*;
//游戏3种模式(菜单,游戏中,结束)
enumGameMode{
Menu,
Playing,
End,
}
constSCREEN_WIDTH:i32=80;
constSCREEN_HEIGHT:i32=50;
constFRAME_DURATION:f32=75.0;
structPlayer{
x:i32,
y:i32,
velocity:f32,
}
implPlayer{
fnnew(x:i32,y:i32)->Self{
Player{
x:0,
y:0,
velocity:0.0,
}
}
fnrender(&mutself,ctx:&mutBTerm){
ctx.set(0,self.y,YELLOW,BLACK,to_cp437('@'));
}
fngravity_and_move(&mutself){
ifself.velocity<2.0{
self.velocity+=0.2;
}
self.y+=self.velocityasi32;
self.x+=1;
ifself.y<0{
self.y=0;
}
}
fnflap(&mutself){
self.velocity=-2.0;
}
}
structState{
player:Player,
frame_time:f32,
mode:GameMode,
obstacle:Obstacle,
score:i32,
}
implState{
fnnew()->Self{
State{
player:Player::new(5,25),
frame_time:0.0,
mode:GameMode::Menu,
obstacle:Obstacle::new(SCREEN_WIDTH,0),
score:0,
}
}
fnplay(&mutself,ctx:&mutBTerm){
ctx.cls_bg(NAVY);
self.frame_time+=ctx.frame_time_ms;
ifself.frame_time>=FRAME_DURATION{
self.player.gravity_and_move();
self.frame_time=0.0;
}
//按空格
ifletSome(VirtualKeyCode::Space)=ctx.key{
self.player.flap();
}
self.player.render(ctx);
ctx.print(0,0,"按空格起飞~");
//障碍物&积分
//实时打印分数
ctx.print(0,1,&format!("Score:{}",self.score));
self.obstacle.render(ctx,self.player.x);
ifself.player.x>self.obstacle.x{
self.score+=1;//分数+1
self.obstacle=Obstacle::new(self.player.x+SCREEN_WIDTH,self.score);
}
ifself.player.y>SCREEN_HEIGHT||self.obstacle.hit_obstacle(&self.player){
self.mode=GameMode::End;
}
}
fnrestart(&mutself){
self.player=Player::new(5,25);
self.frame_time=0.0;
self.mode=GameMode::Playing;
//重置分数和障碍物
self.obstacle=Obstacle::new(SCREEN_WIDTH,0);
self.score=0;
}
fnmain_menu(&mutself,ctx:&mutBTerm){
ctx.cls();
ctx.print_centered(5,"欢迎来到游戏~");
ctx.print_centered(8,"PressPkeytostartGame");
ctx.print_centered(9,"PressQtoquitGame");
ifletSome(key)=ctx.key{
matchkey{
VirtualKeyCode::P=>self.restart(),
VirtualKeyCode::Q=>ctx.quitting=true,
_=>{}
}
{}
}
}
fndead(&mutself,ctx:&mutBTerm){
ctx.cls();
ctx.print_centered(5,"你挂了..");
//挂了后显示一下分数
ctx.print_centered(6,&format!("本局获得了{}分",self.score));
ctx.print_centered(8,"按P键再来一局");
ctx.print_centered(9,"按Q键退出游戏");
ifletSome(key)=ctx.key{
matchkey{
VirtualKeyCode::P=>self.restart(),
VirtualKeyCode::Q=>ctx.quitting=true,
_=>{}
}
{}
}
}
}
implGameStateforState{
fntick(&mutself,ctx:&mutBTerm){
matchself.mode{
GameMode::Menu=>self.main_menu(ctx),
GameMode::End=>self.dead(ctx),
GameMode::Playing=>self.play(ctx),
}
}
}
structObstacle{
x:i32,
gap_y:i32,
size:i32,
}
implObstacle{
fnnew(x:i32,score:i32)->Self{
letmutrandom:RandomNumberGenerator=RandomNumberGenerator::new();
Obstacle{
x,
gap_y:random.range(10,40),
size:i32::max(2,20-score),
}
}
fnrender(&mutself,ctx:&mutBTerm,player_x:i32){
letscreen_x=self.x-player_x;
lethalf_size=self.size/2;
foryin0..self.gap_y-half_size{
ctx.set(screen_x,y,RED,BLACK,to_cp437('|'));
}
foryinself.gap_y+half_size..SCREEN_HEIGHT{
ctx.set(screen_x,y,RED,BLACK,to_cp437('|'));
}
}
fnhit_obstacle(&self,player:&Player)->bool{
lethalf_size=self.size/2;
letdoes_x_match=player.x==self.x;
letplayer_above_gap=player.y<self.gap_y-half_size;
letplayer_below_gap=player.y>self.gap_y+half_size;
does_x_match&&(player_above_gap||player_below_gap)
}
}
fnmain()->BError{
letcontext:BTerm=BTermBuilder::simple80x50()
.with_title("爽哥做游戏--FlappyDragon")
.build()" />
参考资料
[1] 使用 Rust 开发一个微型游戏【已完结】: https://www.bilibili.com/video/BV1vM411J74S
本文由 mdnice 多平台发布