Jogando Snake Game usando Raspberry Pi Game Pad – (Parte 38/38)

Este artigo discute sobre como desenvolver hardware de game pad simples e fazer interface com a placa Raspberrypi e também sobre o técnica de interface de um código de jogo escrito em HTML5 com o game pad. Aqui um Jogo Snake escrito em HTML5 e JavaScript foi modificado de forma que possa ser jogado com o novo game pad com quatro botões. Neste projeto são utilizadas as técnicas de sinais, pipe, fork etc.

O jogo Snake rodando em uma janela do navegador forma a GUI ou front end de todo o sistema. Num sistema operacional Linux, cada dispositivo de hardware é representado como um arquivo. O dispositivo pode ser controlado simplesmente lendo e gravando nesse arquivo. O hardware de um sistema operacional está de um lado e o usuário que tenta acessar o hardware está do outro lado, e entre eles pode haver várias camadas de processos em execução que se comunicam entre si usando métodos de comunicação entre processos. Neste projeto existe um game pad que é o hardware e existe um processo que lê o game pad e também existe um arquivo Pipe ou FIFO entre o jogo e o processo de leitura do game pad.

((wysiwyg_imageupload:11011:))

O jogo é executado em uma janela do navegador e se comunica com o game pad por meio de um Named Pipe ou FIFO. Existem vários processos em execução que podem ler o game pad e gravar os comandos necessários no FIFO para controlar o jogo. O JavaScript escrito no código do jogo simplesmente lê o FIFO para os dados de controle de entrada.

Diagrama de blocos do gamepad Raspberry pi

Fig. 2: Diagrama de blocos do gamepad Raspberry Pi

O processo pai aqui cria quatro processos filhos que são dedicados a cada uma das teclas do gamepad. Sempre que uma tecla é pressionada ou liberada, eles geram um sinal e o enviam ao processo pai com um valor. Usando este método o processo pai pode identificar qual tecla foi pressionada ou liberada.
Assim que o processo pai detecta um pressionamento de tecla a partir do valor recebido junto com o sinal, ele simplesmente grava um valor de comando específico no NAMED PIPE ou FIFO. O jogo HTML lerá continuamente o FIFO a cada 100ms e mudará a direção da cobra de acordo com o comando lido.
A próxima parte do JavaScript lê o arquivo a cada 100 ms e muda a direção do movimento da cobra no jogo.
//++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++//
função carregarArquivo
{
leitor = novo XMLHttpRequest novo ActiveXObject('MSXML2.XMLHTTP');
leitor.open('get', 'xyz', true);
leitor.onreadystatechange=displayContents;
leitor.send(null);
}
função displayContents
{
ch = leitor.responseText(0);
se(ch == 'eu')
título = (título == LESTE) ? LESTE OESTE;
senão if(ch == 'r')
rumo = (título == OESTE) ? OESTE LESTE;
senão if(ch == 'u')
rumo = (título == SUL) ? SUL NORTE;
senão if(ch == 'd')
rumo = (título == NORTE) ? NORTE SUL;
}
//++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++//
As funções utilizadas na codificação do código do Gamepad para operações de escrita no FIFO são explicadas na seção a seguir.
O FIFO precisa ser criado usando o seguinte comando no mesmo diretório onde existem o executável do gamepad e os arquivos HTML do jogo.
mkfifo xyz
O FIFO também pode ser criado usando o próprio código adicionando a função mkfifo , open conforme explicado em um artigo anterior documentação.
O usuário pode gravar dados no arquivo temporário a partir do próprio terminal usando o comando 'echo' conforme mostrado no exemplo a seguir.
eco abcdef >> /tmp/my_fifo
O processo pai de escrita FIFO é escrito de tal forma que escreverá comandos no FIFO em resposta aos sinais recebidos do processo filho. Os comandos que serão escritos no FIFO para controlar a direção da cobra estão listados abaixo;
você -> Cobra para cima
d -> Cobra para baixo
l -> Cobra Esquerda
r -> Cobra DIREITA
Esses comandos podem ser escritos no FIFO com a ajuda da função system .
sistema(“echo r >> xyz );
A chamada de função acima virará o Snake para a direita.

