Pac – Man

Transcrição

Pac – Man
Pac – Man
Relatório do Grupo – Engenharia de Computação
Universidade Federal do Espírito Santo – UFES
Departamento de Informática – Programação II – 2011/2
Grupo
Breno Simão Boscaglia
Diego Paixão Rodrigues
Nicolas Garcia Cavalcante
Professores
Crediné Silva de Menezes.
Orivaldo de Lira Tavares.
Universidade Federal do Espírito Santo
Departamento de Informática
1. Introdução:
O problema escolhido e desenvolvido pelo grupo foi o famoso jogo Pac–
Man. Pac-Man é um jogo eletrônico criado por Toru Iwatani para a empresa
Namco, e sendo distribuído para o mercado americano pela Midway. Produzido
originalmente para Arcade no início da década de 80, tornou-se um dos jogos
mais populares do momento, tendo versões para diversos consoles e
continuações para tantos outros, inclusive na atualidade.
A estrutura do jogo é bem simples: o jogador é uma cabeça redonda com
uma boca que se abre e fecha, posicionado em um labirinto simples repleto de
pastilhas e 4 fantasmas que o perseguiam. O objetivo é comer todas as pastilhas
sem ser alcançado pelos fantasmas, em ritmo progressivo de dificuldade.
A versão do jogo desenvolvida e trabalhada pelo
grupo consiste basicamente nos principais objetivos do
original. O usuário comanda o Pac–Man, que é o
personagem principal, e se movimenta com ele ao longo do
mapa, que possui obstáculos. Assim como o original, seu
objetivo é comer todas as comidas e os bônus distribuídos
ao longo do mapa, fugindo dos monstros simultaneamente.
As comidas valem 1 ponto cada uma, e os bônus, que
consistem no símbolo “$”, valem 10 pontos cada. Vale
ressaltar que na tela do jogo, o usuário pode visualizar a pontuação que ele
acumula ao longo do jogo, por meio do “Score”, que fica visível em cima do mapa.
Antes de iniciar o jogo o usuário se depara com uma capa principal, que se
segue por um menu, onde ele pode escolher em ver as instruções para o mesmo,
ler sua breve história, ou joga-lo. Escolhendo a opção de jogo, tem-se dois níveis
de dificuldade: o nível fácil (1 monstro) ou o difícil (2 monstros).
Durante qualquer momento, inclusive na execução do jogo, o usuário tem a
opção de sair, teclando “Esc”, onde ele irá visualizar uma mensagem se ele deseja
realmente sair ou voltar para jogo, e o jogo então retorna exatamente de onde
parou.
Algumas diferenças entre a versão desenvolvida pelo grupo e o jogo
original:
 No jogo original quando o Pac–Man come as comidas maiores, uma
espécie de bônus, o usuário pode por um instante correr atrás dos
monstros e então destruí-los momentaneamente, enquanto que na versão
do grupo isto não é possível, somente os monstros podem comer o Pac–
Man, ou seja, o usuário deve sempre fugir dos monstros de forma a tentar
comer todas as comidas.
 No jogo original o usuário possui 3 vidas, enquanto que na versão
desenvolvida pelo grupo o usuário possui somente 1 vida.
2
Universidade Federal do Espírito Santo
Departamento de Informática
Segue abaixo algumas fotos das principais telas do jogo:
Capa:
Menu Principal:
3
Universidade Federal do Espírito Santo
Departamento de Informática
Durante o Jogo:
2.
Proposta:
Para a melhor organização do problema codificado, foram utilizadas funções
parametrizadas ou não. Para cada movimento, seja do Pac-Man ou dos monstros,
para cada menu e para a impressão do mapa na tela, temos funções diferentes. A
baixo seguem seus nomes e suas características:

void menu(): Essa função é responsável por imprimir o menu do
jogo, assim como levar o jogador para sua escolha (Jogo, História,
Instruções ou Sair).

void capa(): Essa função imprime apenas uma vez, quando o
programa é rodado, há informações sobre o jogo, como os nomes dos
desenvolvedores e dos professores.
4
Universidade Federal do Espírito Santo
Departamento de Informática

void layout(): Tal função é muito importante pois é nela que o
jogo é criado. Todas as comidas, obstáculos e os bônus são atribuídos
à matriz do jogo.

void movimentoMon1(): Essa função tem como importância
movimentar o monstro 1, que é aquele que está no canto superior
esquerdo da tela. Toda a inteligência incorporada a ele deve-se a esta
função que analisa a posição do Pac-Man em relação ao monstro, e
realiza o melhor movimento possível.

void movimentoMon2(): Assim como a função do monstro 1, essa
daqui tem como objetivo movimentar o mostro 2 que está no canto
inferior direito da tela. Ao ser chamada, ela analisa a sua posição em
relação ao Pac-Man e faz o movimento mais adequado.

