这是一个有关使用ncursesw从Ruby制作简单游戏的故事。我暂时创建的回避游戏的操作如下所示。
运行环境
- Ubuntu 14.04
- Ruby 2.2.0
- ncursesw(gem)1.4.9
要安装所需组件,请使用以下命令
1 2 | $ sudo apt-get install libncursesw5-dev $ gem install ncursesw |
ncurses很好,但是这次我选择了ncursesw,它可以显示日文字符而不会出现乱码。
源代码
如果执行以下所示的main.rb,则将开始与GIF开头的游戏相同。您所要做的就是用向上,向下,向左和向右箭头键移动飞船,以避免飞弹。
由于项目符号是根据屏幕的大小生成的,因此在运行时在垂直和水平方向上的大小都没有限制。可以说,可以相应地调整难度等级。
main.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | require 'ncursesw' class MiniGame def initialize Ncurses.initscr Ncurses.curs_set(0) # カーソル非表示 Ncurses.cbreak # RAW(改行を待たない)モードにする Ncurses.noecho # 入力された内容をエコーしない Ncurses.keypad(Ncurses.stdscr, true) # KEY_* 用 color_config @height, @width = Ncurses.LINES, Ncurses.COLS @exit = false @player = [@height - 1, (@width / 2) - 2] @bullets = Array.new(@width - 1) do Array.new(@height) { false } end end # 全てのスレッドを実行する def run threads = [] threads << drawing_thread threads << input_thread threads << game_thread threads.each(&:join) close_scr rescue Interrupt close_scr end private # 色関連の設定 def color_config @has_colors = Ncurses.has_colors? if @has_colors Ncurses.start_color if Ncurses.use_default_colors == Ncurses::OK Ncurses.init_pair(1, Ncurses::COLOR_CYAN, -1) end end end # 描画するスレッド def drawing_thread Thread.new do until @exit draw_player draw_bullets Ncurses.refresh sleep 0.01 Ncurses.clear end end end # 入力を監視するスレッド def input_thread Thread.new do until @exit case Ncurses.getch when "q".ord then @exit = true when Ncurses::KEY_UP @player[0] -= 1 @player[0] = 1 if @player[0] < 2 when Ncurses::KEY_DOWN @player[0] += 1 @player[0] = @height - 1 if @player[0] > @height - 1 when Ncurses::KEY_RIGHT @player[1] += 1 @player[1] = @width - 3 if @player[1] > @width - 3 when Ncurses::KEY_LEFT @player[1] -= 1 @player[1] = 1 if @player[1] < 1 end end end end # 飛んでくる弾を生成したり当たり判定をしたりするスレッド def game_thread Thread.new do until @exit @bullets.map! do |row| row.unshift rand < 0.02 row.pop row end @exit = true if gameover? sleep 0.1 end Ncurses.move(0, 0) Ncurses.addstr("Game Over!\n") Ncurses.addstr("Please press any key...\n") end end # 自機を描画 def draw_player Ncurses.attron(Ncurses::COLOR_PAIR(1)) if @has_colors Ncurses.move(*@player.zip([-1, 0]).map{ |a, b| a+b }) Ncurses.addstr("▓") Ncurses.move(*@player.zip([0, -1]).map{ |a, b| a+b }) Ncurses.addstr("▓▓▓") Ncurses.attroff(Ncurses::COLOR_PAIR(1)) if @has_colors end # 飛んでくる弾を描画 def draw_bullets @bullets.each_with_index do |row, j| row.each_with_index do |bullet, i| if bullet Ncurses.move(i, j) Ncurses.addstr("▓") end end end end # 弾にあたったらゲームオーバー def gameover? @player.tap do |i, j| break [[i, j], [i, j-1], [i, j+1], [i-1, j]] .any? { |pi, pj| @bullets[pj][pi] } end end # 後処理 def close_scr Ncurses::curs_set(1) Ncurses.nocbreak Ncurses.echo Ncurses.endwin end end game = MiniGame.new game.run |
如何使用ncursesw
我没有看到很多关于在Ruby中处理ncursesw和ncurses的文章,但是有很多用C语言编写的示例和解释,这非常有帮助(因为函数名称相同)。在这里,我将主要介绍我这次制作的游戏中使用的功能。
初始设置和后处理
关于为初始化方法设置各种设置的方法,以及为防万一而在close_scr方法中恢复设置的方法。
-
Ncurses.initscr /Ncurses.endwin - 首先调用以进行初始化/这在程序结尾
-
Ncurses.curs_set(0) /Ncurses::curs_set(1) - 0隐藏光标/ 1显示
-
Ncurses.cbreak /Ncurses.nocbreak - 输入会立即反映出来,而无需等待按键输入中的换行
- 是/否
-
Ncurses.noecho /Ncurses.echo - 回声击键到屏幕
- 不要做
-
Ncurses.keypad(Ncurses.stdscr, true) - 在Ncurses.getch(将在后面进行说明)中,通过将其设置为ture,当您按下功能键或箭头键时,将返回键代码。
色彩设置
颜色被视为一对背景颜色和前景色,并且分配给该对颜色的数字用于为字符和背景上色。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | def color_config @has_colors = Ncurses.has_colors? if @has_colors Ncurses.start_color if Ncurses.use_default_colors == Ncurses::OK Ncurses.init_pair(1, Ncurses::COLOR_CYAN, -1) end end end # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ def draw_player Ncurses.attron(Ncurses::COLOR_PAIR(1)) if @has_colors # # この間はCOLOR_PAIR(1)の色で描画される # Ncurses.attroff(Ncurses::COLOR_PAIR(1)) if @has_colors end |
-
Ncurses.has_colors? - 返回颜色在当前设备上是否可用
-
Ncurses.start_color - 开始使用颜色时致电
-
Ncurses.use_default_colors - 将背景色和用于前景色的色号都设置为-1
- -1是默认的终端背景颜色吗?前景色的含义
-
Ncurses.init_pair(1, Ncurses::COLOR_CYAN, -1) - 制作一对颜色
- 在此示例中,对编号1具有一对CYAN前景和背景的默认颜色。
- 有关如何使用集合对的信息,请参考draw_player方法。
其他
-
Ncurses.getch - 等待按键输入
- 为每个键提供常量,例如Ncurses :: KEY_ *
-
Ncurses.move(i, j) - 将光标移动到屏幕上的第i行和第j列
-
Ncurses.addstr("文字列") - 在光标位置添加字符串
-
Ncurses.refresh - 在屏幕上反映由addstr等添加的字符串
-
Ncurses.clear - 清除屏幕上的字符串等信息
结论
这个回避游戏是在我之前做的居民应用程序中作为迷你游戏实现的,因此,如果您愿意,请看一下。
[Ruby]使用ncursesw的常驻应用程序
参考网站
https://github.com/sup-heliotrope/ncursesw-ruby
NCURSES编程方法
Serika表达ncurses