Commit f7eb74ff authored by Ivo Júnior's avatar Ivo Júnior
Browse files

Merge branch 'Issue#2' of gitlab.c3sl.ufpr.br:bft15/boulder-dash-ASCII into Issue#2

parents bd722721 0f5555ff
0
\ No newline at end of file
269
/* ==========================================================
* Projeto destinado a disciplina de Oficina de Computacao
*
* Autores: Bruno Freitas Tissei e Ivo de Souza Bueno Junior
* Disciplina: Oficina de Computacao
* Entrega: 17/12/2015
* ========================================================== */
#include "entity.h"
// desenha terra na tela
// i, j = posicao na matriz
// offx, offy = deslocamento para o centro
void renderDirt(int i, int j, int offx, int offy) {
int k, l;
for (k = 0; k < 3; k++)
for (l = 0; l < 6; l++)
// adiciona detalhes na cor da textura
if ((k == 0 && (l == 2 || l == 4)) ||
(k == 1 && (l == 3 || l == 5)) ||
(k == 2 && (l == 0 || l == 4))) {
attron(COLOR_PAIR(13));
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", dirt[k][l]);
attroff(COLOR_PAIR(13));
} else {
attron(COLOR_PAIR(1));
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", dirt[k][l]);
attroff(COLOR_PAIR(1));
}
}
// desenha pedra na tela
// i, j = posicao na matriz
// offx, offy = deslocamento para o centro
void renderBould(int i, int j, int offx, int offy) {
int k, l;
for (k = 0; k < 3; k++)
for (l = 0; l < 6; l++)
// adiciona detalhes na cor da textura
if (!((k == 0 || k == 2) && (l == 0 || l == 5))) {
if (k == 0 && (l == 3 || l == 4)) {
attron(COLOR_PAIR(8));
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", bould[k][l]);
attroff(COLOR_PAIR(8));
} else {
attron(COLOR_PAIR(3));
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", bould[k][l]);
attroff(COLOR_PAIR(3));
}
}
}
// desenha diamante na tela
// i, j = posicao na matriz
// offx, offy = deslocamento para o centro
// time = tempo para executar a animacao da textura
void renderDiamonds(int i, int j, int offx, int offy, int time) {
if (time < 10)
renderChar(diamond, i, j, offx, offy, 7);
else if (time < 20)
renderChar(diamond2, i, j, offx, offy, 7);
else
renderChar(diamond3, i, j, offx, offy, 7);
}
/* ==========================================================
* Projeto destinado a disciplina de Oficina de Computacao
*
* Autores: Bruno Freitas Tissei e Ivo de Souza Bueno Junior
* Disciplina: Oficina de Computacao
* Entrega: 17/12/2015
* ========================================================== */
#ifndef _ENTITY_H
#define _ENTITY_H
#include "utils.h"
// jogador:
// x, y = coordenadas do jogador na matriz
// dir = direcao do jogador (8 - cima | 4 - esquerda | 6 - direita | 2 - baixo)
// diamonds = quantidades de diamantes que o jogador possui no level atual
// score = pontuacao do jogador na sessao atual
typedef struct {
int x, y;
int dir;
......@@ -8,6 +22,11 @@ typedef struct {
int score;
} rockford;
// level:
// sprite = arquivo com o sprite do level representado em uma matriz
// grid[WIDTH][HEIGHT] = matriz que representa o mapa (WIDTH = 40, HEIGHT = 21)
// score = pontuacao de cada diamante no level atual
// diamonds = quantidade de diamantes necessarios para passar do level atual
typedef struct {
FILE *sprite;
char grid[WIDTH][HEIGHT];
......@@ -15,6 +34,13 @@ typedef struct {
int diamonds;
} map;
// menu:
// sprite = arquivo com o sprite do menu representado em uma matriz
// highscore = arquivo com a maior pontuacao
// lastscore = arquivo com a ultima pontuacao
// grit[WIDTH][HEIGHT] = matriz que representa o menu (WIDTH = 40, HEIGHT = 21)
// high = a maior pontuacao
// last = a ultima pontuacao
typedef struct {
FILE *sprite;
FILE *highscore;
......@@ -24,6 +50,11 @@ typedef struct {
int last;
} menu;
// vagalume:
// x, y = coordenadas do vagalume na matriz
// dir = direcao do vagalume (8 - cima | 4 - esquerda | 6 - direita | 2 - baixo)
// dead = vagalume estah morto?
// *next = proximo vagalume, pois essa estrutura trata-se de um nodo de uma lista encadeada
typedef struct firefly {
int x, y;
int dir;
......@@ -31,4 +62,8 @@ typedef struct firefly {
struct firefly *next;
} firefly;
void renderDirt(int i, int j, int offx, int offy);
void renderBould(int i, int j, int offx, int offy);
void renderDiamonds(int i, int j, int offx, int offy, int time);
#endif
/* ==========================================================
* Projeto destinado a disciplina de Oficina de Computacao
*
* Autores: Bruno Freitas Tissei e Ivo de Souza Bueno Junior
* Disciplina: Oficina de Computacao
* Entrega: 17/12/2015
* ========================================================== */
#include "firefly.h"
// trata logica de movimentacao e comportamento do vagalume
// *m = mapa
// *first = primeiro elemento da lista encadeada de vagalumes
// *dead = jogador morto
// done = jogador completou o level
void updateFirefly(map *m, firefly *first, int *dead, int done) {
firefly *aux = first->next;
int i, j, k, l;
// percorre a lista encadeada de vagalumes
while (aux != NULL) {
i = aux->x;
j = aux->y;
if (!aux->dead) {
// caso o jogador nao terminou a fase, verifica as bordas do vagalume
// para tratar colisao (morte do jogador)
if (!done) {
for (k = -1; k <= 1; k++) {
for (l = -1; l <= 1; l++) {
......@@ -18,7 +33,11 @@ void updateFirefly(map *m, firefly *first, int *dead, int done) {
}
}
}
// trata comportamento de cada direcao do vagalume
// ordem de prioridade de movimento:
// esquerda > frente > direita > tras
switch (aux->dir) {
// movimento atual: cima
case(8):
if (m->grid[i-1][j] == '0') {
m->grid[i-1][j] = 'M';
......@@ -42,6 +61,7 @@ void updateFirefly(map *m, firefly *first, int *dead, int done) {
aux->y++;
}
break;
// movimento atual: esquerda
case(4):
if (m->grid[i][j+1] == '0'){
m->grid[i][j+1] = 'M';
......@@ -65,6 +85,7 @@ void updateFirefly(map *m, firefly *first, int *dead, int done) {
aux->x++;
}
break;
// movimento atual: direita
case(6):
if (m->grid[i][j-1] == '0'){
m->grid[i][j-1] = 'M';
......@@ -88,6 +109,7 @@ void updateFirefly(map *m, firefly *first, int *dead, int done) {
aux->x--;
}
break;
// movimento atual: baixo
case(2):
if (m->grid[i+1][j] == '0'){
m->grid[i+1][j] = 'M';
......@@ -116,3 +138,28 @@ void updateFirefly(map *m, firefly *first, int *dead, int done) {
aux = aux->next;
}
}
// desenha vagalume na tela
// i, j = posicao na matriz
// offx, offy = deslocamento para o centro
// b1, b2, b3 = cores
void renderFirefly(int i, int j, int offx, int offy, int b1, int b2, int b3) {
int k, l;
for (k = 0; k < 3; k++)
for (l = 0; l < 6; l++) {
// adiciona detalhes na cor da textura
if (k == 0 || k == 2 || l == 0 || l == 5) {
attron(COLOR_PAIR(b1));
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", empty[k][l]);
attroff(COLOR_PAIR(b1));
} else if (k == 1 && (l == 2 || l == 3)) {
attron(COLOR_PAIR(b2));
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", empty[k][l]);
attroff(COLOR_PAIR(b2));
} else {
attron(COLOR_PAIR(b3));
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", empty[k][l]);
attroff(COLOR_PAIR(b3));
}
}
}
/* ==========================================================
* Projeto destinado a disciplina de Oficina de Computacao
*
* Autores: Bruno Freitas Tissei e Ivo de Souza Bueno Junior
* Disciplina: Oficina de Computacao
* Entrega: 17/12/2015
* ========================================================== */
#ifndef _FIREFLY_H
#define _FIREFLY_H
#include "utils.h"
#include "entity.h"
void updateFirefly(map *m, firefly *first, int *dead, int done);
void renderFirefly(int i, int j, int offx, int offy, int b1, int b2, int b3);
#endif
/* ==========================================================
* Projeto destinado a disciplina de Oficina de Computacao
*
* Autores: Bruno Freitas Tissei e Ivo de Souza Bueno Junior
* Disciplina: Oficina de Computacao
* Entrega: 17/12/2015
* ========================================================== */
#include "game.h"
// o level
map level;
// o menu
menu me;
// opcao retornada pelo menu
int menuaction = 0;
int load = true;
int loadMenu = false;
// variaveis para cuidar da transicao entre o menu e o jogo
int load = false;
int loadMenu = true;
// loop principal do jogo
// ismenu = estah no menu
// running = estah rodando
void run(int ismenu, int running) {
// variaveis para tratar o tempo de atualizacao
double last_time, current_time, delta = FPS;
int sleep_time, action = 0, s = 0;
int sleep_time, clock = 0;
// entrada do jogador
int action = 0;
// carrega scores
me.highscore = fopen("./data/highscore.txt", "r");
fscanf(me.highscore, "%d", &me.high);
me.lastscore = fopen("./data/lastscore.txt", "r");
......@@ -18,27 +36,45 @@ void run(int ismenu, int running) {
fclose(me.highscore);
fclose(me.lastscore);
// obtem tempo antes de comecar jogo
last_time = getTime() / NANO;
// carrega sprite do menu
readFileMenu(&me);
while (running) {
// obtem tempo atual
current_time = getTime() / NANO;
// verifica se estah na hora de atualizar o jogo
if (current_time >= last_time) {
// limita atualizacao a 30 fps
last_time += delta;
// verifica se desenha menu ou level
if (ismenu)
renderMenu(&me);
else {
// verifica se estah na hora de carregar o level
if (load) {
// carrega o level
readFileMap(&level, menuaction, 0);
load = false;
}
render(s);
render(clock);
}
// atualiza o jogo
update(action, &ismenu);
// guarda a entrada do teclado
action = getInput();
s = (s + 1) % 30;
// conta o tempo que serah utilizado como relogio em varias funcoes dentro do renderMap
clock = (clock + 1) % 30;
} else {
// define tempo de paralizacao
sleep_time = (int) ((last_time - current_time));
// paraliza o jogo durante o tempo necessario para limitar o jogo a 30 fps
if (sleep_time > 0)
usleep(sleep_time);
}
......@@ -46,6 +82,7 @@ void run(int ismenu, int running) {
}
int getInput() {
// recebe entrada do teclado
int input = getch();
if (input != ERR) {
switch (input) {
......@@ -57,8 +94,10 @@ int getInput() {
return 6;
case KEY_LEFT:
return 4;
// enter
case 10:
return 1;
// esc
case 27:
return 9;
default:
......@@ -68,20 +107,30 @@ int getInput() {
return 0;
}
// atualiza o jogo
// action = entrada do teclado
// *ismenu = estah no menu?
void update(int action, int *ismenu) {
if (*ismenu) {
// atualiza o menu e recebe entrada
menuaction = updateMenu(&me, action, &loadMenu);
// carrega o jogo caso o jogador pressione enter no menu
if (menuaction != -1) {
load = true;
*ismenu = false;
me.last = 0;
}
} else
// atualiza level
updateMap(&level, action, ismenu, &loadMenu);
}
// desenha level na tela
// time = relogio
void render(int time) {
// apaga tela antiga
erase();
// desenha tela nova
renderMap(&level, time);
refresh();
}
/* ==========================================================
* Projeto destinado a disciplina de Oficina de Computacao
*
* Autores: Bruno Freitas Tissei e Ivo de Souza Bueno Junior
* Disciplina: Oficina de Computacao
* Entrega: 17/12/2015
* ========================================================== */
#ifndef _GAME_H
#define _GAME_H
#include "utils.h"
......
/* ==========================================================
* Projeto destinado a disciplina de Oficina de Computacao
*
* Autores: Bruno Freitas Tissei e Ivo de Souza Bueno Junior
* Disciplina: Oficina de Computacao
* Entrega: 17/12/2015
* ========================================================== */
#include "main.h"
// inicio do programa
int main() {
startCurses();
// inicia o loop principal do jogo
run(true, true);
endCurses();
return 0;
}
// inicia ncurses
void startCurses() {
// inicia tela
initscr();
// possibilita uso de cores
start_color();
cbreak();
// retira espera por entrada durante execucao do programa
nodelay(stdscr, true);
// desabilita repeticao da entrada
noecho();
// ativa o teclado para a tela atual
keypad(stdscr, true);
// esconde cursor
curs_set(0);
}
// finaliza ncurses
void endCurses() {
endwin();
}
/* ==========================================================
* Projeto destinado a disciplina de Oficina de Computacao
*
* Autores: Bruno Freitas Tissei e Ivo de Souza Bueno Junior
* Disciplina: Oficina de Computacao
* Entrega: 17/12/2015
* ========================================================== */
#ifndef _MAIN_H
#define _MAIN_H
#include "utils.h"
......
#include "maps.h"
#include "physics.h"
char input[WIDTH];
char mapfile[8][100] = {"./sprites/map1.txt", "./sprites/map2.txt", "./sprites/map3.txt",
"./sprites/map4.txt", "./sprites/map5.txt", "./sprites/map6.txt",
"./sprites/map7.txt", "./sprites/congrats.txt"};
int colors[8][3];
char input[WIDTH];
rockford player;
firefly *firstff, *lastff;
int colors[8][3];
int alter;
int dead;
int offy, offx;
......@@ -40,15 +39,15 @@ void readFileMap(map *m, int mapn, int pscore) {
falltime = 0;
m->sprite = fopen(mapfile[mapnumber], "r");
firstff = (firefly*) malloc(sizeof(firefly));
lastff = firstff;
lastff->next = NULL;
fscanf(m->sprite, "%d %d %d", &m->diamonds, &m->score, &leveltime);
for (i = 0; i < 8; i++)
for (j = 0; j < 3; j++)
fscanf(m->sprite, "%d", &colors[i][j]);
firstff = (firefly*) malloc(sizeof(firefly));
lastff = firstff;
lastff->next = NULL;
for (i = 0; i < HEIGHT; i++) {
fscanf(m->sprite, "%s", input);
for (j = 0; j < WIDTH; j++) {
......@@ -153,6 +152,7 @@ void updateMap(map *m, int action, int *ismenu, int *loadMenu) {
getmaxyx(stdscr, row, col);
offy = (row / 2) - (12 * 3);
offx = (col / 2) - (20 * 6);
if (action == 9) {
saveScore();
*ismenu = true;
......@@ -195,18 +195,15 @@ void updateMap(map *m, int action, int *ismenu, int *loadMenu) {
}
void renderMap(map *m, int time) {
int i, j, k, l;
if (mapnumber == 7) {
m->grid[21][20] = ((player.score / 100000) % 10) + 'A';
m->grid[22][20] = ((player.score / 10000) % 10) + 'A';
m->grid[23][20] = ((player.score / 1000) % 10) + 'A';
m->grid[24][20] = ((player.score / 100) % 10) + 'A';
m->grid[25][20] = ((player.score / 10) % 10) + 'A';
m->grid[26][20] = (player.score % 10) + 'A';
} else {
int i, j, magnitude;
if (mapnumber == 7)
for (i = 21, magnitude = 100000; i <= 26; i++, magnitude /= 10)
m->grid[i][20] = ((player.score / magnitude) % 10) + 'A';
else {
m->grid[3][0] = ((m->diamonds / 10) % 10) + 'A';
m->grid[4][0] = (m->diamonds % 10) + 'A';
m->grid[5][0] = 'K';
m->grid[6][0] = ((m->score / 10) % 10) + 'A';
......@@ -215,16 +212,11 @@ void renderMap(map *m, int time) {
m->grid[12][0] = ((player.diamonds / 10) % 10) + 'A';
m->grid[13][0] = (player.diamonds % 10) + 'A';
m->grid[25][0] = (leveltime / 100) + 'A';
m->grid[26][0] = ((leveltime / 10) % 10) + 'A';
m->grid[27][0] = (leveltime % 10) + 'A';
for (i = 25, magnitude = 100; i <= 27; i++, magnitude /= 10)
m->grid[i][0] = ((leveltime / magnitude) % 10) + 'A';
m->grid[31][0] = ((player.score / 100000) % 10) + 'A';
m->grid[32][0] = ((player.score / 10000) % 10) + 'A';
m->grid[33][0] = ((player.score / 1000) % 10) + 'A';
m->grid[34][0] = ((player.score / 100) % 10) + 'A';
m->grid[35][0] = ((player.score / 10) % 10) + 'A';
m->grid[36][0] = (player.score % 10) + 'A';
for (i = 31, magnitude = 100000; i <= 36; i++, magnitude /= 10)
m->grid[i][0] = ((player.score / magnitude) % 10) + 'A';
}
if (done && player.x == extx && player.y == exty) {
......@@ -253,8 +245,11 @@ void renderMap(map *m, int time) {
updatePhysics(m, m->grid[i][j], i, j, offx, offy, time, falltime, waittime, &dead);
falltime = (falltime + 1) % 7;
if (mapnumber == 7 && ((m->grid[i][j] >= 'a' && m->grid[i][j] <= 'z') || m->grid[i][j] == '@' || m->grid[i][j] == '#' || m->grid[i][j] == '!'))
if (mapnumber == 7 && ((m->grid[i][j] >= 'a' && m->grid[i][j] <= 'z') ||
m->grid[i][j] == '@' || m->grid[i][j] == '#' || m->grid[i][j] == '!'))
renderLetter(m->grid[i][j], i, j, offx, offy);
if (m->grid[i][j] >= 'A' && m->grid[i][j] <= 'K')
renderHUB(m->grid[i][j], i, j, offx, offy);
switch (m->grid[i][j]) {
case('0'):
......@@ -264,17 +259,7 @@ void renderMap(map *m, int time) {
renderChar((j == 1 || j == 22) ? steel : steel2, i, j, offx, offy, 5);
break;
case('2'):
for (k = 0; k < 3; k++)
for (l = 0; l < 6; l++)
if ((k == 0 && (l == 2 || l == 4)) || (k == 1 && (l == 3 || l == 5)) || (k == 2 && (l == 0 || l == 4))) {
attron(COLOR_PAIR(13));
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", dirt[k][l]);
attroff(COLOR_PAIR(13));
} else {
attron(COLOR_PAIR(1));
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", dirt[k][l]);
attroff(COLOR_PAIR(1));
}
renderDirt(i, j, offx, offy);
break;
case('z'):
renderChar(wall, i, j, offx, offy, 4);
......@@ -283,125 +268,45 @@ void renderMap(map *m, int time) {
renderChar(wall2, i, j, offx, offy, 4);
break;
case('4'):
if (done) {
if (time < 15)
renderChar(ext, i, j, offx, offy, 5);
else
renderChar(empty, i, j, offx, offy, 4);
} else
renderChar(ext, i, j, offx, offy, 5);
renderChar(ext, i, j, offx, offy, 5);
if (done && time >= 15)
renderChar(empty, i, j, offx, offy, 4);
break;
case('5'):
for (k = 0; k < 3; k++)
for (l = 0; l < 6; l++) {
attron(COLOR_PAIR((k == 0 || k == 1) ? 6 + k : 12));
if (player.dir == 0 || player.dir == 5)
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", rockf[k][l]);
else if (player.dir == 6 || player.dir == 8)
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", rockfr[k][l]);
else if (player.dir == 4 || player.dir == 2)
mvprintw(3*j+k+offy, 6*i+l+offx, "%c", rockfl[k][l]);
attroff(COLOR_PAIR((k == 0 || k == 1) ? 6 + k : 12));
}
renderRockford(&player, i, j, offx, offy);
break;
case('M'):
renderFirefly(i, j, offx, offy, blink1, blink2, blink3);
break;
case('6'):
if ((m->grid[i][j+1] == '6' || m->grid[i][j+1] == 'w' || m->grid[i][j+1] == 'z' || m->grid[i][j+1] == '7')
&& m->grid[i+1][j] == '0' && m->grid[i+1][j+1] == '0')
if ((m->grid[i][j+1] == '6' || m->grid[i][j+1] == 'w' ||
m->grid[i][j+1] == 'z' || m->grid[i][j+1] == '7') &&
m->grid[i+1][j] == '0' && m->grid[i+1][j+1] == '0')
m->grid[i][j] = 'r';
else if ((m->grid[i][j+1] == '6' || m->grid[i][j+1] == 'w' || m->grid[i][j+1] == 'z' || m->grid[i][j+1] == '7')
&& m->grid[i-1][j] == '0' && m->grid[i-1][j+1] == '0')
else if ((m->grid[i][j+1] == '6' || m->grid[i][j+1] == 'w' ||
m->grid[i][j+1] == 'z' || m->grid[i][j+1] == '7') &&
m->grid[i-1][j] == '0' && m->grid[i-1][j+1] == '0')
m->grid[i][j] = 'l';
if (m->grid[i][j+1] == '0')
m->grid[i][j] = 'f';