1
0
Fork 0
This commit is contained in:
me 2022-11-16 17:36:54 +03:30
parent b83d285241
commit f1e0c492b5
1 changed files with 257 additions and 159 deletions

416
sjump.c
View File

@ -1,22 +1,35 @@
/* /*
_ _ ___
| '. (_' |
| : ._)QUARE (_:UMP
|.' ARRT
Authored by abakh <abakh@tuta.io> Authored by abakh <abakh@tuta.io>
To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty. To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>. You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
*/ */
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#include <signal.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#include <curses.h>
#include <unistd.h>
#include "config.h"
#include "common.h" #include "common.h"
#define SAVE_TO_NUM 11 #define SAVE_TO_NUM 10
#define LEN 24 #define LEN 24
#define HLEN LEN/2 #define HLEN LEN/2
#define WID 80 #define WID 80
#define HWID WID/2 #define HWID WID/2
#define SIZE 12
#define SHOTS_WHEN_STARTING 10 #define SHOTS_WHEN_STARTING 10
#define DELAY 50000
#define byte int
#define randint(a,b) ((a)+(rand()%((b+1)-(a)))) #define randint(a,b) ((a)+(rand()%((b+1)-(a))))
#ifdef Plan9 #ifdef Plan9
int usleep(long usec) { int usleep(long usec) {
@ -31,9 +44,9 @@ int usleep(long usec) {
#endif #endif
// 12 lines of water // 12 lines of water
// 80 columns // 80 columns
enum {LOSE,WIN};
chtype colors[3]={0}; chtype colors[5]={0};
long score=0; long score=0,jumps=0;
FILE* scorefile; FILE* scorefile;
chtype background[LEN][WID]; chtype background[LEN][WID];
@ -43,20 +56,13 @@ char msg[150]={0};
byte msg_show=0; byte msg_show=0;
bool timed[3]; bool timed[3];
byte circlex[3]; byte squarex[3];
byte circley[3]; byte squarey[3];
byte loops_left=0; byte loops_left=0;
float shooting_angle=0; int oy=0;
int ox=0;
float rotation_angle=0; float rotation_angle=0;
int combo=1;
byte digit_count(int num){
byte ret=0;
do{
++ret;
num/=10;
}while(num);
return ret;
}
void filled_rect(byte sy,byte sx,byte ey,byte ex){ void filled_rect(byte sy,byte sx,byte ey,byte ex){
byte y,x; byte y,x;
for(y=sy;y<ey;++y) for(y=sy;y<ey;++y)
@ -76,18 +82,6 @@ void red_border(void){
} }
void fill_aims(){
for(byte i=0;i<26;++i){
aims[i].y= randint(8,HLEN);
aims[i].x= randint(0,HWID);
aims[i].angle=randint(0,628)/100;
aims[i].v=1;
aims[i].sign='A'+i;
aims[i].brake=0;
aims[i].visible=1;
}
}
float center_distance(byte y,byte x){ float center_distance(byte y,byte x){
//y distance is twice accounted for. visual reasons //y distance is twice accounted for. visual reasons
return sqrt( (y-HLEN)*(y-HLEN)+0.25*(x-HWID)*(x-HWID) ); return sqrt( (y-HLEN)*(y-HLEN)+0.25*(x-HWID)*(x-HWID) );
@ -96,82 +90,24 @@ void star_line(byte y){
for(byte x=1;x<WID-1;++x) for(byte x=1;x<WID-1;++x)
mvaddch(y,x,'.'); mvaddch(y,x,'.');
} }
void make_background(){
float d;
for(byte y=0;y<LEN;++y){
for(byte x=0;x<WID;++x){
d=center_distance(y,x)/(HLEN/4);
if(d<4){
if( ((int)d) %2){
background[y][x]='#';
}
else{
background[y][x]='$'|colors[0];
}
}
else{
background[y][x]=' ';
}
}
}
}
void logo(){ void logo(){
mvaddstr(0,0," _ "); mvprintw(0,0," _ ___ ");
mvaddstr(1,0,"| '. "); mvprintw(1,0,"(_' | Score: %d",score);
mvaddstr(2,0,"| : "); mvprintw(2,0,"._)QUARE (_:UMP Combo: %d",combo);
mvaddstr(3,0,"|.' ARRT "); addch('\n');
}
void draw_circle(byte sy,byte sx,char c){
/*chtype c=colors[2];
switch(loops_left){
case -1:
c|='.'
break;
default:
c|='0'+loops_left;
}*/
for(byte y=0;y<5;++y){
for(byte x=0;x<10;++x){
if((y-5)*(y-5)+(x-5)/2*(x-5)/2<25){
mvaddch(sy+y,sx+x,c);
}
}
}
}
void draw_angle(byte sy,byte sx){
float y=sy+5;
float x=sx+5;
for(byte i=0;i<5;++i){
mvaddch((byte)y,(byte)x,'#'|A_BOLD);
y+=sin(shooting_angle);
x+=cos(shooting_angle)/2;
}
}
void draw(){
for(byte i=0;i<3;++i){
draw_circle(circley[i],circlex[i],'.');
}
draw_angle(circley[0],circlex[0]);
logo();
if(msg_show){
--msg_show;
mvaddstr(LEN-1,0,msg);
}
} }
byte save_score(void){ byte save_score(void){
return fallback_to_home("circlejump_scores",score,SAVE_TO_NUM); return fallback_to_home("sjump_scores",score,SAVE_TO_NUM);
} }
void show_scores(byte playerrank){ void show_scores(byte playerrank){
filled_rect(0,0,LEN,WID); erase();
red_border(); logo(0,0);
if(playerrank==FOPEN_FAIL){ if(playerrank==FOPEN_FAIL){
mvaddstr(1,0,"Could not open score file."); mvaddstr(3,0,"Could not open score file");
mvprintw(2,0,"However, your score is %ld.",score); printw("\nHowever, your score is %ld.",score);
refresh(); refresh();
return; return;
} }
@ -179,49 +115,203 @@ void show_scores(byte playerrank){
char formername[60]={0}; char formername[60]={0};
long formerscore=0; long formerscore=0;
rewind(score_file); rewind(score_file);
fscanf(score_file,"%*s : %*d"); fscanf(score_file,"%*s : %*d\n");
if ( fscanf(score_file,"%s : %ld",formername,&formerscore)==2 && formerscore>0){ move(4,0);
byte a = (LEN-9)/2; byte b=0;
star_line(1); if ( fscanf(score_file,"%s : %ld\n",formername,&formerscore)==2){
star_line(LEN-2); halfdelay(1);
mvaddstr(1,WID/2-8,"CONGRATULATIONS!!"); printw("*****CONGRATULATIONS!****\n");
mvprintw(a+1,HWID-10," _____ You bet the"); printw(" You beat the\n");
mvprintw(a+2,HWID-10," .' | previous"); printw(" previous\n");
mvprintw(a+3,HWID-10," .' | record"); printw(" record\n");
mvprintw(a+4,HWID-10," | .| | of"); printw(" of\n");
mvprintw(a+5,HWID-10," |.' | |%11ld",formerscore); printw(" %14ld\n",formerscore);
mvprintw(a+6,HWID-10," | | held by"); printw(" held by\n");
mvprintw(a+7,HWID-10," ___| |___%7s!",formername); printw(" %11s\n",formername);
mvprintw(a+8,HWID-10," | |"); printw(" \n");
mvprintw(a+9,HWID-10," |____________|"); printw(" \n");
mvprintw(LEN-3,HWID-11,"Press a key to continue"); printw("*************************\n");
refresh(); printw("Press a key to proceed:");
do{ Effect:
input=getch(); move(4,0);
}while((input==KEY_UP||input=='w') || (input==KEY_DOWN||input=='s')); mvprintw(4,0, " _____ ");
filled_rect(0,0,LEN,WID); mvprintw(5,0, " .' |");
red_border(); mvprintw(6,0, " .' |");
mvprintw(7,0, " | .| |");
mvprintw(8,0, " |.' | |");
mvprintw(9,0, " | |");
mvprintw(10,0," ___| |___");
mvprintw(11,0," | |");
mvprintw(12,0," |____________|");
b=(b+1)%6;
if(getch()==ERR)
goto Effect;
nocbreak();
cbreak();
erase();
logo(0,0);
} }
} }
//scorefile is still open with w+ //scorefile is still open with w+
move(4,0);
char pname[60] = {0}; char pname[60] = {0};
long pscore=0; long pscore=0;
byte rank=0; byte rank=0;
rewind(score_file); rewind(score_file);
mvaddstr(1,WID/2-4,"HIGH SCORES"); printw(">*>*>Top %d<*<*<\n",SAVE_TO_NUM);
attron(colors[3]);
while( rank<SAVE_TO_NUM && fscanf(score_file,"%s : %ld\n",pname,&pscore) == 2){ while( rank<SAVE_TO_NUM && fscanf(score_file,"%s : %ld\n",pname,&pscore) == 2){
star_line(2+2*rank);
move(2+2*rank,1);
if(rank == playerrank) if(rank == playerrank)
printw(">>>"); printw(">>>");
printw("%s",pname); printw("%d) %s : %ld\n",rank+1,pname,pscore);
mvprintw(2+2*rank,WID-1-digit_count(pscore),"%d",pscore);
++rank; ++rank;
} }
addch('\n');
refresh(); refresh();
} }
void draw_square(byte sy,byte sx){
for(byte y=0;y<SIZE;++y){
mvaddch(sy+y,sx,ACS_VLINE);
mvaddch(sy+y,sx+SIZE*2,ACS_VLINE);
}
for(byte x=0;x<SIZE*2;++x){
mvaddch(sy,sx+x,ACS_HLINE);
mvaddch(sy+SIZE,sx+x,ACS_HLINE);
}
mvaddch(sy,sx,ACS_ULCORNER);
mvaddch(sy+SIZE,sx+SIZE*2,ACS_LRCORNER);
mvaddch(sy+SIZE,sx,ACS_LLCORNER);
mvaddch(sy,sx+SIZE*2,ACS_URCORNER);
}
void move_o(){
if(ox==0){
if(oy==0){
ox++;
}
else{
oy--;
}
}
else if(ox==SIZE*2){
if(oy==SIZE){
ox--;
combo=1;
}
else{
oy++;
}
}
else if(oy==SIZE){
if(ox==0){
oy--;
}
else{
ox--;
}
}
else if(oy==0){
if(ox==SIZE*2){
oy++;
}
else{
ox++;
}
}
//---->---
//| |
//^ V
//| |
//----<---
}
void draw_angle(byte sy,byte sx){
int y=sy+oy;
int x=sx+ox;
attron(colors[0]);
mvaddch(y,x,'O');
attroff(colors[0]);
}
void draw(int sy,int sx){
for(byte i=0;i<3;++i){
draw_square(sy+squarey[i],sx+squarex[i]);
}
logo();
}
byte shooting_scene(){
float dy=(oy-(SIZE/2))/(float)SIZE;
float dx=(ox-(SIZE))/(float)(SIZE*2);
dy/=2;//it was too hard :(
float y=squarey[0]+oy;
float x=squarex[0]+ox;
float offsetx=0;
float offsety=0;
float doffsety=0;
float doffsetx=-dx*2;
byte reached_o=0;
while(1){
erase();
draw(offsety,offsetx);
if(round(x)<=-round(offsetx)+1){//slow the animation
reached_o=1;
}
attron(colors[0]);
mvaddch(round(y)+round(offsety),round(x)+round(offsetx),'O');
attroff(colors[0]);
for(byte i=0;i<1;i++){
y+=dy;
x+=dx;
offsety+=doffsety;
if(reached_o){
offsetx=-x;
}
else{
offsetx+=doffsetx;
}
if( y>=LEN-1 || y<=1|| x> squarex[1]+SIZE*3 || x<-SIZE){
combo=1;
return LOSE;
}
if(y>=squarey[1] && x>=squarex[1] && y<=squarey[1]+SIZE && round(x)<=squarex[1]+SIZE*2){
if(round(y)==squarey[1] || round(y)==squarey[1]+SIZE){
score+=combo*101;
}
else{
score+=combo;
}
combo++;
jumps++;
oy=round(y)-squarey[1];
ox=round(x)-squarex[1];
for(byte i=0;i<3;++i){
squarey[i]+=offsety;
squarex[i]+=offsetx;
}
squarey[0]=squarey[1];
squarex[0]=squarex[1];
squarey[1]=squarey[2];
squarex[1]=squarex[2];
squarex[2]=squarex[1]+WID-SIZE;
squarey[2]=5+ (rand()%(LEN-(5+SIZE)));
//since square 0 always ends up at the center after the animation,
//square 2 should be choosen in a way that it would still remain
//in the screen after the animation in which it becomes square 1.
return WIN;
}
}
refresh();
if(reached_o){
usleep(DELAY/6);
}
else{
usleep(DELAY/3);
}
}
}
void help(void){ void help(void){
nocbreak(); nocbreak();
cbreak(); cbreak();
@ -229,9 +319,7 @@ void help(void){
filled_rect(0,0,LEN,WID); filled_rect(0,0,LEN,WID);
red_border(); red_border();
mvprintw(1,HWID-4,"GAME PLAY"); mvprintw(1,HWID-4,"GAME PLAY");
mvprintw(3,1,"If you hit a letter on keyboard, the letter on the"); mvprintw(3,1,"Jump from square to square.");
mvprintw(4,1,"screen will soon stop. You have to aim for the");
mvprintw(5,1,"center of the target using the moving letters.");
attroff(colors[3]); attroff(colors[3]);
refresh(); refresh();
getch(); getch();
@ -251,53 +339,63 @@ int main(void){
srand(time(NULL)%UINT_MAX); srand(time(NULL)%UINT_MAX);
if(has_colors()){ if(has_colors()){
start_color(); start_color();
init_pair(1,COLOR_RED,COLOR_BLACK); use_default_colors();
init_pair(2,COLOR_YELLOW,COLOR_BLACK); init_pair(1,COLOR_RED,-1);
init_pair(3,COLOR_GREEN,COLOR_BLACK); init_pair(2,COLOR_YELLOW,-1);
for(byte b=0;b<3;++b) init_pair(3,COLOR_GREEN,-1);
init_pair(4,COLOR_MAGENTA,-1);
init_pair(5,COLOR_BLUE,-1);
for(byte b=0;b<5;++b)
colors[b]=COLOR_PAIR(b+1); colors[b]=COLOR_PAIR(b+1);
} }
make_background();
Start: Start:
oy=ox=0;
squarey[0]=5;
squarex[0]=0;
squarey[1]=5;
squarex[1]=squarex[0]+WID-SIZE;
squarey[2]=5;
squarex[2]=squarex[1]+WID-SIZE;
erase(); erase();
halfdelay(1); nodelay(stdscr,1);
curs_set(0); curs_set(0);
score=0; score=0;
msg_show=0; msg_show=0;
aims_to_stop=shots=SHOTS_WHEN_STARTING;
fill_aims();
while(1){ while(1){
draw(); erase();
draw(0,0);
draw_angle(squarey[0],squarex[0]);
refresh(); refresh();
input=getch(); input=getch();
move_o();
if(input=='?' || input==KEY_F(1)) if(input=='?' || input==KEY_F(1))
help(); help();
if(input=='Q'){ if(input=='q'){
strcpy(msg,"Ctrl-C to quit.");
msg_show=50;
}
if(input!=ERR){
usleep(100000);
flushinp();
}
if(!aims_to_stop){
break; break;
} }
for(int i=0;i<26;++i){ if(input=='\n'||input==KEY_ENTER){
move_aim(aims+i); if(shooting_scene()==LOSE){
break;
}
}
usleep(DELAY);
if(input!=ERR){
flushinp();
} }
} }
nodelay(stdscr,0);
flushinp(); flushinp();
nocbreak(); nocbreak();
cbreak(); cbreak();
curs_set(1); curs_set(1);
end_scene();
mvprintw(LEN,0,"Press a key to see the high scores:");
refresh();
getch();
show_scores(save_score()); show_scores(save_score());
attron(colors[0]|A_STANDOUT); printw("\n\nWanna play again? (y/n)");
mvprintw(LEN-1,HWID-11,"Wanna play again? (y/n)");
attroff(colors[0]|A_STANDOUT);
do{ do{
input=getch(); input=getch();
}while((input==KEY_UP||input=='w') || (input==KEY_DOWN||input=='s')); }while((input==KEY_UP||input=='w') || (input==KEY_DOWN||input=='s'));