linuxのキーボード同時押し

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
すい

linuxのキーボード同時押し

#1

投稿記事 by すい » 10年前

linuxでキーボードの同時押しを判定したいのですが、どうやればいいでしょうか

コード:

while(1){
    if(同時押し判定)break;
}
みたいなことをやりたいです。

アバター
あたっしゅ
記事: 664
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: linuxのキーボード同時押し

#2

投稿記事 by あたっしゅ » 10年前

>linuxでキーボードの同時押しを判定したいのですが、どうやればいいでしょうか

同時押しでなければキー入力が判定できる、という実力の持ち主と考えてレスします。

生(なま) の Linux でやってるわけじゃないですよね。

「Linux で、ゲームなどのマルチメディア関係のソフトウェアを作る」を検索したところ、
SDL(Simple DirectMedia Layer) が出てきましたが、こちらをご使用ですか ?

http://ja.wikipedia.org/wiki/SDL SDL - Wikipedia(日本語)
http://www.x68uec.org/files/other/press ... uranbo.htm ゲーム作成講座 on Linux(&Windows)(日本語)
http://www.libsdl.org/index.php Simple DirectMedia Layer(英語)
http://www.tacoworks.jp/software/SDLdoc-jp/html/ SDL(日本語、Google Chrome では文字化け、IE11 ではOK)
http://www.tacoworks.jp/software/SDLdoc ... board.html SDL ドキュメント Handling the Keyboard(日本語)

以上をざっと見た感じでは、モディファイヤ(CTRL、ALT、SHIFTなど)ならできるようですが、普通のキー同士の同時押しの判定はできないようです。
ジョイスティックまわりの関数はあるので、ジョイスティックを使ってくれ、という方針なのでしょうか ?
とりあえず、自分は Linux での Demo(いわゆるメガデモ) 作りに興味があったので、調べてみました。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: linuxのキーボード同時押し

#3

投稿記事 by ISLe » 10年前

キーが押されたり離されたりするのを監視し、判定したいキーがすべて押されている状態を同時押しとみなします。

キーボードイベント処理をいちいち自前で実装するのは現実的ではないので、既存のツールキットライブラリを利用するのが良いと思います。

かずま

Re: linuxのキーボード同時押し

#4

投稿記事 by かずま » 10年前

こんなのは、いかがですか?

コード:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <sys/time.h>

int main(void)
{
    struct timeval tv, tv0 = { 0 };
    struct termios t, t0;
    char c, c0 = 0;
    long ti;

    tcgetattr(0, &t);
    t0 = t;
    t.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
                    | INLCR | IGNCR | ICRNL | IXON);
    t.c_oflag &= ~OPOST;
    t.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    t.c_cflag &= ~(CSIZE | PARENB);
    t.c_cflag |= CS8;
    tcsetattr(0, TCSANOW, &t);

    while (1) {
        read(0, &c, 1);
        gettimeofday(&tv, 0);
        ti = (tv.tv_sec - tv0.tv_sec) * 1000000 + (tv.tv_usec - tv0.tv_usec);
        if (ti < 100000) {
            printf(" %c %c\n", c0, c);
            break;
        }
        tv0 = tv;
        c0 = c;
        printf("%c\n", c);
        fflush(stdout);
    }
    tcsetattr(0, TCSANOW, &t0);
    return 0;
}

アバター
あたっしゅ
記事: 664
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: linuxのキーボード同時押し

#5

投稿記事 by あたっしゅ » 10年前

termios.h ってなんだろうって思って検索したら http://typea.info/tips/wiki.cgi?page=C+ ... 2%A4%C2%CE C termios構造体。

curses library ってなんじゃい、と思って、さらに検索したら http://ja.wikipedia.org/wiki/Curses curses。

http://ja.wikipedia.org/wiki/%E3%83%AD% ... C%E3%82%B0 ローグで使われたライブラリか。

すいさんは、期待していたのとは異なるレスがついた、と思われるかもしれません。
「キーボード同時押し」でゲームを作りたいのかな、と推測しました。
「Linux で」っていわれても、UNIX 系のゲームは、アルファベット文字しか表示できない時代から存在しているわけで、
わざわざ UNIX 系を選んでゲームを作る、となると、アルファベット文字で表現できるゲームが作りたいのかな、と受け取る人もいるのです。
別に、意地悪しているわけではありません。

キーボード同時押し判定はどんなプログラムで使うのか、
なぜ Windows 等ではなく、Linux を選んだのか

を書いてくださらないと、期待していたレスは付かないかもしれません。
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

かずま

Re: linuxのキーボード同時押し

#6

投稿記事 by かずま » 10年前

かずま さんが書きました:こんなのは、いかがですか?
tv0 の初期値を 0 にして、ti を求めるときに * 100000 で
マイクロ秒にしたらオーバーフローを起こして、ti がまともな
値にならず、思った通りに動かない場合があるというバグが
ありました。次のように修正します。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <termios.h>
#include <sys/time.h>
 
int main(void)
{
    struct timeval tv, tv0;
    struct termios t, t0;
    int c, c0 = 0;
    long ti;
 
    gettimeofday(&tv0, 0);
    tcgetattr(0, &t);
    t0 = t;
    t.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
                    | INLCR | IGNCR | ICRNL | IXON);
    t.c_oflag &= ~OPOST;
    t.c_lflag &= ~(ECHO | ECHONL | ICANON  | IEXTEN);
    t.c_cflag &= ~(CSIZE | PARENB);
    t.c_cflag |= CS8;
    tcsetattr(0, TCSANOW, &t);
 
    while (1) {
        c = getchar();
        gettimeofday(&tv, 0);
        ti = (tv.tv_sec - tv0.tv_sec) * 1000 + (tv.tv_usec - tv0.tv_usec) / 1000;
        if (ti < 100) break;
        tv0 = tv;
        c0 = c;
        printf("%c\r\n", c);
    }
    printf(" %c %c\r\n", c0, c);

    tcsetattr(0, TCSANOW, &t0);
    return 0;
}

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: linuxのキーボード同時押し

#7

投稿記事 by ISLe » 10年前

MS-DOSとかで文字しか使わなかった時代からしても、Linuxとは根本的にキーボードに対する仕組みが違うんですよね。

アバター
Hiragi(GKUTH)
記事: 167
登録日時: 13年前
住所: 大阪府
連絡を取る:

Re: linuxのキーボード同時押し

#8

投稿記事 by Hiragi(GKUTH) » 10年前

以前SDLでのゲーム作成をしていた時に、ここの新・ゲームプログラミングの館のキー監視関数を参考にしてSDLで
キー入力の監視をする関数を作成しました。(といってもまだ完全でない)

コード:

#include <stdio.h>

#include "SDL.h"

int Key[SDLK_LAST];      // キーが押されているフレーム数を格納する

int gpUpdateKey()
{
	Uint8 *tmpKey;           // 現在のキーの入力状態を格納する
	tmpKey = SDL_GetKeyState(NULL);
	SDL_PumpEvents();
	for(int i=0; i < SDLK_LAST; i++ )
	{ 
		if( tmpKey[i] != 0)  // i番のキーコードに対応するキーが押されていたら
		{
			Key[i]++;        // 加算
		} else {             // 押されていなければ
			Key[i] = 0;      // 0にする
		}
	}
        return 0;
}
この関数はゲーム使用を前提として作ったものなのでそもそも定期的に呼ばないといけません。
というわけですいさんのイメージしているような物とは違うかもしれませんが一応おいておきます。
だいがくせい!

閉鎖

“C言語何でも質問掲示板” へ戻る