void movimentoPac(): Esta função é a base do jogo, pois é nela
que a tecla pressionada pelo usuário é identificada e o movimento do
Pac-Man é realizado. Depois que tal movimento é feito, essa função
chama as outras duas funções que realizam o movimento dos
monstros (dependendo da dificuldade escolhida pelo jogador).

void posicoes(int a, int b, int c, int d, int e, int
f): Essa função paramétrica é responsável diretamente por imprimir
o mapa para o jogador e está estritamente ligada à função
“movimentoPac()”, pois a cada vez que há um movimento do Pac-Man
ela é chamada para que “atualize” o mapa visto pelo usuário.

int main(): A função principal serve para fazer as principais
conexões entre as funções.
Logo no início da criação do jogo, nos deparamos com um problema que foi
solucionado com a criação de uma estrutura. Nós precisaríamos criar uma matriz
que fosse possível alterar suas entradas a todo instante e em todas as funções.
Por isso, não poderíamos declara-la em cada função separadamente. Portanto,
criamos o
struct
{
char mapa[25][60];
}jogo;
que nos possibilita alterar sempre a mesma matriz.
5
Universidade Federal do Espírito Santo
Departamento de Informática
Dentre muitos algoritmos utilizados na criação do jogo os mais importantes
são os que movimentam o Pac-man e os monstros. A função movimentoPac() é
chamada no main() e ali ela fica aguardando a direção que o jogador deseja
andar. Se a tecla pressionada for o “w”, então será atribuído à mesma coluna e
uma linha a menos que a posição atual do Pac-Man a letra ‘C’ e aonde ele estava
será atribuído um espaço vazio (‘0’ na tabela ASCII). Isso vale para os botões “a”,
“s” e “d”, entretanto, o movimento será para a esquerda, para baixo e para a
direita, respectivamente. Vale reforçar que no caso do movimento à esquerda, a
nova posição será a mesma linha mas uma coluna a menos na matriz, assim
como no movimento à direita será uma coluna a mais. Para o “s” a coluna da
matriz permanece e linha é acrescida de um.
É importante saber que antes que ocorra tais movimentos é necessário que
seja conferido se a posição destino é parede, se for, o Pac-Man ficará parado.
Dentro de cada um desses movimentos, as funções movimentoMon1() e
movimentoMon2() são chamadas para que movimente os monstros. Para melhor
explicar como funciona tais funções utilizaremos como referência apenas uma
mas tudo se aplica para a outra.
A função do monstro comparará a
posição atual entre ele e o Pac-Man, sendo
8 possíveis situações, veja figura ao lado.
Caso apenas as colunas da matriz esteja
variando o monstro tentará ir em linha reta
até o Pac-Man, mas se algum obstáculo
(parede) for encontrado no caminho ele
terá rotas de fuga alternativas. Agora,
tomando o monstro como a origem do
plano cartesiano e imaginando que o seu
objetivo esteja no primeiro quadrante ele tentará alcança-lo fazendo movimentos
em forma de escada. Entretanto, quando esta situação ocorre, um número
aleatório (0 ou 1) é gerado e cada um deles faz um movimento diferente (o 0 varia
a linha e o 1 varia a coluna). Assim, temos um movimento aleatório que sempre
visa o seu objetivo. Assim como no caso em que eles estão na mesma linha, caso
o movimento gerado (0 ou 1) for parede ele terá rotas de fuga programadas. Vale
lembrar que as outras situações tem a mesma lógica, entretanto em sentido e
direção diferentes.
Algo muito importante, utilizado no decorrer do programa são as bibliotecas
importadas no início do código, dentre elas temos:
#include <stdio.h>: Do inglês “standard input-output header”, possui definições de
entrada e saída como leitura de dados digitados e impressão de informações na
tela. Utilizada no “printf” e “scanf”.
#include <conio.h>: Tamebém ultilizada para entrada e sáida de dados. Ela
possui funções mais complexas que a stdio.h não tem. Utilizada no getch().
6
Universidade Federal do Espírito Santo
Departamento de Informática
#include <time.h>: Biblioteca responsável pela manipulação de data e hora.
Com ela conseguimos gerar um número “aleatório” apartir do tempo da máquina.
#include <windows.h>: Possui declarações de todas as funções no
Windows API. Foi utilizada para o comando “Sleep”.
É importante lembrar a interação entre o jogador e o jogo. Tentamos fazer com
que ele fosse mais flexível possível. A toda hora, colocamos opções de voltar ao
menu principal, e opções de sair do jogo.
As teclas necessária para se jogar são mostradas antes que o jogo se inicie e
são “w”,“a”,”s” e ”d” que faz o moviemnto do Pac-Man.
3.
Testes:
Por ser um jogo que não possui dados de entrada e saida numérica direta,
para testá-lo foi necessário que criássemos situações críticas com o jogo, onde
poderíamos encontrar erros. As tabelas a seguir são os testes feitos para o PacMan e para o monstro, respectivamente.
Tecla Antes do movimento Movimento Esperado
w
w
w
w
a
a
a
a
s
s
s
s
d
d
d
d
vazio
comida
parede
monstro
vazio
comida
parede
monstro
vazio
comida
parede
monstro
vazio
comida
parede
monstro
Cima
Cima
--Cima
Esquerda
Esquerda
--Esquerda
Baixo
Baixo
--Baixo
Direita
Direita
--Direita
Movimento Feito Depois do Movimento
Cima
Cima
--Cima
Esquerda
Esquerda
--Esquerda
Baixo
Baixo
--Baixo
Direita
Direita
--Direita
vazio
vazio
parede
Game Over
vazio
vazio
parede
Game Over
vazio
vazio
parede
Game Over
vazio
vazio
parede
Game Over
Tabela 1: Teste feito com os movimentos do Pac-Man. Pode-se observar que todos os movimentos
esperados aconteceram, comprovando sua eficiência.
7
Universidade Federal do Espírito Santo
Departamento de Informática
Monstro Pac-Man
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
Origem
eixo x +
eixo x +
eixo x +
Quadrante 1
Quadrante 1
Quadrante 1
Quadrante 1
Quadrante 1
Quadrante 1
eixo y +
eixo y +
eixo y +
Quadrante 2
Quadrante 2
Quadrante 2
Quadrante 2
Quadrante 2
Quadrante 2
eixo x eixo x eixo x Quadrante 3
Quadrante 3
Quadrante 3
Quadrante 3
Quadrante 3
Quadrante 3
eixo y eixo y eixo y Quadrante 4
Quadrante 4
Quadrante 4
Quadrante 4
Quadrante 4
Quadrante 4
t 1ª Opção 2ª Opção 3ª Opção Movimento Esperado Movimento Feito
------0
0
0
1
1
1
------0
0
0
1
1
1
------0
0
0
1
1
1
------0
0
0
1
1
1
Livre
Parede
Parede
Livre
Parede
Parede
Livre
Parede
Parede
Livre
Parede
Parede
Livre
Parede
Parede
Livre
Parede
Parede
Livre
Parede
Parede
Livre
Parede
Parede
Livre
Parede
Parede
Livre
Parede
Parede
Livre
Parede
Parede
Livre
Parede
Parede
--Livre
Parede
--Livre
Parede
--Livre
Parede
--Livre
Parede
--Livre
Parede
--Livre
Parede
--Livre
Parede
--Livre
Parede
--Livre
Parede
--Livre
Parede
--Livre
Parede
--Livre
Parede
----Livre
----Livre
----Livre
----Livre
----Livre
----Livre
----Livre
----Livre
----Livre
----Livre
----Livre
----Livre
Direita
Cima
Esquerda
Cima
Direita
Esquerda
Direita
Cima
Esquerda
Cima
Esquerda
Baixo
Cima
Esquerda
Direita
Esquerda
Cima
Direita
Esquerda
Baixo
Direita
Cima
Esquerda
Direita
Esquerda
Cima
Direita
Cima
Direita
Baixo
Cima
Direita
Esquerda
Direita
Cima
Esquerda
Direita
Cima
Esquerda
Cima
Direita
Esquerda
Direita
Cima
Esquerda
Cima
Esquerda
Baixo
Cima
Esquerda
Direita
Esquerda
Cima
Direita
Esquerda
Baixo
Direita
Cima
Esquerda
Direita
Esquerda
Cima
Direita
Cima
Direita
Baixo
Cima
Direita
Esquerda
Direita
Cima
Esquerda
Tabela 2: Teste feito com os movimentos dos Monstros. Pode-se observar que todos os movimentos
esperados aconteceram, comprovando sua eficiência. Vale lembrar que a
coluna “t” é o número aleatório gerado(0 ou 1).
8
Universidade Federal do Espírito Santo
Departamento de Informática
4. Conclusão:
À princípio o problema nos pareceu bastante simples, mas com o decorrer
de sua idealização percebemos que teríamos um grande desafio pela frente. Com
o trabalho pronto, podemos observar que nossos principais objetivos foram
alcançados, até aqueles que julgávamos muito difíceis, como no caso dos
monstros perseguirem o Pac-Man.
Entretanto, nem tudo foi um sucesso em nosso projeto, um exemplo disso
foi o fato de não conseguirmos fazer com que os monstros seguissem trajetórias
diferentes, uma vez que eles estivessem juntos. Um outro problema encontrado,
foi o fato de armazenarmos o que havia na entrada que o monstro iria ocupar,
para que depois isso fosse impresso quando ele mudasse de posição, com isso,
se e eventualmente eles ocuparem a mesma posição na matriz, vários outros
monstros seriam “gerados”.
Algumas soluções para resolver esses problemas foram pensadas e
testadas, porém não obtivemos sucesso. Acreditamos que se tivéssemos mais
tempo, com certeza solucionaríamos todos eles.
9

Documentos relacionados