私はスクリプトに初めて触れており、どのように作業するかについての高度な質問があります。
私は現在、次の2つの主な機能を備えたSpace Invadersに似たシンプルなゲームをデザインしたいと思います。
- 毎秒画面上部の弾丸が落ちます。
- ユーザーは画面の下部で船を動かして弾丸を避けることができます。
問題は、入力を受けている間に弾丸を下に移動する方法が見つからないことです。
メインループのほとんどのコードは次のとおりです。
while true #gets user input and updates screen.
do
read -r -sn1 -t 1 USERIN
case $USERIN in
D) moveleft ;;
C) moveright ;;
esac
updatescreen #(my code makes sure that at least a second has passed since the last "updatescreen" execution before running this)
done
ユーザー入力に関係なく、画面を毎秒更新したいと思います。タイムアウトを入力するのに時間がかかるため、プログラムは中断に更新されます。読み出しタイムアウト値が低い場合は問題ありませんが、下げると「間違ったタイムアウト仕様」というエラーが発生します。
この問題を解決する方法はありますか?それとも完全に異なるプログラム構成がありますか?
答え1
マルチスレッドが必要です。見るGNUパラレル
答え2
解決策が見つかりました。デフォルトでは、バックグラウンドで更新ループを実行し、フォアグラウンドでメインループを実行します。トラップ/キルコマンドを使用して互いに通信できます。
完全な例を提供するために、.shファイルをgithubにアップロードしました。
どのように動作するかについての修正された概要は次のとおりです。
注:エスケープするにはctrl-cを使用する必要があります。
#!/bin/bash
update()
{
trap "move_left;" $LEFT
trap "move_right;" $RIGHT
while true; do
#output whatever needed
done
}
read_in()
{
trap "return;" SIGINT SIGQUIT
while true; do
read -s -n 1 key
case key in
C) kill -$RIGHT $game_pid ;;
D) kill -$LEFT $game_pid ;;
esac
done
}
move_left()
{
#update position variable
}
move_right()
{
#update position variable
}
update &
game_pid=$!
read_in
kill -9 $game_pid
上記のサンプルスクリプトを実際のサンプルバージョンとして使用してください。しかし、すでに持っています!プログラムアーキテクチャに対するいくつかの修正です。