Código-fonte do projeto

###

#include <bcm2835.h>
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define IN_PIN1 RPI_GPIO_P1_07
#define IN_PIN2 RPI_GPIO_P1_22
#define IN_PIN3 RPI_GPIO_P1_18
#define IN_PIN4 RPI_GPIO_P1_16

#define OUT_PIN1 RPI_GPIO_P1_15
#define OUT_PIN2 RPI_V2_GPIO_P1_13
#define OUT_PIN3 RPI_GPIO_P1_12
#define OUT_PIN4 RPI_GPIO_P1_11

#define SNAKE_FIFO_NAME "xyz"

vazio set_pins_input (void);
vazio set_pins_output (void);
vazio set_output_pins_low (void);
void button_signal_handler ( int sig, siginfo_t *siginfo, void *context );
vazio signal_on_state_change_pin1 ( vazio );
vazio signal_on_state_change_pin2 ( vazio );
vazio signal_on_state_change_pin3 (void);
vazio signal_on_state_change_pin4 (void);
void sig_set_handler (int sinal, void *handler);
void sig_send_val (pid_t id, int signo, int val);

pid_t filho_id(5);
ponto interno = 0;

int principal (void)
{
int eu;
int cobra_fifo = -1;

se (!bcm2835_init )
retornar 1;

set_pins_output ;
set_output_pins_low ;
set_pins_input ;
atraso (100);

sig_set_handler ( SIGUSR1, &button_signal_handler );

if (! (child_id (0) = garfo ))
{
signal_on_state_change_pin1 ;
_sair(0);
}
outro;

if (! (child_id (1) = garfo ))
{
signal_on_state_change_pin2 ;
_sair(0);
}
outro;

if (! (child_id (2) = garfo ))
{
signal_on_state_change_pin3 ;
_sair(0);
}
outro;

if (! (child_id (3) = garfo ))
{
signal_on_state_change_pin4 ;
_sair(0);
}
outro;

enquanto (1)
{
sistema("eco x >> xyz");
atraso (100);
}

bcm2835_close ;
retornar 0;
}

vazio signal_on_state_change_pin1 ( vazio )
{
enquanto (1)
{
se (bcm2835_gpio_lev(IN_PIN1))
{
atraso (50);
se (bcm2835_gpio_lev(IN_PIN1))
{
sig_send_val (getppid , SIGUSR1, 1);

fazer
{
enquanto ( bcm2835_gpio_lev (IN_PIN1))
atraso (1);
atraso (50);
}
enquanto (bcm2835_gpio_lev(IN_PIN1));

sig_send_val (getppid , SIGUSR1, 1);
}
outro;
}outro;
atraso (1);
}
}

vazio signal_on_state_change_pin2 ( vazio )
{
enquanto (1)
{
se (bcm2835_gpio_lev(IN_PIN2))
{
atraso (50);
se (bcm2835_gpio_lev(IN_PIN2))
{
sig_send_val (getppid , SIGUSR1, 2);

fazer
{
enquanto ( bcm2835_gpio_lev (IN_PIN2))
atraso (1);
atraso (50);
}
enquanto (bcm2835_gpio_lev(IN_PIN2));

sig_send_val (getppid , SIGUSR1, 2);
}
outro;
}outro;
atraso (1);
}
}

vazio signal_on_state_change_pin3 ( vazio )
{
enquanto (1)
{
se (bcm2835_gpio_lev(IN_PIN3))
{
atraso (50);
se (bcm2835_gpio_lev(IN_PIN3))
{
sig_send_val (getppid , SIGUSR1, 3);

fazer
{
enquanto ( bcm2835_gpio_lev (IN_PIN3))
atraso (1);
atraso (50);
}
enquanto (bcm2835_gpio_lev(IN_PIN3));

sig_send_val (getppid , SIGUSR1, 3);
}
outro;
}outro;
atraso (1);
}
}

vazio signal_on_state_change_pin4 ( vazio )
{
enquanto (1)
{
se (bcm2835_gpio_lev(IN_PIN4))
{
atraso (50);
se (bcm2835_gpio_lev(IN_PIN4))
{
sig_send_val (getppid , SIGUSR1, 4);

fazer
{
enquanto ( bcm2835_gpio_lev (IN_PIN4))
atraso (1);
atraso (50);
}
enquanto (bcm2835_gpio_lev(IN_PIN4));

sig_send_val (getppid , SIGUSR1, 4);
}
outro;
}outro;
atraso (1);
}
}

void button_signal_handler (int sig, siginfo_t *siginfo, void *contexto)
{
if ( 1 == *( ( int * ) &siginfo -> si_value ) )
sistema("echo você >> xyz");
senão if ( 2 == *( ( int * ) &siginfo -> si_value ) )
sistema("echo r >> xyz");
senão if (3 == *( (int *) &siginfo -> si_value))
sistema("echo l >> xyz");
senão if ( 4 == *( ( int * ) &siginfo -> si_value ) )
sistema("echo d >> xyz");
outro;

bcm2835_gpio_write (OUT_PIN1,st);
st = ~ st;
}

vazio set_output_pins_low ( vazio )
{
bcm2835_gpio_write (OUT_PIN1, BAIXO);
bcm2835_gpio_write (OUT_PIN2, BAIXO);
bcm2835_gpio_write (OUT_PIN3, BAIXO);
bcm2835_gpio_write (OUT_PIN4, BAIXO);
}

vazio set_pins_output ( vazio )
{
bcm2835_gpio_fsel (OUT_PIN1, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel (OUT_PIN2, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel (OUT_PIN3, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel (OUT_PIN4, BCM2835_GPIO_FSEL_OUTP);
}

vazio set_pins_input ( vazio )
{
bcm2835_gpio_fsel ( IN_PIN1, BCM2835_GPIO_FSEL_INPT );
bcm2835_gpio_set_pud ( IN_PIN1, BCM2835_GPIO_PUD_OFF );

bcm2835_gpio_fsel ( IN_PIN2, BCM2835_GPIO_FSEL_INPT );
bcm2835_gpio_set_pud ( IN_PIN2, BCM2835_GPIO_PUD_OFF );

bcm2835_gpio_fsel ( IN_PIN3, BCM2835_GPIO_FSEL_INPT );
bcm2835_gpio_fsel ( IN_PIN3, BCM2835_GPIO_FSEL_INPT );

bcm2835_gpio_set_pud ( IN_PIN4, BCM2835_GPIO_PUD_OFF );
bcm2835_gpio_set_pud ( IN_PIN4, BCM2835_GPIO_PUD_OFF );
}

void sig_send_msg ( pid_t id, int signo, char *msg )
{
sinal de união *sigdata;

sigdata=malloc(sizeof(união sigval));
sigdata -> sival_ptr = mensagem;

sigqueue (id, sinal, *sigdata);

grátis (sigdata);
}

void sig_send_val ( pid_t id, int signo, int val )
{
sinal de união *sigdata;

sigdata=malloc(sizeof(união sigval));
sigdata -> sival_int = val;

sigqueue (id, sinal, *sigdata);

grátis (sigdata);
}

void sig_set_handler ( int sinal, void *handler )
{
struct sigaction *act;
act=malloc(sizeof(struct sigaction));
agir -> sa_sigaction = manipulador;
agir -> sa_flags = SA_SIGINFO;

sigaction (signo, ato, NULL);
}

###

Diagramas de circuito

Diagrama de circuito para jogar o jogo Snake-Raspberry-Pi

Vídeo do projeto

Conteúdo Relacionado

Voltar para o blog

Deixe um comentário

Os comentários precisam ser aprovados antes da publicação.